简体   繁体   English

试图将数据从文件存储到结构数组。 C

[英]Trying to store data from file to arrays of structure. C

I'm pretty new to C programming, In the function below in my program I am trying to read numbers from a text file and enter them to arrays of structure x,y,mass accordingly. 我对C编程非常陌生,在我程序的以下功能中,我试图从文本文件中读取数字,并将其相应地输入到结构x,y,mass的数组中。 The text file looks like this: 文本文件如下所示:

 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);
}

I wrote this so far but i dont know if im going the correct way 我到目前为止已经写了这篇文章,但我不知道我是否走了正确的路

If you are just getting started, get started correctly. 如果您只是入门,请正确入门。 When you approach a problem that requires reading lines of data , use a line oriented input function to read the data (eg fgets or POSIX getline ). 当您遇到需要读取数据行的问题时,请使用面向行的输入函数读取数据(例如fgets或POSIX getline )。 This allows you to validate the read separate and apart from parsing values from the line. 这使您可以单独验证读取的内容,并且可以分析行中的值。

After reading and validating a line of data, you can then parse that data into whatever values you need. 在读取并验证了一行数据之后,您可以将该数据解析为所需的任何值。 There are a great many tools available. 有很多可用的工具。 sscanf , strtod , strtok or simply walking a pointer over each character in your line buffer comparing character-by-character as you go and taking the needed action. sscanfstrtodstrtok或仅将指针移到行缓冲区中的每个字符上,就可以在执行操作时逐个字符地进行比较。

Here, sscanf provides a very convenient way to parse 3 floating-point values from a line of text. 在这里, sscanf提供了一种非常方便的方法来解析一行文本中的3个浮点值。 (and use double instead of float for any engineering related work and always use integer values for currency). (并在所有工程相关工作中使用double而不是float ,并且始终使用整数值作为货币)。 If you did not know how many values you were reading from each line, then walking strtod through the buffer would work fine. 如果您不知道每行要读取多少个值,则在缓冲区中穿行strtod会很好。

Validate, validate, validate. 验证,验证,验证。 If you read it -- validate what your read. 如果您阅读了它-验证您阅读的内容。 If you convert it -- validate your conversion took place (and if needed that the value is within the expected range). 如果您进行转换-确认您进行了转换(如果需要,该值在预期范围内)。

Putting those pieces together, you can do something similar to the following to read 3-values from each line into an array of struct (up to MAX elements). 将这些片段放在一起,您可以执行类似于以下操作的操作,将每行的3个值读入一个struct数组(最多MAX元素)。 The code expects the filename to read as the first argument (or it will read from stdin by default if no arguments are given): 代码期望文件名作为第一个参数读取(或者,如果没有给出参数,默认情况下将从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;
}

( note: I have left validating that a whole line was read as an exercise. strlen and then checking that the last character read is '\\n' will suffice) 注意:我已经保留了验证整个行作为练习的内容strlen然后检查最后读取的字符为'\\n'就足够了)

Example Input File 输入文件示例

$ 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

Example Use/Output 使用/输出示例

$ ./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

Lastly, always compile with warnings enabled , and do not accept code until it compiles cleanly without warning . 最后,始终在启用警告的情况下进行编译,并且不要接受代码,直到代码在没有警告的情况下干净地进行编译 To enable warnings add -Wall -Wextra to your gcc compile string. 要启用警告,请在您的gcc编译字符串中添加-Wall -Wextra (add -pedantic for several additional warnings). (添加-pedantic以获得其他一些警告)。 For VS ( cl.exe on windoze), add /Wall . 对于VS(windoze上为cl.exe ),添加/Wall For clang , add -Weverything . 对于clang ,添加-Weverything Read and understand each warning. 阅读并理解每个警告。 They will identify any problems, and the exact line on which they occur. 他们将确定任何问题以及发生问题的确切路线。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM