2012-03-23 3 views
0

내 프로그램에서 파일의 데이터를 읽는 데 문제가 있습니다. 문제는 파일이 현재 비어 있다는 것입니다. 프로그램이 실행될 때마다 한 장의 책 []이 채워져 나중에 코드에 기록됩니다. 10 개의 구조체가 모두 파일에있을 때 작동 할 것이라고 확신하지만 파일이 비어 있고 10 개의 구조체를 읽으려고하면 충돌이 발생합니다.파일에서 알 수없는 구조체 수를 읽는 중 -C

파일에서 알 수없는 구조체 (최대 10 개)를 읽을 수있는 방법이 있습니까?

struct stock 
{ 
    char name[31]; 
    int stock; 
}; 

int main (void) 
{ 
    stock books[10]; 

    FILE *fptr; 
    fptr = fopen("stock.dat", "rb"); 
    fread(books, sizeof(struct stock), 10, fptr); 

    fclose (fptr); 
} 
+0

어디에서 충돌이 발생합니까? 오류가 무엇입니까? 이것은 끔찍하게 거의 완벽한 문제 설명입니다. – tbert

+0

파일 형식을 제어하는 ​​경우 (즉, 다른 사람이 정의하지 않은 경우) 바이너리 대신 텍스트 형식 (예 : 이름, 행 당 한 행)을 사용하는 것이 좋습니다. 조금 더 많은 코드를 의미하지만 코드를 한 번만 작성하십시오. 파일이 훨씬 더 유용 할 것입니다. –

답변

2

당신이 파일의 구조의 최대 가능한 번호를 알고 메모리에 모두가 감당할 수있는 경우 :

int main (void) 
{ 
    #define MAX_BOOKS 10 
    stock books[MAX_BOOKS]; 
    size_t cnt_books = 0; 
    FILE *fptr; 
    fptr = fopen("stock.dat", "rb"); 
    cnt_books = fread(books, sizeof(struct stock), MAX_BOOKS, fptr); 
    fclose (fptr); 
    return 0; 
} 

그렇지 않으면 루프 덩어리로 읽을 :

while (cnt_books = fread(books, sizeof(struct stock), MAX_BOOKS, fptr)) { 
     /* ... */ 
    } 
2

예, 당신이 그것을 할 수 있습니다

  • 당신은 파일
  • 당신은 항목의 수를 확인해야
  • 읽고 있는지 확인하기 위해 fopen에 의해 반환 된 값을 확인해야 - size_t 반환 된 값 : fread
1

크래시? 그 진술이 아니라, 그 파일이 전혀 없다면 말입니다. name 필드는 유효한 C 문자열이 아니기 때문에 배열에 유효한 항목이 10 개 있다고 가정하면 충돌이 발생할 수 있습니다. 내가 선호하지만

num = fread(books, sizeof(struct stock), 10, fptr); 

:

num = fread (book, sizeof(*book), sizeof(book)/sizeof(*book), fptr); 

을 그 당신이 많은 코드를 변경할 필요가 없습니다 의미 때문에

당신은 당신이 실제로 읽고 얼마나 많은 알아낼 방법은 함께 형태 명이나 배열 사이즈가 바뀌는 이벤트

파일이 열리지 않을 수도있는 경우 fopen 반환 값을 확인해야합니다. 전체 코드가 같이 보일 것입니다 :

#include <stdio.h> 

typedef struct { 
    char name[31]; 
    int stock; 
} tStock; 

int main (void) { 
    tStock book[10]; 
    size_t num, i; 

    FILE *fptr = fopen ("stock.dat", "rb"); 
    if (fptr == NULL) { 
     num = 0; 
    } else { 
     num = fread (book, sizeof(*book), sizeof(book)/sizeof(*book), fptr); 
     fclose (fptr); 
    } 

    printf ("Read %d items\n", num); 
    for (i = 0; i < num; i++) { 
     printf (" Item %d is %s, %d\n", book[i].name, book[i].stock); 
    } 

    return 0; 
} 
0

코드가 괜찮아 보입니다. fread 매뉴얼 페이지를 참조하십시오 - 읽은 항목의 수를 반환합니다.

0
fptr = fopen("stock.dat", "rb"); 
if(fptr == NULL) 
{ 
    // error 
} 
else 
{ 
    for(int i=0; i<10 && !feof(fptr); i++) 
    { 
    fread(&books[i], sizeof(struct stock), 1, fptr); 
    } 
    fclose(fptr); 
} 
+0

나는 fread 함수 내에서 10 대신에 1을 의미한다고 생각한다. –

+0

@ CodeZordsman 실제로, 코드는 완전히 잘못되어 스스로도 알아 차렸다. 시정 해줘서 고마워. – Lundin

0
잘 모르겠어요

하지만 fread()이 충돌하지만,이 경우에는 0을 읽기 항목 수를 반환 안된다. 또한 정확히 어떻게 라인 stock books[10]; 컴파일 이해가되지 않는다, 그것은 struct stock books[10];이어야합니다.

두 가지를 제안합니다. 1. struct stock books[10]; 으로 바꿉니다. 중요한 일은 fptr이 NULL이 아닌지 확인하는 것입니다. 아마 그것은 파일을 열 수 없습니다 (아마도 같은 디렉토리에 있지 않거나 아직 존재하지 않습니다). 결과는 NULL fptr이며 fread에서 사용하면 응용 프로그램이 다운됩니다.

+0

'stock books [10];'는 C++ 컴파일러로 컴파일합니다 – gbulmer

관련 문제