2016-12-07 80 views
1
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#define SLENG 50 //just a random value 

typedef struct Song 
{ 
    char *name; 
    char *nameSong; 
    char *timeSong; 
    int date; 
} Song; 

void saveToFile(Song *x, int *songCount) //Saves info to the binary file 
{ 
    FILE *f = fopen("array.txt", "w"); 
    if (f == NULL) 
    { 
     printf("Error\n"); 
    } 
    fwrite(songCount, sizeof(int), 1, f); 
    fwrite(x, sizeof(struct Song), (*songCount), f); 
    fclose(f); 
} 

void readSong(Song *x, int *songCount) //Reads info fromt he file and writes it 
{ 
    FILE *fr = fopen("array.txt", "r"); 
    if (fr == NULL) 
    { 
     printf("Error\n"); 
    } 
    printf("Songs:\n"); 
    fread(songCount, sizeof(int), 1, fr); 
    fread(x, sizeof(struct Song), (*songCount), fr); 
    for(int i=0; i < (*songCount); i++) 
    { 
     printf("%d. %s %s %s %d\n", (i+1), x[i].name, x[i].nameSong, x[i].timeSong, x[i].date); 
    } 
    fclose(fr); 
} 

void insertSong(Song *x, int Count) //Inserts new song into the array. 
{ 
    printf("\nInsert name of the band:\n"); 
    x[Count].name=malloc(SLENG * sizeof(char)); 
    scanf("%s", x[Count].name); 

    printf("Insert name of the song:\n"); 
    x[Count].nameSong=malloc(SLENG * sizeof(char)); 
    scanf("%s", x[Count].nameSong); 

    printf("Insert length of the song:\n"); 
    x[Count].timeSong=malloc(SLENG * sizeof(char)); 
    scanf("%s", x[Count].timeSong); 

    printf("Insert then song was created:\n"); 
    scanf("%d", &(x[Count].date)); 
    printf("\n"); 
} 

main() 
{ 
    int songCount, menuOption; 
    Song *x=malloc(SLENG*sizeof(char)+SLENG*sizeof(char)+SLENG*sizeof(char)+sizeof(int)); 
    printf("1. insert song\n 2. load from file\n "); 
    scanf("%d", &menuOption); 
    switch(menuOption) 
    { 
     case(1) : 
      printf("Insert how many songs do you want to input?\n"); 
      scanf("%d", &songCount); 
      for(int i=0; i<songCount; i++) 
      { 
       insertSong(x, i); 
      } 
      saveToFile(x, &songCount); 
      break; 
     case(2) : 
      readSong(x, &songCount); 
      break; 
    } 
} 

我有一個assingment寫PROGRAMM這將輸入一些數據文件,並可以從文件中讀取數據,該問題可能與FWRITE或fread,當我嘗試從文件加載並寫入數據時,似乎崩潰了。任何想法爲什麼它不能正常工作?我甚至可以這樣做,因爲它是動態結構數組。提前致謝。C不加載從文件信息(FREAD,FWRITE)

+2

歡迎堆棧溢出!這聽起來像你可能需要學習如何使用調試器來遍歷代碼。使用一個好的調試器,您可以逐行執行您的程序,並查看它與您期望的偏離的位置。如果你打算做任何編程,這是一個重要的工具。進一步閱讀:[如何調試小程序](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)。 –

+2

指針特定於單個進程。你不能保存指針。沒有辦法將指針加載到另一個進程中,即使它是相同的程序。要麼使用數組,要麼想出一種方法來[*序列化*](https://en.wikipedia.org/wiki/Serialization)每個結構中的數據。是的,指針都是你保存的。 –

+0

至於數組的問題,你總是無條件地爲每個字符串分配'SLENG'字符。這確實比編譯時固定大小的數組要好。 –

回答

2

爲了將結構保存到文件中,它必須只包含標量值,而不是指向內存對象的指針。修改您的結構,而不是使用指針數組:

typedef struct Song { 
    char name[SLENG]; 
    char nameSong[SLENG]; 
    char timeSong[SLENG]; 
    int date; 
} Song; 

,並相應修改了代碼,但要注意:

  • 保存和讀取的結構,並從文件的二進制模式"wb"需要打開它和"rb"
  • 它是很容易讓人誤解的來命名一個二進制文件array.txt
  • 寫入文件時,您不需要傳遞計數地址,但在讀取時需要傳遞數組指針的地址,因爲您還不知道要分配多少內存。

下面是修改代碼:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#define SLENG 50 // this value is used in the file format 

typedef struct Song { 
    char name[SLENG]; 
    char nameSong[SLENG]; 
    char timeSong[SLENG]; 
    int date; 
} Song; 

int saveToFile(Song *x, int songCount) { //Saves info to the binary file 
    FILE *f = fopen("array.bin", "wb"); 
    if (f == NULL) { 
     printf("Error\n"); 
     return -1; 
    } 
    fwrite(songCount, sizeof(int), 1, f); 
    int written = fwrite(x, sizeof(struct Song), songCount, f); 
    fclose(f); 
    return written; 
} 

int readSong(Song **x, int *songCount) { //Reads info from the file and writes it 
    int count = 0; 
    FILE *fr = fopen("array.bin", "rb"); 
    if (fr == NULL) { 
     printf("Error\n"); 
     return -1; 
    } 
    printf("Songs:\n"); 
    fread(&count, sizeof(int), 1, fr); 
    *x = calloc(count, sizeof(Song)); 
    if (*x == NULL) { 
     printf("Cannot allocate %d bytes of memory\n", count); 
     fclose(fr); 
     return -1; 
    } 
    int found = fread(*x, sizeof(struct Song), count, fr); 
    for (int i = 0; i < found; i++) { 
     printf("%d. %s %s %s %d\n", i + 1, 
       (*x)[i].name, (*x)[i].nameSong, (*x)[i].timeSong, (*x)[i].date); 
    } 
    fclose(fr); 
    return *songCount = found; 
} 

void insertSong(Song *x, int Count) { //Inserts new song into the array. 
    printf("\nInsert name of the band:\n"); 
    scanf("%49s", x[Count].name); 

    printf("Insert name of the song:\n"); 
    scanf("%49s", x[Count].nameSong); 

    printf("Insert length of the song:\n"); 
    scanf("%49s", x[Count].timeSong); 

    printf("Insert then song was created:\n"); 
    scanf("%d", &(x[Count].date)); 
    printf("\n"); 
} 

int main(void) { 
    int songCount, menuOption; 
    Song *x = NULL; 

    printf("1. insert song\n 2. load from file\n "); 
    scanf("%d", &menuOption); 

    switch (menuOption) { 
     case 1: 
     printf("Insert how many songs do you want to input?\n"); 
     if (scanf("%d", &songCount) == 1) { 
      x = calloc(songCount, sizeof(Song)); 
      for (int i = 0; i < songCount; i++) { 
       insertSong(x, i); 
      } 
      saveToFile(x, songCount); 
     } 
     break; 
     case 2: 
     readSong(&x, &songCount); 
     break; 
    } 
    free(x); 
    x = NULL; 

    return 0; 
} 
+0

你在calloc函數中顛倒了參數 – Fefux

+0

@Fefux:對'calloc()'的參數順序沒有任何影響,但它的確記錄爲void * calloc(儘管與'bsearch'一致,但在C標準中與'size_t fread(void * ptr,size_t size,size_t nmemb,FILE * stream);'和'fwrite()'不一致'和'qsort'。 – chqrlie

+0

是的,但它只是符合文檔 – Fefux