Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C文本文件到结构,数组,然后输出_C_Struct_Text Files_Readfile - Fatal编程技术网

C文本文件到结构,数组,然后输出

C文本文件到结构,数组,然后输出,c,struct,text-files,readfile,C,Struct,Text Files,Readfile,我试图获取一个简单的图书信息文本文件,并将其存储到一个结构数组中。与Java或C相比,我只是在学习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

我试图获取一个简单的图书信息文本文件,并将其存储到一个结构数组中。与Java或C相比,我只是在学习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;

}
#包括
#包括
#包括
typedef结构书{
字符标题[100];
char作者[100];
字符发布器[100];
浮动价格;
char-isbn[100];
整版;
整版;
}书;
内部主(空)
{
//补充资料(“魔术师:学徒”,“雷蒙德E.费斯特”,5.02,“0553564943”,512,1);
//我的书={“魔术师:学徒”,“雷蒙德E.费斯特”,“未知”,5.02,“0553564943”,512,1};
//补充资料(myBook);
char ch,文件名[25];
文件*fp;
printf(“输入您希望查看的文件名\n”);
获取(文件名);
fp=fopen(文件名,“r”);//读取模式
如果(fp==NULL)
{
perror(“打开文件时出错。\n”);
退出(退出失败);
}
//printf(“%s文件的内容为:”,文件名);
/*而((ch=fgetc(fp))!=EOF)
printf(“%c”,ch)*/
字符行[9001];
字符*项目;
int reccount=0;
int k;
int maxEntries=100;
而(fgets(第9000行,fp)){
printf(“%s”,第行);
项目=strtok(第“”行);
strcpy(库存[reccount]。标题,项目);
printf(“1”);
项目=strtok(第“”行);
strcpy(库存[reccount]。作者,项目);
printf(“2”);
项目=strtok(第“”行);
strcpy(库存[reccount]。发布者,项目);
项目=strtok(第“”行);
存货[reccount]。价格=atof(物料);
项目=strtok(第“”行);
strcpy(库存[reccount].isbn,项目);
项目=strtok(第“”行);
存货[reccount].pages=atoi(项目);
项目=strtok(第“”行);
存货[reccount]。份数=atoi(项目);
//printf(“%s\n”,库存[reccount].publisher);
reccount++;
}
fclose(fp);
printf(“我的库存:\n”);
int i;
对于(i=0;i
这不是FGET的问题。
首先,
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
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
然后使用
作为分隔符。其次,在第一次使用
strtok
后,将
NULL
传入,而不是
行。您可以执行以下操作:

Magician:Apprentice RaymondE.Feist Spectra(January1,1994) 5.02 0553564943 512 1 
Magician:Master RaymondE.Feist Spectra(January1,1994) 7.99 0553564935 499 1
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
您还可以使用另一个分隔符(如
,以便在作者姓名中有空格),然后您可以按如下方式格式化文件:

Magician:Apprentice RaymondE.Feist Spectra(January1,1994) 5.02 0553564943 512 1 
Magician:Master RaymondE.Feist Spectra(January1,1994) 7.99 0553564935 499 1
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 = 0;
while (fgets(line,9000,fp)) count++;
fclose(fp);
fp = fopen(file_name, "r");
Book* inventory = malloc(count*sizeof(Book));
Edit:要保持文件格式不变,您需要为每本书调用7次
fgets
。不幸的是,
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);
int count=0;
而(fgets(line,9000,fp))count++;
计数=计数/7;
fclose(fp);
fp=fopen(文件名,“r”);
帐簿*存货=malloc(计数*帐簿大小);
int i;
int reccount;
对于(reccount=0;reccount
请注意,新型ISBN只有13位,旧的只有10位。使用100存储ISBN不会有溢出的危险,但每本书浪费86字节。显示的格式为作者姓名(尤其是)和出版商(似乎包括出版日期)具有不同寻常的格式,没有空格分隔部分姓名。我很高兴我不必编写代码将
RaymondE.Feist
拆分为名字、首字母和姓氏(处理诸如:
DorothySayers
-无中间首字母;
麦克拉尼蒙纳德
-无中间首字母和多个大写字母等姓名).
char-line[9001];
,然后使用
fgets(line,9001,fp)
-没有
-1
fgets
说明了nul终止符。这是事实。我不确定提议的数据重新格式化;我更愿意看到对
fgets()的单独调用
对于每行数据-每本书七次调用。带有一组空分隔符的
strtok(line,“”)
是一种退化情况;任何分隔符的第一次出现是输入字符串末尾的
'\0'
。如果使用
strtok()拆分一行,您是对的
,用开始指针调用一次,然后用NULL调用。最好使用
strtok\u r()