2013-10-16 60 views
3

我只是試圖獲得一組數字(而我發佈的代碼不是我要使用的方法,我確實需要寫入二進制文件輸出在代碼中完成)。
一切工作正常,除了「ordenar」的最後一次迭代:當我在訂購後再次打印數字時,除了最後一行之外,所有東西都是有序的,我已驗證ordenar是否正確完成,並且在那最後一次迭代返回值爲10,但看起來好像它不寫入最後一次輸出。fwrite在最後一次迭代中不工作

代碼是:

#define _CRT_SECURE_NO_DEPRECATE 
#define SIZE 10 
#define MAX 10 

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

int numbers[SIZE]; 


int genera_numeros() { 
    unsigned long i, j; 
    FILE *file; 

    file = fopen("number.dat", "wb"); 
    if (!file) { 
     perror("fopen"); 
     return 1;  
    } 

    srand(time(0)); 
    for (i = 0; i < MAX; i++) { 
     for (j = 0; j < SIZE; j++) { 
      numbers[j] = rand()%1000; 
      printf("%i ", numbers[j]); 
     } 
     fwrite(numbers, sizeof(int), SIZE, file); 
     printf("\n"); 
    } 
    fclose(file); 
    return 0; 
} 


int imprime_numeros() { 
    unsigned long i, j; 
    int numbers[SIZE]; 
    FILE *file; 

    file = fopen("number.dat", "rb"); 
    if (!file) { 
     perror("fopen"); 
     return 1; 
    } 

    for (i = 0; i < MAX; i++) { 
     fread(numbers, sizeof(int), SIZE, file); 
     for (j = 0; j < SIZE; j++) { 
      printf("%i ",numbers[j]); 
     } 
     printf("\n"); 
    } 
    fclose(file); 
    return 0; 
} 

int compare (const void * a, const void * b) 
{ 
    return (*(int*)a - *(int*)b); 
} 


int ordenar(FILE* file, long int num_bloque) 
{ 
    int byte=0, written=0; 
    fseek(file, num_bloque * sizeof(int) * SIZE, SEEK_SET); 
    fread(numbers, sizeof(int), SIZE, file); 
    qsort (numbers, SIZE, sizeof(int), compare); 
    fseek(file, num_bloque * sizeof(int) * SIZE, SEEK_SET); 
    byte=ftell(file); 
    written=fwrite(numbers, sizeof(int), SIZE, file); 
    return 0; 
} 


int main(int argc, char* argv[]) { 
    FILE *file; 
     file = fopen("number.dat", "rb+"); 
    long int i; 

    genera_numeros(); 
    printf("\n\n Los numeros son:\n\n"); 
    imprime_numeros(); 
    printf("\n\n Ordenando..."); 

    for (i=0; i<MAX; i++) 
    { 
     ordenar(file, i); 
    } 

    printf("\n\n Los numeros son:\n\n"); 
    imprime_numeros(); 
    printf("\n"); 

    fclose(file); 
    system("PAUSE"); 
    return 0; 
} 
+0

您可以在開始時打開文件,然後在'genera'和'imprime'期間打開/關閉它。我很確定這是一個壞主意。如果您在'main'程序中打開'file'並等待排序循環之前會發生什麼? – Floris

+0

沒有運氣。 –

+0

你應該避免發佈大塊代碼。總是試着準備[簡短,獨立,正確,例子](http://www.sscce.org/) – zero323

回答

3

對於初學者來說,因爲我不知道究竟你的代碼是應該做的,刪除哪些給你段錯誤。
你關閉你file都與imprime_numeros()main()。 刪除一個或另一個,你的程序工作。



這是我的解決方案,您的問題不排序最後一行。只需再做一次

for(i=0;i<MAX+1;i++){ 

它工作。我目前正在研究「爲什麼」解決方案的一部分。
編輯1
我花了一段時間,但這裏有雲:
在你的main(),你必須FILE* file=fopen(..),這就是它是否正確開啓你不檢查的地方。每次你的程序運行時,它都沒有找到該文件,並且main()中的file設置爲NULL。


然後它愉快地繼續並調用函數genera_numeros(),它打開它自己的文件(並創建numbers.dat btw ...),但在本地範圍內,因爲外部genera_numeros()file仍爲NULL。

所以它創建一個文件,填充它並進入imprima_numeros(),打開先前創建的numbers.dat(仍然在本地範圍內,並在使用後關閉此文件)。

然後去ordenar部分,事情開始變得有趣。
ordenar(file, i)需要你的NULL文件和...崩潰與分段錯誤。
有趣一部分,什麼欺騙了我,是這將 occure第二次運行程序,因爲numbers.dat仍將從以前的運行)。

EDIT 2 FINAL 是的,我只花了2個非付費後期nigt在別人的代碼中發現的bug小時。我可能是那個人......無論如何...
問題是與同一個文件的多個打開。
我的意思是,當您修復之前的bug時,打開不存在的文件,或者只是運行程序第二次打開main()中的文件,然後用imprime_numerosgenera_numeros打開並關閉該文件幾次。這應該是implementation-defined的行爲。
問題是,在循環中最後一次呼叫ordenar()後,用imprime_numeros重新打開它,寫入的最後一個已排序的行在磁盤上的文件中尚不可見。這將在您關閉文件流後完成。所以你在寫入排序的最後一行之前就可以看到文件的狀態。

現在爲什麼我的MAX+1解決方案工作是因爲它強制寫最後一行permamently所以它是在您的文件可見imprime_numeros()打開。
這就是差不多所有。
請注意,通過添加MAX + 1,您可以獲得440字節大小的文件(我有4個字節的整數),它應該是400.我也忘記了提及如何解決這個問題,但您可以提出跟蹤根據我的描述。
提示
fclose(文件)在從它讀取之前。

所有正在閱讀本答案的人都對此感興趣,我將非常感謝您將它編輯爲語法,風格。這很晚了,這個花了我很多。

+0

我確實忘記檢查文件是否在main()中打開,但是我會確保該文件始終存在。 關於最後一次ieration沒有排序,我仍然不知道爲什麼會發生這種情況,但我注意到,沒有發生的不是最後一次,而是第一次。 我可以通過在主排序循環前後分別移動fopen和fclose來修復它。 有人可以解釋爲什麼會發生這種情況嗎? –

+0

@AdrianSalgado閱讀我的第二個更新。最後,我想。等等,再走一步。 – zubergu

+0

@AdrianSalgado在這裏,你去。所有的調試和解釋。 – zubergu

相關問題