繁体   English   中英

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

[英]Copy file into array(structure) using fscanf c

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

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


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


int readin(void)
{
    FILE *fp;
    masses cg;
//Error saying cg is an undeclared identifier.
    fp = fopen("m.txt", "rb");
    int n = 0;

    if (fp == NULL) {
        printf("Cannot find file.");
        return 0;
    }
    else {
        fscanf(fp, "%f" &cg.x, &cg.y, &cg.mass);
//Error here too
            n++;
            fclose(fp);
            getchar();
            return n;

    }

    }
    /* Write this function to read in the data from a file */
    /* into the array masses */
    /* note that this function should return the number of */
    /* masses read in from the file */


void computecg(int n_masses)
{
    /* Write this function to compute the C of G */
    /* and print the result */
}
void main(void)
{
    int number;
    if ((number = readin()) > 0) {
        computecg(number);
    }
}

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

定义结构cg和声明两个结构CG变量CG质量如下: while (n < MAX){ fscanf("%f %f %f", &cg.x, &cg.y, &cg.mass); masses[n] = cg; ++n;} return n; 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函数中,应注释包含质量cg的行,并在else块中 ,可以编写while块,如下所示:

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

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

void main()

main的正确声明是int main (void)int main (int argc, char **argv) (您将看到使用等效的char *argv[]编写)。 注意: maintype int的函数,它返回一个值。 请参阅: C11标准§5.1.2.2.1程序启动p1(草稿n1570) 另请参见: 请参见main()在C和C ++中应该返回什么?

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

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()声明的数组(最好与打开的文件描述符一起声明)

为什么在调用readin()之前在main()打开文件? 显然,如果您尝试打开文件而失败,则几乎不需要调用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()的位置和质量值,并返回为其读取位置和质量的对象的数量。

您只需将填充的数组以及要在其中存储值的对象数传递。 出于示例目的,只需在computecg()函数中将masses数组中的内容打印出来,即可:

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上编译-因为不需要使用getchar();使终端保持打开状态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

使用/输出示例

$ ./bin/cgmasses_read <dat/cgmasses.txt

10 objects read:

  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的计算留给您。 仔细检查一下,如果您还有其他问题,请告诉我。

暂无
暂无

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

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