逐行读取文件,它仅将最后一行存储在文件中

时间:2019-04-05 05:57:14

标签: c fgets

我必须读取一个如下所示的.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';
    }
}

2 个答案:

答案 0 :(得分: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 */
}

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

为了“安全”还需要做很多事情,并且不要因为太长而无法读取部分行,等等。但这可能会让您入门。

答案 1 :(得分:1)

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

  • 您应该在尝试打开文件之前测试命令行参数是否存在。
  • 您的阅读循环测试不正确:fgets()返回指向目标数组或NULL的指针,因此您不应该使用> 0,而是这样:

    while (fgets(flightInfo, sizeof flightInfo, fp) != 0)
    
  • 字符'\n'被称为换行符,而不是回车符。在旧版平台上,\n被转换为文本文件0D 0A中的2个字节,即:回车符换行符。 / p>

  • 该循环读取文件内容,但不解析行内容并将其存储到为此定义的变量中。您应该解析该行,转换值并将信息存储到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重命名。

  • 在所有情况下都应关闭文件。