[英]read data from txt file into a struct in C
您好我正在尝试将逗号分隔的文件读入 c 中的结构。 问题是它们在同一句话之间有空格,所以 fscanf 不能正常工作。
文本文件:
9780136019701,An Introduction to Organic Chemistry,Timberlake Karen,10,3.54,12-2008
9781506304212,Mathematics for Social Scientists,Kropko Jonathan,7,4.73,12-2015
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Date
{
int year;
int month;
} Date;
typedef struct Book
{
long long int isbn;
char title[100];
char author[100];
int quantity;
int price;
Date date;
} Book;
int main() {
Book* Books;
int n_books=0;
FILE *ptr = fopen("Books.txt", "r");
if(ptr!=NULL) {
Books = (Book*)malloc(sizeof(Book));
while(!feof(ptr)) {
fscanf(ptr,"%lld",&((*(Books+n_books)).isbn));
fscanf(ptr,"%s",(*(Books+n_books)).title);
fscanf(ptr,"%s",(*(Books+n_books)).author);
fscanf(ptr,"%d",&((*(Books+n_books)).quantity));
fscanf(ptr,"%f",&((*(Books+n_books)).price));
Date date;
fscanf(ptr,"%d",&date.month);
fscanf(ptr,"%d",&date.year);
(*(Books+n_books)).date = date;
printf("Name:%s\n",Books[n_books].title);
printf("ID:%lld\n",Books[n_books].isbn);
printf("price:%f\n",Books[n_books].price);
printf("date:%d-%d\n",Books[n_books].date.month,Books[n_books].date.year);
printf("quantity:%d\n",Books[n_books].quantity);
printf("author:%s\n",Books[n_books].author);
n_books++;
Books=realloc(Books,sizeof(Book)*n_books);
}
fclose(ptr);
}
else {
printf("Couldnt load books data");
exit(0);
}
free(Books);
return 0;
}
您的程序存在以下问题:
%s
转换格式说明符将只读取一个单词。while(!feof(ptr))
,这通常是错误的(在这种情况下也是错误的)。,
。%f
,您告诉fscanf
将float
存储到int price
中。Books=realloc(Books,sizeof(Book)*n_books);
只会为您当前使用的内容分配足够的内存,但您需要为当前使用的内容和下一本书分配足够的内存。这是解决这些问题的解决方案:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Date
{
int year;
int month;
} Date;
typedef struct Book
{
long long int isbn;
char title[100];
char author[100];
int quantity;
double price;
Date date;
} Book;
int main( void )
{
Book *Books;
int n_books = 0;
FILE *fp = fopen( "Books.txt", "r" );
if ( fp == NULL )
{
perror( "fopen" );
exit( EXIT_FAILURE );
}
Books = malloc( sizeof(Book) );
if ( Books == NULL )
{
fprintf( stderr, "Memory allocation error!\n" );
exit( EXIT_FAILURE );
}
while (
fscanf(
fp,
"%lld,%99[^,],%99[^,],%d,%lf,%d-%d",
&Books[n_books].isbn,
Books[n_books].title,
Books[n_books].author,
&Books[n_books].quantity,
&Books[n_books].price,
&Books[n_books].date.month,
&Books[n_books].date.year
)
== 7
)
{
printf( "Name: %s\n", Books[n_books].title );
printf( "ID: %lld\n", Books[n_books].isbn );
printf( "price: %lf\n", Books[n_books].price );
printf( "date: %d-%d\n", Books[n_books].date.month, Books[n_books].date.year);
printf( "quantity: %d\n", Books[n_books].quantity);
printf( "author: %s\n", Books[n_books].author);
n_books++;
Books = realloc( Books, sizeof(Book) * (n_books+1) );
if ( Books == NULL )
{
fprintf( stderr, "Memory allocation error!\n" );
exit( EXIT_FAILURE );
}
}
free(Books);
fclose( fp );
return 0;
}
对于问题中指定的输入,该程序具有以下输出:
Name: An Introduction to Organic Chemistry
ID: 9780136019701
price: 3.540000
date: 12-2008
quantity: 10
author: Timberlake Karen
Name: Mathematics for Social Scientists
ID: 9781506304212
price: 4.730000
date: 12-2015
quantity: 7
author: Kropko Jonathan
然而,同样值得注意的是,每次循环迭代调用一次realloc
是相当低效的,因为realloc
可能每次都必须将旧内存缓冲区的全部内容复制到新内存位置。 但是,如果您有成百上千本书,这可能只会成为一个问题。 有关使用realloc
的更有效算法,请参阅我对另一个问题的回答。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.