簡體   English   中英

C fscanf輸入格式

[英]C fscanf input format

我有一個包含以下格式的行的輸入文件:

 %s %d %d %d %lf %lf ... %lf\n

其中double值的數量未知,但是對於我的計算,我只接受其中的前15個。

我不知道的問題是,當我到達這樣的行時:

City0 28 2 2016 1 2 3 4 5 6 7 8 9 10
City1 28 2 2016 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
City2 1 3 2016 1 2 3 4 5

並且我將各自的值正確分配給某個結構,得到以下結果:

City0 28 2 2016 Number of measures: 10
City1 28 2 2016 Number of measures: 15
16 17 18 19 Number of measures: 1
City2 1 3 2016 Number of measures: 5

如何讀(無處)/忽略所有內容,直到到達行尾,然后照常開始閱讀下一行? 我需要以下輸出:

City0 28 2 2016 Number of measures: 10
City1 28 2 2016 Number of measures: 15
City2 1 3 2016 Number of measures: 5

我嘗試了這個,但沒有更多的主意:

i=0; char character;
while (fscanf(fp, "%s %d %d %d", c.name, &c[i].date.day, 
    &c[i].date.month, &c[i].date.year)==4 && i<number_of_cities) {
    while (fscanf(fp, "%lf", &c[i].measures[j])==1 && j<15) {
        j++;
    }
    if (j==15) {
        while (fscanf(fp, "%s", character)!='\n') {}
    }
    c[i].mnum = j;
    j=0;
    i++;
}

您可以使用fscanf()讀取整行輸入,使用sscanf()掃描前四個值,然后在循環中再次使用sscanf()讀取double值。 這里的技巧是使用%n指令將下一個讀取位置的位置保存在字符串中。

這是一個例子。 請注意, size_t用於數組索引,因為這是一個無符號整數類型,可以保證保存任何數組索引。 另請注意,在打開文件和掃描行的開頭時會進行一些錯誤檢查。 如果該行的初始元素與期望值不匹配,則程序退出並顯示錯誤消息。 這種錯誤檢查可能會更嚴格一些。 例如,如果將年份作為浮點值輸入(例如2016.0 ,則將接受輸入,但存儲在2016.0 measures[]的值將從小數點后的0開始。

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

struct Data {
    char name[1000];
    struct {
        int day;
        int month;
        int year;
    } date;
    size_t mnum;
    double measures[15];
};

int main(void)
{
    size_t i = 0, j = 0;
    char buffer[1000];
    char *read_ptr = buffer;
    int n_read = 0;

    size_t number_of_cities = 3;

    struct Data c[number_of_cities];

    FILE *fp;
    if ((fp = fopen("datafile.txt", "r")) == NULL) {
        fprintf(stderr, "Unable to open file\n");
        exit(EXIT_FAILURE);
    }

    while (fgets(buffer, 1000, fp) != NULL) {
        if (sscanf(buffer, "%s %d %d %d %n", c[i].name, &c[i].date.day, 
                   &c[i].date.month, &c[i].date.year, &n_read) != 4) {
            fprintf(stderr, "Incorrect input format\n");
            exit(EXIT_FAILURE);
        }
        read_ptr += n_read;
        while (sscanf(read_ptr, "%lf %n", &c[i].measures[j], &n_read) == 1 &&
               j < 15) {
            read_ptr += n_read;
            ++j;
        }
        c[i].mnum = j;
        ++i;        
        j = 0;
        read_ptr = buffer;
        if (i == number_of_cities) {
            break;
        }
    }

    for (i = 0; i < number_of_cities; i++) {
        printf("%s %d %d %d Number of measures: %zu\n",
               c[i].name,
               c[i].date.day, c[i].date.month, c[i].date.year,
               c[i].mnum);
        for (j = 0; j < c[i].mnum; j++) {
            printf("%5g", c[i].measures[j]);
        }
        putchar('\n');
    }

    return 0;
}

使用示例數據作為輸入的程序輸出:

City0 28 2 2016 Number of measures: 10
    1    2    3    4    5    6    7    8    9   10
City1 28 2 2016 Number of measures: 15
    1    2    3    4    5    6    7    8    9   10   11   12   13   14   15
City2 1 3 2016 Number of measures: 5
    1    2    3    4    5

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM