Ошибка при заполнении массива из текстового файла - PullRequest
0 голосов
/ 25 апреля 2019

У меня проблемы с заполнением массива данными, которые я пытаюсь прочитать из текстового файла.Поэтому я использовал следующий код, чтобы попытаться прочитать следующий текстовый файл:

текстовый файл:

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 останавливается, как только он читает пробел, где он читает имена, поэтому я переключился на 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 Ответ

2 голосов
/ 25 апреля 2019

Управлять вводом и извлечением данных проще с помощью fgets и sscanf, чем с 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...