fgets或fscanf对数组结构读取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 = " trn";
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 problemn");
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:%3dn", number, string, gram, calorie);
}
fclose ( pf);
free ( token);
}
else {
perror ( filename);
}
return 0;
}

最新更新