gpt4 book ai didi

c - 尝试将数据从文件存储到结构数组

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

在我的程序的下面的函数中,我试图从文本文件中读取数字,并将它们相应地输入到结构 x,y,mass 的数组中。文本文件如下所示:

 1 2 3 //first number is x, second is y, and third is mass
1 2 3
1 2 3
 #include <stdio.h>
#include <stdlib.h>
#define MAX 100
struct cg {
float x, y, mass;
}masses[MAX];

int readin(void)
{
FILE *file = fopen("test.txt", "r");
int count;
if (file == NULL) {
printf("Error: can't open files.\n");
return 1;
}
else {
while (1) {
char c = fgetc(file);

if (c != EOF) {
if (count == 0) {
masses[count].x = c;
}
else if (count == 1)
{
masses[count].y = c;
}
else if (count == 2)
{
masses[count].mass = c;
}
if (count != 3) {
count++;
}
else { count = 0; }

}
else {
break;
}

}
}
fclose(file);
}

到目前为止我写了这篇文章,但我不知道我是否走正确的路

最佳答案

如果您刚刚开始,请正确开始。当您解决需要读取行数据的问题时,请使用面向行的输入函数来读取数据(例如fgets或POSIX getline)。这允许您验证读取,并且与解析该行中的值分开。

读取并验证一行数据后,您可以将该数据解析为您需要的任何值。有很多可用的工具。 sscanfstrtodstrtok 或者只是将指针遍历行缓冲区中的每个字符,逐个字符进行比较并获取需要采取行动。

这里,sscanf 提供了一种非常方便的方法来从一行文本中解析 3 个浮点值。 (对于任何与工程相关的工作,请使用double而不是float,并且始终使用整数值作为货币)。如果您不知道从每行读取了多少个值,那么在缓冲区中遍历 strtod 就可以了。

验证,验证,验证。如果你读过它——验证你读到的内容。如果您转换它 - 验证您的转换是否发生(如果需要,该值是否在预期范围内)。

将这些部分放在一起,您可以执行类似于以下的操作,将每行的 3 个值读取到结构数组中(最多 MAX 元素)。该代码期望将文件名作为第一个参数读取(或者如果未给出参数,则默认从 stdin 读取):

#include <stdio.h>

enum { NMEMB = 3, MAX = 100, MAXC = 512 };

typedef struct {
double x, y, mass;
} cg;

int main (int argc, char **argv) {

int n = 0; /* masses index */
char buf[MAXC] = ""; /* buffer for each line */
cg masses[MAX] = {{ .x = 0 }}; /* array of cg initialized to 0 */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

if (!fp) { /* validate file open for reading */
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}

while (n < MAX && fgets (buf, MAXC, fp)) { /* read each line */
cg tmp = { .x = 0 }; /* temporary struct */
/* you should validate complete line read here */
/* parse values into tmp and validate */
if (sscanf (buf, "%lf %lf %lf", &tmp.x, &tmp.y, &tmp.mass) == 3)
masses[n++] = tmp; /* assign tmp to massess, increment n */
}
if (fp != stdin) fclose (fp); /* close file if not stdin */

for (int i = 0; i < n; i++)
printf ("masses[%2d] %5.2f %5.2f %5.2f\n",
i, masses[i].x, masses[i].y, masses[i].mass);

return 0;
}

(注意:我已经将整行作为练习进行了验证。strlen,然后检查最后读取的字符是否为'\n ' 就足够了)

输入文件示例

$ cat ../dat/int3x20.txt
21 61 78
94 7 87
74 1 86
79 80 50
35 8 96
17 82 42
83 40 61
78 71 88
62 20 51
58 2 11
32 23 73
42 18 80
61 92 14
79 3 26
30 70 67
26 88 49
1 3 89
62 81 93
50 75 13
33 33 47

示例使用/输出

$ ./bin/cg ../dat/int3x20.txt
masses[ 0] 21.00 61.00 78.00
masses[ 1] 94.00 7.00 87.00
masses[ 2] 74.00 1.00 86.00
masses[ 3] 79.00 80.00 50.00
masses[ 4] 35.00 8.00 96.00
masses[ 5] 17.00 82.00 42.00
masses[ 6] 83.00 40.00 61.00
masses[ 7] 78.00 71.00 88.00
masses[ 8] 62.00 20.00 51.00
masses[ 9] 58.00 2.00 11.00
masses[10] 32.00 23.00 73.00
masses[11] 42.00 18.00 80.00
masses[12] 61.00 92.00 14.00
masses[13] 79.00 3.00 26.00
masses[14] 30.00 70.00 67.00
masses[15] 26.00 88.00 49.00
masses[16] 1.00 3.00 89.00
masses[17] 62.00 81.00 93.00
masses[18] 50.00 75.00 13.00
masses[19] 33.00 33.00 47.00

最后,始终在编译时启用警告,并且不要接受代码,直到在没有警告的情况下干净地编译。要启用警告,请将 -Wall -Wextra 添加到 gcc 编译字符串中。 (添加 -pedantic 以获得几个额外的警告)。对于 VS(windoze 上的 cl.exe),添加 /Wall。对于 clang,添加 -Weverything。阅读并理解每个警告。他们将识别任何问题以及问题发生的确切线路。

关于c - 尝试将数据从文件存储到结构数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47426295/

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