2015-06-01 41 views
0

我有一個問題,關於我的Quicksort文件中的字符串的實現。快速排序的字符串和C語言文件

此練習要求輸入要打開的文件的文件名,最多可以有100個項目。使用函數char filling(FILE* myfile),將文件中包含的每一行都通過一個在文件結束處結束的while循環複製到數組中。

然後它被稱爲函數sort(strings, start, end, leq)來排序字符串數組,這些字符串在函數結尾處將被複制到一個名爲sorted_myfile的新文件中。

我的問題是:如何測試我的程序是否適用於文件?

在函數char filling中,聲明leq_fn leq指向函數typedef bool(* leq_fn)(char *, char *)的指針的聲明,該指針包含在快速排序的函數中。我希望我給你所需的所有信息來幫助我。謝謝。

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include "quicksort.h" 
#define MAX_LENGTH 100 
#define EXTRA_LENGTH 101 
#define LENGTH_STRING 255 

char filling(FILE *myfile); 
char *strings[MAX_LENGTH]; //Array of at most 100 items 

char filling(FILE *myfile){ 
    char *row; 
    char new_filename[LENGTH_STRING]; 
    FILE* sorted_myfile; 
    int i=0, start=0, end=MAX_LENGTH-1; 
    bool res_cmplen, res_cmpalpha, res_cmpalpha_nocase; 
    FILE *sorted_myfile; 

    while(i<=EOF){ 
    if(i==EXTRA_LENGTH){ 
     printf("The file has more than 100 items\n"); 
    }else{ 
     row = calloc(LENGTH_STRING, sizeof(char)); 
     fgets(row, LENGTH_STRING, myfile); 
     strings[i]=row; 
     i++; 
     free(row); 
    } 
    } 
    leq_fn leq; 

    leq = cmp_len; 
    res_cmplen = (*leq)("hello", "bye"); 
    leq = cmp_alpha; 
    res_cmpalpha = (*leq)("HELLO", "bye"); 
    leq = cmp_alpha_nocase; 
    res_cmpalpha_nocase = (*leq)("hello", "BYE"); 

    sort(strings, start, end, leq); 
    scanf("%s", new_filename); 
    sorted_myfile = fopen(new_filename, "w"); 
    for(i=0;i<end;i++){ 
    fputs(strings[i], sorted_myfile); 
    } 

    return 0; 
} 


int main(void) { 
    char filename[LENGTH_STRING]; 
    FILE *myfile; 

    printf("What is the file name?\n"); 
    scanf("%s", filename); 
    myfile = fopen(filename, "r"); 

    if(ferror(myfile)!=0){ 
     printf("The file doesn't exist\n"); 
    }else{ 
     filling(myfile); 
    } 

    return 0; 
} 
+1

在'filling'函數中,循環不會被迭代一次。宏EOF通常定義爲'-1','0 <= -1'永遠不會成立。另外,爲了檢查文件是否正確打開,你需要檢查返回的指針是否爲'NULL',而不是調用'ferror',並且除文件不存在外還可能有許多其他問題。 –

+0

@JoachimPileborg所以在while循環中變量** i **會被初始化爲-1? –

+0

另外,你的代碼中有*未定義的行爲*,你首先使用'calloc'分配內存,複製*指針*(但不是指針指向的內容),然後釋放剛剛分配的內存,指針指向未分配的內存。以任何方式使用該指針都會導致未定義的行爲。 –

回答

1

我第一次開始與修復這些:

  1. 變化char *row;char *row = NULL;
  2. 同樣改變FILE* sorted_myfile;FILE* sorted_myfile = NULL;
  3. 變化bool res_cmplen, res_cmpalpha, res_cmpalpha_nocase;
    bool res_cmplen = 0, res_cmpalpha = 0, res_cmpalpha_nocase = 0;
    bool res_cmplen = 1, res_cmpalpha = 1, res_cmpalpha_nocase = 1;
    取決於什麼是更安全的實施。
  4. 變化FILE *sorted_myfile;FILE *sorted_myfile = NULL;
  5. main()變化FILE *myfile;FILE *myfile = NULL;
  6. free(row);row成爲懸擺指針,然後你把它作爲是什麼,然後在循環的最後一次迭代,你離開它是,這會調用未定義的行爲。因此,在釋放內存後執行row = NULL;
  7. char *strings[MAX_LENGTH];不是//Array of at most 100 items,而是//array of MAX_LENGTH pointers。這裏發生了什麼:strings[i]=row;
  8. 在下面的片段:

    while(i<=EOF){ 
        if(i==EXTRA_LENGTH){ 
         printf("The file has more than 100 items\n"); 
        }else{ 
         row = calloc(LENGTH_STRING, sizeof(char)); 
         fgets(row, LENGTH_STRING, myfile); 
         strings[i]=row; 
         i++; 
         free(row); 
        } 
    } 
    

    i遞增在else{}條件和if(i==EXTRA_LENGTH)評估爲真即,如果i等於EXTRA_LENGTH,它不會被增加或修改,因爲在else{}僅發生。所以當i == 255時,你的代碼永遠不會輸入else{}條件,只能打印「該文件有100多項」無限。

  9. 這是一個小的,但是,在main()我可以看到myfile = fopen(filename, "r");,這將打開文件。精細。雖然我沒有看到你什麼時候關閉它,但是如果你完成的話。某處可能會丟失fclose();

+1

6.由於內存需要在排序操作過程中保持分配狀態,因此直到以後才能執行'free'。 –