2014-10-30 80 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); 
} 
相关问题