从txt文件填充数组时出错

时间:2019-04-24 23:51:15

标签: c

我无法用试图从txt文件读取的数据填充数组。因此,我使用以下代码尝试读取以下txt文件。

txt文件:

Smith, Susan
B
80.0
17.76

Sanders, Fred
M
87.25
23.45

Kerr, Heidi
M
80.0
47.86

Russo, Rick
B
83.75
12.15

我使用的代码:


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


typedef struct employee

{

    char name[100];      // employee's name - last, first

    char title;          // title 'B' or 'M'

    double hours_worked; // total number of hours worked

    double payrate;      // pay rate per hour

    double payment;      // total payment for the pay period 

} Employee;

int main()
{
    Employee payroll[200];
    int i = 0;
    FILE*infile;
    infile = fopen("payroll.txt", "r");
    //fscanf loop that will fill payroll array with data from file
    while (!feof(infile))
    {

        fscanf(infile, " %s", &payroll[i].name); //Reading name
        fscanf(infile, "%c", &payroll[i].title); //Reading title
        fscanf(infile, "%lf", &payroll[i].hours_worked); //Reading hours worked
        fscanf(infile, "%lf", &payroll[i].payrate); //Reading pay rate
        ++i;
    }
    printf("%d\n", i);
//loop that tests to make sure array was correctly filled
    for (i = 0; i < 4; ++i)
    {
        printf("%s\n", payroll[i].name);
        printf("%c\n", payroll[i].title);
        printf("%lf\n", payroll[i].hours_worked);
        printf("%lf\n", payroll[i].payrate);

    }





    fclose(infile);
    system("pause");
    return 0;
}

所以我意识到我的问题必须是第一个读取字符串名称的fscanf,因为一旦fscanf读取了读取名称的空白,fscanf就停止了,所以我切换到fgets():


        fgets(payroll[i].name, 100, infile);


但是那仍然不能给我正确的结果。

请帮助

edit:因此,我的fscanfs显然存在其他问题,因为如果我将txt文件编辑为此以消除空格,则可以使用fscanf:


Smith,Susan
B
80.0
17.76
Sanders,Fred
M
87.25
23.45
Kerr,Heidi
M
80.0
47.86
Russo,Rick
B
83.75
12.15

我正在使用此代码的位置:


while (!feof(infile))
    {   
        fscanf(infile, " %s", &payroll[i].name); //Reading name
        fscanf(infile, "%c", &payroll[i].title); //Reading title
        fscanf(infile, "%lf", &payroll[i].hours_worked); //Reading hours worked
        fscanf(infile, "%lf", &payroll[i].payrate); //Reading pay rate
        ++i;
    }

如果打印结果像这样疯狂,我仍然会收到错误消息: https://i.stack.imgur.com/x6l7a.png

1 个答案:

答案 0 :(得分:2)

使用fgetssscanf来控制输入和数据提取比使用fscanf来控制输入和数据提取要容易得多,像这样,以及其他一些注释性的更改和添加。

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

#define RECORDS 200             // better not to hard-code inline
#define NAMELEN 99

typedef struct employee {
    char name[NAMELEN+1];       // employee's name - last, first
    char title;                 // title 'B' or 'M'
    double hours_worked;        // total number of hours worked
    double payrate;             // pay rate per hour
    double payment;             // total payment for the pay period 
} Employee;

int main(void)
{
    char instr[256];
    Employee payroll[RECORDS];
    int records = 0;                            // `i` was a poor choice of name
    FILE *infile;
    infile = fopen("payroll.txt", "r");
    if(infile == NULL) {
        perror("Could not open file");
        exit(1);                                // check file opened
    }

    // loop that will fill payroll array with data from file
    while(fgets(instr, sizeof instr, infile) != NULL) {
        // name
        if(records >= RECORDS) {
            perror("Too many records");
            exit(1);
        }
        instr[ strcspn(instr, "\r\n") ] = 0;    // remove trailing newline etc
        instr[NAMELEN] = 0;                     // truncate long name 
        strcpy(payroll[records].name, instr);

        // title
        if(fgets(instr, sizeof instr, infile) == NULL) {
            perror("Incomplete data");
            exit(1);
        }
        payroll[records].title = instr[0];

        // hours worked
        if(fgets(instr, sizeof instr, infile) == NULL) {
            perror("Incomplete data");
            exit(1);
        }
        if(sscanf(instr, "%lf", &payroll[records].hours_worked) != 1) {
            perror("Error in hours worked");
            exit(1);
        }

        // pay rate
        if(fgets(instr, sizeof instr, infile) == NULL) {
            perror("Incomplete data");
            exit(1);
        }
        if(sscanf(instr, "%lf", &payroll[records].payrate) != 1) {
            perror("Error in pay rate");
            exit(1);
        }

        ++records;
    }
    printf("%d records\n", records);

    //loop that tests to make sure array was correctly filled
    for (int i = 0; i < records; ++i) {                 // use the variable
        printf("%s\n", payroll[i].name);
        printf("%c\n", payroll[i].title);
        printf("%.2f\n", payroll[i].hours_worked);      // %f not %lf
        printf("%.2f\n", payroll[i].payrate);           // specify dec places
        printf("\n");
    }

    fclose(infile);
    return 0;
}

程序输出:

4 records
Smith,Susan
B
80.00
17.76
Sanders,Fred M 87.25 23.45
Kerr,Heidi M 80.00 47.86
Russo,Rick B 83.75 12.15

请注意,feof不会检查文件结尾。它通过事先读取文件末尾(没有数据)来检查您是否出错。


编辑:或者,如果您确实希望解决方案使用fscanf,则为

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

#define RECORDS 200             // better not to hard-code inline
#define NAMELEN 99

typedef struct employee {
    char name[NAMELEN+1];       // employee's name - last, first
    char title;                 // title 'B' or 'M'
    double hours_worked;        // total number of hours worked
    double payrate;             // pay rate per hour
    double payment;             // total payment for the pay period 
} Employee;

int main(void)
{
    Employee payroll[RECORDS];
    int records = 0;                                // `i` was a poor choice of name
    FILE *infile;
    infile = fopen("payroll.txt", "r");
    if(infile == NULL) {
        perror("Could not open file");
        exit(1);                                    // check file opened
    }

    // loop that will fill payroll array with data from file
    while(fscanf(infile, " %99[^\n] %c%lf%lf",      // spaces remove the newlines
             payroll[records].name,                 // no `&`
            &payroll[records].title,
            &payroll[records].hours_worked, 
            &payroll[records].payrate) == 4) {
        ++records;
    }
    printf("%d records\n", records);

    //loop that tests to make sure array was correctly filled
    for (int i = 0; i < records; ++i) {             // use the variable
        printf("%s\n", payroll[i].name);
        printf("%c\n", payroll[i].title);
        printf("%.2f\n", payroll[i].hours_worked);  // %f not %lf
        printf("%.2f\n", payroll[i].payrate);       // specify dec places
        printf("\n");
    }

    fclose(infile);
    return 0;
}