逐行读取文件,它只存储文件中的最后一行

问题描述 投票:1回答:2

我必须从.txt文件中读取如下所示:

New York,4:20,3:03
Kansas City,12:03,3:00
North Bay,16:00,0:20
Kapuskasing,10:00,4:02
Thunder Bay,0:32,0:31

我试图将每个元素分成它自己的数组是最终目标,所以我可以用它来做别的事情。

我的while循环正确读取文件,但只是将文件的最后一行存储在一个数组中,我无法找出原因。读取的文件也可以是任意数量的行。我确信它会读取每一行,因为它会打印出它完美读取的每一行。所以我认为问题在于存储它正在阅读的内容。

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

#pragma warning(disable: 4996)

// a function to remove the trailing carriage return
void clearTrailingCarraigeReturn(char *buffer);

/* == FUNCTION PROTOTYPES == */

/* == CONSTANTS == */
#define RECORD_SIZE     256
#define NUM_RECORDS     5
#define CHUNK_SIZE  1024    
#define STRING_SIZE 80

// MAIN
int main(int argc, char *argv[]) {
    FILE    *fp;
    char    flightInfo[RECORD_SIZE] = { 0 };
    char    cityName[20] = {};
    char    flightHour[20] = {};
    char    flightMin[20] = {};
    char    layoverHour[20] = {};
    char    layoverMin[20] = {};
    int     i = 0;

    struct flightInfo {
        char flightName[20];
        double flightTime;
        double layoverTime;
    };

    fp = fopen(argv[1], "r");
    // first - we'll check the command-line arguments to ensure that the user specified 
    // a single argument - which we will assume is the name of a file
    if (argc != 2) {
        printf("Sorry - you need to specify the name of a file on the command line.\n");
        return -1;
    }

    if (fp == NULL) {
        printf("Can't open the TEXT file for reading\n");
        return -4;
    }

    // get each of the lines from the file
    while (fgets(flightInfo, sizeof flightInfo, fp) > 0) {
        clearTrailingCarraigeReturn(flightInfo);
        // display the line we got from the file
        printf("  >>> read record [%s]\n", flightInfo);
    }

    // we exited the reading loop - was it because we read the EOF?
    if (feof(fp)) {
        printf(" [DONE reading the file ... we've reached the EOF]\n");
    } else {
        // we exited the loop because of an error
        if (ferror(fp)) {
            // there's an error
            printf("Error reading a record from the file\n");
            if (fclose(fp) != 0) {
                // we can't even close the file
                printf("Can't close the TEXT file we opened for reading\n");
            }
            return -5;
        }
    }
}

// This function locates any carriage return that exists in a record
// and removes it ...
void clearTrailingCarraigeReturn(char *buffer) {
    char *whereCR = strchr(buffer, '\n');
    if (whereCR != NULL) {
        *whereCR = '\0';
    }
}
c fgets
2个回答
1
投票

您的代码中存在多个问题:

  • 您应该在尝试打开文件之前测试命令行参数是否存在。
  • 你的阅读循环的测试是不正确的:fgets()返回一个指向目标数组或NULL的指针,所以你不应该使用> 0而是这样: while (fgets(flightInfo, sizeof flightInfo, fp) != 0)
  • 字符'\n'称为换行符,而不是回车符。在传统平台上,\n在文本文件0D 0A中转换为2个字节,即:回车和换行。
  • 循环读取文件内容,但不解析行内容并将其存储到您为其定义的变量中。您应该解析该行,转换值并将信息存储到flighInfo结构数组中的下一个条目: if (sscanf(flightInfo, "%19[^,],%2[0-9]:%2[0-9],%2[0-9]:%2[0-9]", cityName, flightHour, flightMin, layoverHour, layoverMin) == 5) { /* convert the times into `double` values and store the info */ } else { /* report the error, exit */ }
  • 你为struct flightInfo标签和char数组使用相同的名称。这很容易让人感到困惑和容易出错。你应该重命名char数组linebuf
  • 你应该在所有情况下关闭文件。

1
投票

您没有存储扫描结果。这些线:

while (fgets(flightInfo, sizeof flightInfo, fp)  > 0)
{

    clearTrailingCarraigeReturn(flightInfo);
    // display the line we got from the file
    printf("  >>> read record [%s]\n", flightInfo);
}

将下一行读入flightInfo(这是一个char数组),当下一行重新读入flightInfo的开头时。最后一行读取将存储在flightInfo中。

如果你想保留它,你也需要存储该行。 EG,你可以这样做:

char multiple_flight_info[100][1024];
int i = 0;
while (fgets(multiple_flight_info[i], 1024, fp)  > 0)
{
    clearTrailingCarraigeReturn(flightInfo[i]);
    // display the line we got from the file
    printf("  >>> read record [%s]\n", flightInfo);
    i++;
    if (i > 100) { exit(1); } /* do better error exiting here */
}

基本上这会创建一个双数组。第一个索引是要读取的行号,第二个索引是读取行中的字符位置。

还有很多事情需要做才能“安全”而不是阅读部分线条,因为一个太长,等等。但这可能会让你开始。

© www.soinside.com 2019 - 2024. All rights reserved.