繁体   English   中英

C-读取多个整数并使用sscanf进行浮点运算

[英]C - reading multiple integers and floats with sscanf

我正在为我的C编程类做一个练习问题,该问题告诉我编写一个程序来读取文件中的变量。 在第一行,它应该读入整数N。

从那里,它应该读取一个整数,然后读取N行的每行五个浮点数。 应该计算出文件中所有浮点数的总和,然后将其写入另一个文件。

我编写了一个程序,该程序应该使用fgets将行复制到字符串,然后使用sscanf对其进行剖析并将段分配给不同的数组位置。 但是,通过sscanf(可能为空值或换行符)获取无关信息时遇到了一些问题。 它没有正确存储整数N(它会产生较大的随机值并通过无限循环产生运行时错误),并且它也可能不在循环内部运行。

我该如何完善它,使其读入整数并正确浮动?

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

#define MAX_STRING 30
#define MAX_LINE_SIZE 200

int main(void)
{
    FILE *f1, *f2;
    char filename[MAX_STRING];
    char fileline[MAX_LINE_SIZE];
    int N, eN;
    float totalwage = 0;
    int* ssn;
    float** wage;

    printf ("Enter a file name for data analysis: ");
    scanf ("%s", &filename); //get file name from user input for reading

    f1 = fopen (filename, "r");

    fgets (fileline, MAX_LINE_SIZE, f1); //read first line
    sscanf (fileline, "%d", &N); //pull integer from first line to determine how many lines follow

    for (eN = 0; eN < N; eN ++) //read N lines following the first
    {
        // VVV read single line from file
        fgets (fileline, MAX_LINE_SIZE, f1);
        // VVV record data from line
        sscanf (fileline, "%d, %f, %f, %f, %f, %f", &ssn[eN], &wage[eN][0], &wage[eN][1], &wage[eN][2], &wage[eN][3], &wage[eN][4]);
        // VVV add the 5 wages on each line to a total
        totalwage += wage[eN][0] + wage[eN][1] + wage[eN][2] + wage[eN][3] + wage[eN][4];
    }

    fclose (f1);

    printf ("Enter a file name for the result: ");
    scanf ("%s", &filename); //get file name from user input for writing

    f2 = fopen (filename, "w");

    fprintf (f2, "%f", totalwage); //store total of wages in file specified by user

    printf ("\nThe information has been stored. Press any key to exit.\n");
    getchar();
}

正在读取的文件是“ wages.txt”,其内容如下:

10
1, 10, 20, 30, 40, 50
2, 11, 12, 13, 14, 15
3, 21, 23, 25, 27, 29
4, 1, 2, 3, 4, 5
5, 30, 60, 90, 120, 150
6, 37, 38, 39, 40, 41
7, 40, 50, 60, 70, 80
8, 5, 10, 15, 20, 25
9, 80, 90, 100, 110, 120
10, 1000, 2000, 3000, 4000, 2000

回顾一下,问题在于存在运行时错误,由于某种无限循环,程序会崩溃。 通过一些调试,我发现它没有在第一行中正确读取整数。 而不是值十,它存储较大的值,就像读取空字符一样。


我添加了代码,试图为ssn和工资分配内存。 但是,我不确定该操作是否正确完成,并且程序仍然存在崩溃的运行时错误。

ssn = malloc (N*MAX_STRING);
wage = malloc (N*MAX_STRING);
for (eN = 0; eN < N; eN ++)
{
    wage[eN] = malloc (N*MAX_STRING);
}

您没有为工资分配任何内存。 它被声明为一个指向浮点数的指针。 很好,但是指针没有指向任何地方。

ssn也一样。

在此行之后:

sscanf (fileline, "%d", &N); //pull integer from first line to determine how many lines follow

您需要为ssn和工资分配内存。

由于这是家庭作业,因此我不会告诉您如何分配内存。 您需要能够自己弄清楚。

正如其他人指出的

scanf ("%s", &filename);

应该:

scanf ("%s", filename);

请注意,如果列数更改,则sscanf是一个大问题

修订用于strtod

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

#define MAX_STRING 30
#define MAX_LINE_SIZE 200
#define COLS 5

int main(void)
{
    FILE *f1, *f2;
    char filename[MAX_STRING];
    char fileline[MAX_LINE_SIZE];
    int N, eN, i;
    float totalwage = 0;
    float (*wage)[COLS];
    char *p;

    printf ("Enter a file name for data analysis: ");
    scanf ("%s", filename); //get file name from user input for reading
    f1 = fopen (filename, "r");
    fgets (fileline, MAX_LINE_SIZE, f1); //read first line
    sscanf (fileline, "%d", &N); //pull integer from first line to determine how many lines follow
    wage = malloc((sizeof(float) * COLS) * N);
    /* check malloc ... */
    for (eN = 0; eN < N; eN ++) //read N lines following the first
    {
        // VVV read single line from file
        p = fgets (fileline, MAX_LINE_SIZE, f1);
        strtol(p, &p, 10); /* skip first column */
        for (i = 0; i < COLS; i++) {
            wage[eN][i] = strtod(p + 1, &p); /* p+1 skip comma, read a float */
            totalwage += wage[eN][i]; /* sum */
        }
    }
    free(wage);
    fclose (f1);
    printf ("Enter a file name for the result: ");
    scanf ("%s", filename); //get file name from user input for writing
    f2 = fopen (filename, "w");
    fprintf (f2, "%f", totalwage); //store total of wages in file specified by user
    printf ("\nThe information has been stored. Press any key to exit.\n");
    getchar();
    fclose(f2); /* you forget to close f2 */
    return 0;
}

还要注意,您只读取浮点数,不需要存储它们,因此可以避免使用malloc ,并且在现实世界中检查fopenfgets的结果...

当您分配内存来存储一个浮点数时,您需要了解一个浮点数包含四个字节,因此在调用malloc时,需要考虑到这一点,以存储一个浮点数: malloc( sizeof(float ) )以存储数组大小int的float malloc( N*sizeof(float ) )sizeof(int)

暂无
暂无

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

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