使用fscanf c将文件复制到数组(结构)中

时间:2018-11-20 01:36:26

标签: c arrays file structure

我正在尝试编写一个函数,该函数将使用fscanf复制文件中的浮点数并将其放入数组中。我还需要返回文件中的浮点数。 这是我目前拥有的:

ST_GeomFromEWKT('SRID=4326;POINT(28.872109890126964 160.10529558104636)'),24.237968,129.512386,227.032799,27.644993,60.959401,25.178026,201.229746,34.178728,250.975993,3.635878

这是我学习c的第一年,而我的老师很糟糕,非常感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

定义结构cg并声明 struct cg 变量 cg mass 如下:while (n < MAX){ fscanf("%f %f %f", &cg.x, &cg.y, &cg.mass); masses[n] = cg; ++n;} return n;

struct cg {
    float x, y, mass;
}cg, masses[MAX];

然后,在功能 readin 中,应注释包含 mass cg 的行,并在 else块中写一会儿如下所示:

while (n < MAX){
    fscanf("%f %f %f", &cg.x, &cg.y, &cg.mass);
    masses[n] = cg;
    ++n;
}
return n;

答案 1 :(得分:0)

在许多区域中,您可以“调整”内容,以使位置和质量的读取更加可靠。但是,在查看任何细节之前,让我们开始:

void main()

main的正确声明是int main (void)int main (int argc, char **argv)(您将看到用等效的char *argv[]编写)。 注释maintype int的函数,它返回一个值。请参阅:C11 Standard §5.1.2.2.1 Program startup p1 (draft n1570)。另请参阅:See What should main() return in C and C++?

现在让我们谈谈细节。您定义一个结构,并声明一个名为MAX的结构(包括其中的masses个)的全局数组,

struct cg {
    // structure to hold x and y co-ordinates and mass
    float x, y, mass;
}masses[MAX];

注意:对于任何计算,您都希望将float更改为double,以利用提高的精度并最小化舍入误差。)

在正确定义和声明的同时,避免使用全局变量。在极少数情况下,它们在所有情况下都是不必要的。相反,只需声明您的struct cg,然后在main()中声明您的数组,然后将该数组作为参数传递给需要它的每个函数。您已经正确定义了全局MAX,因此传递给函数进行填充的所有操作就是main()中声明的数组(最好是带有打开的文件描述符)

为什么在调用main()之前在readin()中打开文件?显然,如果您尝试打开文件而失败,则几乎不需要调用readin()。因此,通常,在将打开的FILE*流指针传递给函数进行读取之前,请在调用方中打开文件,确认文件已打开-否则,无需调用该函数。例如

int main (int argc, char **argv)
{
    int number;
    struct cg masses[MAX] = {{ .x = 0.0 }};
    /* use filename provided as 1st argument (stdin by default) */
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

    if (!fp) {  /* validate file open for reading */
        perror ("file open failed");
        return 1;
    }

    if ((number = readin (masses, fp)) > 0) {
        printf ("\n%d objects read:\n\n", number);
        computecg (masses, number);
    }

    if (fp != stdin) fclose (fp);   /* close file if not stdin */

    return 0;
}

通过这种方式,您的readin()减少为:

int readin (struct cg *masses, FILE *fp)
{
    int n = 0;

    while (n < MAX && fscanf (fp, "%lf %lf %lf",
                        &masses[n].x, &masses[n].y, &masses[n].mass) == 3)
        n++;

    return n;
}

注意:在调用if (n < MAX && ...fscanf如何通过拒绝读取多于MAX的值来保护数组边界。始终保护数组边界可能存在的任何地方,您的代码读取的值可能会多于您的空格...)

按照原本打算从打开的文件中进行readin()的位置和质量值的操作,并返回读取了位置和质量的对象的数量。

您只需传递填充的数组以及在数组中存储值的对象数。例如,只需在masses函数中将computecg()数组中的内容打印出来,就可以做到:

void computecg (struct cg *masses, int n_masses)
{
    /* Write this function to compute the C of G */
    /* and print the result */
    for (int i = 0; i < n_masses; i++)
        printf ("%6.2f  %6.2f  %6.2f\n", 
                masses[i].x, masses[i].y, masses[i].mass);
}

将其放在一起,示例如下:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

#define MAX 100

struct cg {                 /* define struct, declare instance in main() */
    double x, y, mass;      /*  (a typedef will make things convenient)  */
};

int readin (struct cg *masses, FILE *fp)
{
    int n = 0;

    while (n < MAX && fscanf (fp, "%lf %lf %lf",
                        &masses[n].x, &masses[n].y, &masses[n].mass) == 3)
        n++;

    return n;
}

void computecg (struct cg *masses, int n_masses)
{
    /* Write this function to compute the C of G */
    /* and print the result */
    for (int i = 0; i < n_masses; i++)
        printf ("%6.2f  %6.2f  %6.2f\n", 
                masses[i].x, masses[i].y, masses[i].mass);
}

int main (int argc, char **argv)
{
    int number;
    struct cg masses[MAX] = {{ .x = 0.0 }};
    /* use filename provided as 1st argument (stdin by default) */
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

    if (!fp) {  /* validate file open for reading */
        perror ("file open failed");
        return 1;
    }

    if ((number = readin (masses, fp)) > 0) {
        printf ("\n%d objects read:\n\n", number);
        computecg (masses, number);
    }

    if (fp != stdin) fclose (fp);   /* close file if not stdin */
#if defined (_WIN32) || defined (_WIN64)
    getchar();
#endif    
    return 0;
}

注意:#if defined (_WIN32) || defined (_WIN64)仅用于检查程序是否在Windows上编译-因为不需要使用{{1} }否则

示例输入文件

getchar();

使用/输出示例

$ cat dat/cgmasses.txt
1.37 1.37 713.54
3.00 3.00 189.55
1.05 1.05 276.15
2.57 2.57 238.94
2.17 2.17 189.03
6.73 6.73 263.26
3.26 3.26 795.61
9.41 9.41 283.92
1.60 1.60 279.72
1.70 1.70 719.12

cg的计算留给您。仔细研究一下,如果您还有其他问题,请告诉我。