【问题标题】:Read various length of data from a comma delimited text file in C从 C 中的逗号分隔文本文件中读取各种长度的数据
【发布时间】:2014-03-21 21:54:36
【问题描述】:

我有一个 txt 文件,其中的单词和数字用逗号分隔。我想读取字符直到下一个逗号,处理数据,然后从找到最后一个逗号的位置继续读取。我使用 fgetc(),但不确定它是否更新了 FILE 指针中的最后读取位置。

我遵循了这里建议的一般想法,这还行不通,但已经接近了。一开始的条件检查似乎效果不佳(EOF)。似乎在复制航空公司名称时我得到了一个额外的字符,然后它就会崩溃。

// Read data from file, data is comma delimited!
flight* read_from_text()
{
    #define DATA_CHUNK 20
    FILE *fp;
    flight temp_data;
    flight *data=malloc(sizeof(*data));
    data=&temp_data;
    char buffer[DATA_CHUNK];
    int c=0,n=0,i=0,state=0;

    // Open file for reading
    if((fp=fopen("c:\\data.txt","r"))==NULL)
    {
        printf("Error opening flight data file.");
        return NULL;
    }

    // read a single entry from file

    while(1)
    {
        while(((c=fgetc(fp))!=',')||(c=!EOF))
            buffer[n++]=(char)c;
        if(c==EOF) break;

        switch(state)
        {
            case CODE:
                // Check if flight code is valid
                if((buffer[0]<'0')||(buffer[0]>'9')||(buffer[1]<'0')||(buffer[1]>'9'))
                    printf("Error reading in flight number\n");
                else
                    temp_data.code=atoi(buffer);
                state++;
                break;
            case AIRLINE_NAME:
                // Check airline name length is OK
                if(n>(sizeof(temp_data.airline_name)))
                    printf("Airline name is too long, some characters will be cut\n");
                strncpy(temp_data.airline_name,buffer,n);
                state++;
                break;
            case DESTINATION:
                if(n>(sizeof(temp_data.destination)))
                    printf("Destination name is too long, some characters will be cut\n");
                strncpy(temp_data.destination,buffer,n);
                state++;
                break;
            case RESERVED_SEATS:
                temp_data.reserved_seats=atoi(buffer);
                state++;
                break;
            case DATE:
                if(n>(sizeof(temp_data.date)))
                    printf("Date format is too long, might be corrupted\n");
                strncpy(temp_data.date,buffer,n);
                state=0;
                break;
        }

        // Clear buffer
        for(i=0;i<DATA_CHUNK;i++)
            buffer[i]='\n';
        n=0;
    }

    printf("%d\n",temp_data.code);
    printf("%s\n",temp_data.airline_name);
    printf("%s\n",temp_data.destination);
    printf("%d\n",temp_data.reserved_seats);
    printf("%s\n",temp_data.date);
    getchar();

    return data;
}

【问题讨论】:

  • 您可以逐行动态读取它,然后用逗号对其进行标记。
  • 当然 fgetc 会更新 FILE 指针中的最后读取位置。如果 yozu 有一个包含“ABC”的文件,第一个 fgetc 将返回 'A',第二个 'B' 以此类推。

标签: c file


【解决方案1】:

您也可以考虑一次读几行并使用类似 strtok 的东西 使用“,”作为分隔符读取每个子字符串。对于一个简单的程序,这应该是 行。 strtok 具有内部状态,因此您不能将其与其他调用交错,因此它不是线程安全的。或者,您可以查看 strings.h 中的函数“index”。它返回一个指针,指向第一次出现的字符,如 ','。

在任何情况下,您都可以使用 fgetc 构建一个简单的状态机并回答您的问题,每个后续调用都将获取文件中的下一个字符。

【讨论】:

    【解决方案2】:

    是的,函数fgetc会更新Read指针,直到它返回EOF,表示文件结束。

    正是因为这个EOF,函数fgetc才返回int而不是char

    因此,当存储函数fgetc 的返回值时,请使用int 而不是char

    如果是EOF,那么你知道你已经到了文件的末尾。

    否则,将其转换为 char 并“按计划”进行。

    例如:

    FILE* fp = fopen(fileName,"r");
    int i;
    char c;
    while (1)
    {
        i = fgetc(fp);
        if (i == EOF)
            break;
        c = (char)i;
        ...
    }
    fclose(fp);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多