gpt4 book ai didi

c - 如何将 .xyz 文件读入 double 组?

转载 作者:行者123 更新时间:2023-11-30 16:10:56 24 4
gpt4 key购买 nike

我是 C 语言新手,来自 Python。我想将 .xyz 文件读入动态大小的数组中,以便稍后在程序中用于各种计算。该文件的格式如下:

Title  
Comment
Symbol 0.000 0.000 0.000
Symbol 0.000 0.000 0.000
....

前两行不是必需的,应该跳过。文件的“符号”部分是化学符号——例如H、Au、C、Mn——.xyz 文件格式用于存储原子的 3D 坐标。它们也需要被忽略。我对空格分隔的十进制数字感兴趣。因此我想:

  • 跳过前两行,或者以某种方式忽略它们。
  • 跳过每行的第一部分,直到第一个空格。
  • 将三列数字(坐标)存储在一个数组中。

到目前为止,我已经能够打开一个文件进行读取,然后我尝试检查该文件的长度,以便根据需要存储的坐标集数量来更改数组的大小.

// Variable declaration
FILE *fp;
long file_size;

// Open file and error checking
fp = fopen ("file_name" , "r");
if(!fp) perror("file_name"), exit(1);

// Check file size
fseek(fp, 0, SEEK_END);
file_size = ftell(fp);
rewind(fp);

// Close file
fclose(fp);

我已经能够使用 fscanf(fp, "%*[^\n]") 跳过前两行,跳到行尾。但是,我无法弄清楚如何循环遍历文件的其余部分,同时仅将十进制数字存储在数组中。

如果我理解正确,我需要为数组分配内存,结合使用 malloc() 和我的 file_size ,然后将数据复制到数组中使用fread()

以下是实际 .xyz 文件内容的示例:

10 atom system
Energy: -914941.6614699
Ag 0.96834 1.51757 0.02281
Ag 0.96758 -1.51824 -0.02206
Ag -1.80329 2.27401 0.03179
Ag -3.58033 0.00046 0.00126
Ag -1.80447 -2.27338 -0.03537
Ag -0.96581 0.02246 -1.51755
Ag -0.96929 -0.02231 1.51463
Ag 1.80613 0.03321 -2.27213
Ag 3.58027 0.00028 0.00206
Ag 1.80086 -0.03407 2.27455

最佳答案

这是 C 语言中将文件读入 cstring 数组(指向 cstring 的指针,因此大致相当于 Python 字符串列表)的通用方法。

    int count = 0;                  // line counter;
int char_count = 0; // char counter;
int max_len = 0; // for storing the longest line length
int c; // for measuring each line length
char **str_ptr_arr; // array of pointers to c-string

//extract characters from the file, looking for endlines; note that
//the EOF check has to come AFTER the getc(fp) to work properly
for (c = getc(fp); c != EOF; c = getc(fp)) { //edit see comments
char_count += 1;
if (c == '\n') { //safe comparison see comments
count += 1;
if (max_len < char_count) {
max_len = char_count; //gets longest line
}
char_count = 0;
}
}
//should probably do an feof check here
rewind(fp);

现在你有了行数和最长行的长度(如果你愿意,你可以尝试使用上面的循环来排除行,但将整个内容读入 c- 数组可能会更容易)字符串,然后将其处理为 double 组)。现在为指向 C 字符串的指针数组和 C 字符串本身分配内存:

    //allocate enough memory to hold all the strings in the file, by first
//allocating the arr of ptrs then a slot for each c-string pointed to:
str_ptr_arr = malloc(count * sizeof(char*)); //size of pointer
for (int i = 0; i < count; i++) {
str_ptr_arr[i] = malloc ((max_len + 1) * sizeof(char)); // +1 for '\0' terminate
}
rewind(fp); //rewind again;

现在,我们遇到了一个问题,那就是如何填充这些 cstring(Python 简单多了!)。这行得通,我不确定这是否是专家的方法,但在这里我们读到了临时缓冲区然后使用 strcpy 将缓冲区的内容移动到我们分配的数组槽中:

    for (int i = 0; i < count; i++) {
char buff[max_len + 1]; //local temporary buffer that can store any line in file
fscanf(fp, "%s", buff); //read the first string to buffer
strcpy(str_ptr_arr[i], buff);
}

注意:这是开始排除行或从行中删除各种子字符串的好时机,因为您可以使用其他 cstring 方法使 strcpy 以缓冲区内容为条件。我自己对此还很陌生(学习编写在 Python 程序中使用的 C 函数),但这似乎是正确的方法。

也可以直接访问动态分配的 float 组来存储数值数据,而无需使用 cstring 数组;这可以在上面的最后一个循环中完成。您可以在空格处拆分字符串,排除字母部分,然后使用 cstring 函数 atof 转换为 float 据类型。

编辑:我应该提到,所有这些内存分配在使用完毕后都必须手动释放,方法如下:

   for(int i = 0; i < count; i++) {      // free each allocated cstring space
free(str_ptr_arr[i]);
}
free(str_ptr_arr); // free the cstring pointer space
str_ptr_arr = NULL;

关于c - 如何将 .xyz 文件读入 double 组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58770892/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com