2014-10-30 113 views
0

我剛剛進入C,我認爲這將是一個很好的練習。我一直在試圖從文件中讀取fgets,我只是做錯了什麼。我想輸入要讀取的文件名,輸入要輸出的文件名,創建該文件,對其進行排序(只是一個單詞列表),然後將已排序的列表轉儲到已創建的文件中。我知道我應該這樣做:C:從一個文件讀取,排序,然後輸出到另一個

char strIn[25]; 
printf("Enter a source filename: "); 
fgets(strIn, 25, stdin); 
printf("You entered: %s \n", strIn); 
FILE *infile;  
infile = fopen(strIn, "r"); 
if (infile == NULL){ 
    printf("Unable to open file."); 
} 


char strOut[25]; 
printf("Enter a destination filename: "); 
fgets(strOut, 25, stdin); 
printf("You entered: %s \n", strOut); 
FILE *outfile; 

任何幫助表示讚賞!謝謝

+1

閱讀有關'scanf()的'功能 - 這將是收集輸入更理智的方式,此外,如果你想練習考慮寫你自己的輸入功能,使用'的getchar()' – 4rlekin 2014-10-30 08:31:32

+0

你constaining你的文件名25個字符,因此查找適當的任意長度的字符串輸入。 – GKFX 2014-10-30 09:00:04

回答

2

你是在正確的軌道上。 qsort會做你想做的。這裏使用的方法不可擴展;一切都保存在內存中,靜態分配會使事情變得非常迅速,但它可以作爲一個玩具的例子。目前,一旦輸入文件中有超過1000行,它將會中斷。

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

#define MAXNAMELEN 100 
#define MAXLINELEN 100 
#define MAXITEMS 1000 

int main(int argc, char ** argv) { 

    FILE * infile, * outfile; 
    // Statically allocated -- dastardly! 
    char name[MAXNAMELEN]; 
    char line[MAXLINELEN]; 
    char lines[MAXITEMS][MAXLINELEN]; 
    int i, items = 0; 

    printf("Enter a source filename: "); 
    fgets(name, sizeof(name), stdin); 
    name[strlen(name)-1] = '\0'; // strip newline 
    // No error checking -- ANYWHERE -- dastardly! 
    infile = fopen(name, "r"); 
    while (fgets(line, sizeof(line), infile)) { 
      strcpy(lines[items], line); 
      items++; 
    } 

    qsort(lines, items, MAXLINELEN, strcmp); 

    printf("Enter a destination filename: "); 
    fgets(name, sizeof(name), stdin); 
    name[strlen(name)-1] = '\0'; // strip newline 
    outfile = fopen(name, "w"); 
    for (i=0; i<items; i++) { 
     fputs(lines[i], outfile); 
    } 

    fclose(infile); 
    fclose(outfile); 
} 
3

fgets將換行符\n放在緩衝區的末尾。所以你需要刪除它。

int length = strlen(strIn); 
if (length > 0 && strIn[length-1] == '\n') 
    strIn[length-1] = '\0'; 
1

現在通過動態分配和錯誤檢查(可能比上述版本有所改進)。排序/usr/share/dict/words(99171行)完全沒有問題。仍然要求整個數組保存在內存中。有關此方法,請參閱External Sorting

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

#define CHUNKLEN 100 
#define INITITEMS 1000 

/* Reads a string from stream into buffer until a newline or EOF. 
    buffer is dynamically allocated (and reallocated if necessary) 
    to ensure the string fits. Returns the number of characters put 
    into the buffer (zero if EOF and no characters read), or -1 on error. */ 

int unlimited_read(char ** buffer, FILE * stream) { 

    int bufl = CHUNKLEN; 
    int strl = 0; 
    char * chunk = (char *)malloc(CHUNKLEN); 

    if ((*buffer = (char *) malloc(CHUNKLEN)) == NULL) { 
     perror("memory error (malloc)"); 
     return -1; 
    } 

    while (fgets(chunk, CHUNKLEN, stream) != NULL) { 

     strcpy(*buffer + strl, chunk); 
     strl += strlen(chunk); 

     if ((strl == bufl - 1) && *(*buffer + strl - 1) != '\n') { 

      // lengthen buffer 
      bufl += CHUNKLEN - 1; 
      if ((*buffer = realloc(*buffer, bufl)) == NULL) { 
       perror("memory error (realloc)"); 
       return -1; 
      } 

     } else { 
      // This shouldn't fail -- we're only ever making it smaller 
      *buffer = realloc(*buffer, strl); 
      return strl; 
     } 

    } // while 

    // If fgets returned NULL and we are not at EOF, it didn't work 
    return feof(stream) ? strl : -1; 
} 

/* Compare two strings given pointers to those strings. 
    Routine is courtesy of the qsort man page */ 

int cmpstringp(const void *p1, const void *p2) { 
    return strcmp(* (char * const *) p1, * (char * const *) p2); 
} 

/* Sort lines in a file. File must end with a newline. */ 
int main(int argc, char ** argv) { 

    FILE * infile, * outfile; 
    char * inname, * outname, *tmpstr; 
    char ** lines; 
    int ret, tmp, nlines, i, items = 0; 

    if (argc != 3) { 
     printf("Usage: %s file_to_sort output_file\n", argv[0]); 
     exit(EXIT_FAILURE); 
    } 

    inname = argv[1]; 
    outname = argv[2]; 

    if ((lines = malloc(INITITEMS * sizeof(char *))) == NULL) { 
     perror("memory error (malloc)"); 
     exit(EXIT_FAILURE); 
    } 

    nlines = INITITEMS; 

    infile = fopen(inname, "r"); 
    while ((ret = unlimited_read(&lines[items], infile)) > 0) { 
      items++; 
      if (items == nlines) { 
       nlines += INITITEMS; 
       lines = realloc(lines, (nlines * sizeof(char *))); 
      } 
    } 

    if (ret < 0) { 
     printf("WARNING: possibly truncated file\n"); 
    } 

    tmpstr = lines[items - 1]; // Final line in file 
    tmp = strlen(tmpstr); 
    if (tmpstr[tmp - 1] != '\n') { 
     printf("Error: input file does not end with newline\n"); 
     exit(EXIT_FAILURE); 
    } 

    qsort(lines, items, sizeof(char *), cmpstringp); 

    outfile = fopen(outname, "w"); 

    for (i = 0; i < items; i++) { 
     fputs(lines[i], outfile); 
     free(lines[i]); 
    } 
    free(lines); 

    fclose(infile); 
    fclose(outfile); 
} 
相關問題