繁体   English   中英

数组结构上的 fgets 或 fscanf 以读取 c 中的特定格式文件

[英]fgets or fscanf on array struct to read specific format file in c

有这样的文件时如何使用 fgets 和 sscanf?

No  Nama Masakan                    Berat (Gram)            Kalori
1   Asinan                              250                 208
2   Toge Goreng                         250                 243
3   Gado - Gado                         150                 295
4   Ketoprak                            250                 153
5   Pempek                              200                 384
6   Rawon                               160                 331
7   Soto Ayam                           100                 101
8   Soto Padang                         100                 127
9   Tongseng                            120                 331
10  Hamburger                           125                 257
11  Kerupuk Palembang                   50                  168
12  Kerupuk Udang                       20                  72
13  Mie Bakso                           200                 302
14  Nasi Tim Ayam                       420                 588
15  Pizza                               125                 163
16  Sate Kambing                        180                 729
17  Sayur Krecek                        175                 249
18  Siomay                              100                 361
19  Soto Betawi                         150                 135
20  Soto Makasar                        150                 525
21  Soto Sulung                         150                 86

所以那个文件有 22 行。 那么如何扫描每种格式呢? 使用 fgets 还是 fscanf? 我认为解决方案可能是这样的:

while(!feof(fp))
{
 fgets(buffer,100,fp);
 sscanf(buffer,"%d",&struct[i].number);
 sscanf(buffer,"%[^\n]",struct[i].string);
 sscanf(buffer,"%d",&struct[i].gram);
 sscanf(buffer,"%d",&struct[i].calorie);
}

我在做什么正确吗? 如果不是,请告诉我,这样我就不会对如何解决这个问题感到好奇。 有时我总是遇到类似的问题,想知道如何解决。 谢谢你。

因为name字段可以包含空格,所以解析比较复杂。
使用指针保存行中的位置。 然后从这些指针中解析或复制。
这只是几种解析策略之一。

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

int main ( void) {
    char buffer[100] = "";
    char string[100] = "";
    char *filename = "file.txt";
    int number = 0;
    int gram = 0;
    int calorie = 0;
    FILE *pf = NULL;

    if ( NULL != ( pf = fopen ( filename, "r"))) {
        fgets(buffer,100,pf); // get header line
        while(fgets(buffer,100,pf)) // get lines until end of file
        {
            char *name = buffer;
            int span = 0;
            if ( 1 != sscanf(buffer,"%d %n",&number, &span)) {
                continue;
            }
            name += span; // name now points to first character of name field
            char *endfield = NULL;
            if ( NULL != ( endfield = strstr ( name, "   "))) {; // endfield points to three spaces after name field
                span = endfield - name;
                if ( span && span < sizeof string) {
                    strncpy(string,name,span); // copy span characters
                    string[span] = 0; // zero terminate
                    printf ( "%-20s", string);
                }
                if ( 2 == sscanf(endfield,"%d%d",&gram,&calorie)) {
                    printf ( "   gram:%3d   calorie:%3d", gram, calorie);
                }
                printf ( "\n");
            }
        }
        fclose ( pf);
    }
    else {
        perror ( filename);
    }
    return 0;
}

另一种策略是使用strtok

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

int main ( void) {
    char buffer[100] = "";
    char string[100] = "";
    char **token = NULL; // pointer to pointer to store tokens
    char *filename = "file.txt";
    char *whitespace = " \t\r\n";
    int limit = 0;
    int number = 0;
    int gram = 0;
    int calorie = 0;
    FILE *pf = NULL;

    if ( NULL != ( pf = fopen ( filename, "r"))) {
        fgets ( buffer, 100, pf); // get header line
        while ( fgets ( buffer, 100, pf)) {
            char *line = buffer;
            char *item = NULL;
            int count = 0;
            while ( ( item = strtok ( line, whitespace))) {
                if ( count + 1 > limit) {
                    char **temp = realloc ( token, sizeof *token * ( count + 1));
                    if ( NULL == temp) {
                        fprintf ( stderr, "realloc problem\n");
                        fclose ( pf);
                        free ( token);
                        exit (1);
                    }
                    token = temp;
                    limit = count + 1;
                }
                token[count] = item;
                ++count;
                line = NULL;
            }

            if ( count < 4) { // too few tokens
                continue;
            }

            number = 0;
            gram = 0;
            calorie = 0;

            if ( 1 != sscanf ( token[0], "%d", &number)) { // the first token
                continue;
            }
            if ( 1 != sscanf ( token[count - 2], "%d", &gram)) { // the next to last token
                continue;
            }
            if ( 1 != sscanf ( token[count - 1], "%d", &calorie)) { // the last token
                continue;
            }

            string[0] = 0;
            for ( int each = 1; each < count - 2; ++each) {
                strcat ( string, token[each]);
                if ( each < count - 3) {
                    strcat ( string, " ");
                }
            }

            printf ( "%2d  %-20sgram:%3d   calorie:%3d\n", number, string, gram, calorie);
        }
        fclose ( pf);
        free ( token);
    }
    else {
        perror ( filename);
    }
    return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM