我正在尝试获取书籍信息的简单文本文件并将其存储到结构数组中。我只是在学习C而不是Java或C#,我有点困惑。
我知道这与我编写代码的方式有关
我的文字文件是:
Magician:Apprentice
RaymondE.Feist
Spectra(January1,1994)
5.02
0553564943
512
1
Magician:Master
RaymondE.Feist
Spectra(January1,1994)
7.99
0553564935
499
1
然后我有我的代码,我不知道我做错了什么,我知道它与while有关(fgets(行......我知道如何显示所有文本,我只是遇到问题)正确地将文本存储到结构中。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct book{
char title[100];
char author[100];
char publisher[100];
float price;
char isbn[100];
int pages;
int copies;
} Book;
int main( void )
{
//addInventory( "Magician: Apprentice", "Raymond E. Feist", 5.02, "0553564943", 512, 1 );
//Book myBook = { "Magician: Apprentice", "Raymond E. Feist", "unknown", 5.02, "0553564943", 512, 1 };
//addInventory( myBook );
char ch, file_name[25];
FILE *fp;
printf("Enter the name of file you wish to see\n");
gets(file_name);
fp = fopen(file_name,"r"); // read mode
if( fp == NULL )
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
//printf("The contents of %s file are :", file_name);
/*while( ( ch = fgetc(fp) ) != EOF )
printf("%c",ch);*/
char line[9001];
char *item;
int reccount = 0;
int k;
int maxEntries = 100;
while (fgets(line,9000,fp)) {
printf("%s",line);
item = strtok(line,"");
strcpy(inventory[reccount].title,item);
printf("1");
item = strtok(line,"");
strcpy(inventory[reccount].author,item);
printf("2");
item = strtok(line,"");
strcpy(inventory[reccount].publisher,item);
item = strtok(line,"");
inventory[reccount].price = atof(item);
item = strtok(line,"");
strcpy(inventory[reccount].isbn,item);
item = strtok(line,"");
inventory[reccount].pages = atoi(item);
item = strtok(line,"");
inventory[reccount].copies = atoi(item);
//printf("%s\n",inventory[reccount].publisher);
reccount++;
}
fclose(fp);
printf("My Inventory:\n");
int i;
for( i = 0; i < count; i++ )
{
printf( "Title:\t\"%s\"\n", inventory[i].title );
printf( "Author:\t%s\n", inventory[i].author );
printf( "Publisher:\t%s\n", inventory[i].publisher );
printf( "Price:\t$%.02f\n", inventory[i].price );
printf( "ISBN:\t%s\n", inventory[i].isbn );
printf( "Pages:\t%d\n", inventory[i].pages );
printf( "Copies:\t%d\n", inventory[i].copies );
}
return 0;
}
答案 0 :(得分:0)
这不是fgets的问题
首先,fgets
从文件中读取一行文本,strtok
使用分隔符拆分字符串。您可能希望像这样格式化文件:
Magician:Apprentice RaymondE.Feist Spectra(January1,1994) 5.02 0553564943 512 1
Magician:Master RaymondE.Feist Spectra(January1,1994) 7.99 0553564935 499 1
然后使用" "
作为分隔符。其次,在您第一次使用strtok
后,请传递NULL
而不是line
。你可以这样做:
item = strtok(line," ");
strcpy(inventory[reccount].title,item);
item = strtok(NULL," ");
strcpy(inventory[reccount].author,item);
item = strtok(NULL," ");
strcpy(inventory[reccount].publisher,item);
item = strtok(NULL," ");
inventory[reccount].price = atof(item);
item = strtok(NULL," ");
strcpy(inventory[reccount].isbn,item);
item = strtok(NULL," ");
inventory[reccount].pages = atoi(item);
item = strtok(NULL," ");
inventory[reccount].copies = atoi(item);
您还可以使用其他分隔符(例如;
,以便您可以在作者姓名中包含空格),然后您可以像这样格式化文件:
Magician:Apprentice;Raymond E. Feist;Spectra(January1,1994);5.02;0553564943;512;1
Magician:Master;Raymond E. Feist;Spectra(January1,1994);7.99;0553564935;499;1
此外,count
和inventory
都未定义。你可以这样做(在while(fgets...)
循环之前):
int count = 2;
Book* inventory = malloc(count*sizeof(Book));
或者,如果您希望能够使用不同大小的文件,只需计算行数,然后关闭并重新打开该文件:
int count = 0;
while (fgets(line,9000,fp)) count++;
fclose(fp);
fp = fopen(file_name, "r");
Book* inventory = malloc(count*sizeof(Book));
修改:为了保持文件格式,您需要为每本书调用fgets
7次。不幸的是,fgets
包含换行符,因此您需要使用strtok
int count = 0;
while (fgets(line,9000,fp)) count++;
count = count / 7;
fclose(fp);
fp = fopen(file_name, "r");
Book* inventory = malloc(count*sizeof(Book));
int i;
int reccount;
for (reccount = 0; reccount < count; reccount++){
fgets(line,9000,fp);
item = strtok(line, "\n");
strcpy(inventory[reccount].title,item);
fgets(line,9000,fp);
item = strtok(line, "\n");
strcpy(inventory[reccount].author,item);
fgets(line,9000,fp);
item = strtok(line, "\n");
strcpy(inventory[reccount].publisher,item);
fgets(line,9000,fp);
inventory[reccount].price = atof(line);
fgets(line,9000,fp);
item = strtok(line, "\n");
strcpy(inventory[reccount].isbn,item);
fgets(line,9000,fp);
inventory[reccount].pages = atoi(line);
fgets(line,9000,fp);
inventory[reccount].copies = atoi(line);
}
fclose(fp);