簡體   English   中英

從txt文件中讀取數據到C中的結構

[英]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;
}

您的程序存在以下問題:

  1. %s轉換格式說明符將只讀取一個單詞。
  2. 您正在使用while(!feof(ptr)) ,這通常是錯誤的(在這種情況下也是錯誤的)。
  3. 您沒有跳過輸入流中的,
  4. 通過使用%f ,您告訴fscanffloat存儲到int price中。
  5. 該行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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM