首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在数组结构上读取c++中的特定格式文件的fget或fscanf

在数组结构上读取c++中的特定格式文件的fget或fscanf
EN

Stack Overflow用户
提问于 2022-06-18 07:32:53
回答 1查看 37关注 0票数 0

当有这样的文件时,如何使用fget和sscanf?

代码语言:javascript
复制
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行。那么如何扫描每一种格式呢?使用fget还是fscanf?我认为解决办法可能是这样的:

代码语言:javascript
复制
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);
}

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-06-18 12:17:29

因为name字段可以包含空格,所以解析很复杂。

使用指针保存行中的位置。然后从这些指针中解析或复制。

这只是几种解析策略之一。

代码语言:javascript
复制
#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

代码语言:javascript
复制
#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;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72667519

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档