2016-12-11 18 views
-1

我对C很陌生,有人“挑战”我尝试使用C创建排序程序。我来自语言在做这种事情的时候更高层次更容易,但我认为更低层次的错综复杂性比我的头脑要好。我还没有实现分类,因为我一路上遇到了障碍(只有其中一个)。C - 不能将文件存储到字符串数组中(基于脱行)

不管怎么说,这里是我的代码至今:

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

int main(int argc, char *argv[]) 
{ 
    FILE *unsortedFile; /* prepare file variable */ 
    char lineBuffer[100]; /* prepare variable for each line */ 
    char *listOfLines[100]; /* prepare line array variable to be sorted */ 
    int n = 0; 
    int i; 
    if (argc == 2) /* if a file has been given */ 
    { 
     unsortedFile = fopen(argv[1], "r"); /* open it readonly */ 
     if (unsortedFile == NULL) /* if it couldn't open */ 
     { 
      printf("Couldn't open the file %s\n", argv[1]); 
      printf("Does it exist?\n"); 
      return -1; /* stop the program here, return non-zero for error */ 
     } 
     printf("original file:\n\n"); 
     while (fgets(lineBuffer, sizeof(lineBuffer), unsortedFile)) 
     { 
      printf("%s", lineBuffer); 
      listOfLines[n] = lineBuffer; /* store line buffer to the array */ 
      n = ++n; /* increase n for the next array element */ 
     } 
     printf("\nLines to be sorted: %d\n", n); 
     for (i = 0; i < n; i++) 
     { 
      printf("%s", listOfLines[i]); 
     } 
    } else /* if no or too many args provided */ 
    { 
     printf("\nArgument error - you either didn't supply a filename\n"); 
     printf("or didn't surround the filename in quotes if it has spaces\n\n"); 
     return -1; /* return non-zero for error */ 
    } 
} 

在这一点上,你可能比你见过的最凌乱的意大利面条代码忙碌呕吐......但不管怎么说,这个问题发生在while声明,我猜。原始文件打印到控制台罚款,但我不认为每行都被存储到listOfLines

这里是什么在file.txt,我提供作为参数传递给该程序的文件:

zebra 
red 
abacus 
banana 

,这里是该程序的输出:

[email protected]:/mnt/c/Users/Dustin/projects/c/sort$ ./sort file.txt 
original file: 

zebra 
red 
abacus 
banana 

Lines to be sorted: 4 
banana 
banana 
banana 
banana 
[email protected]:/mnt/c/Users/Dustin/projects/c/sort$ 

貌似最后一行的文件是唯一一个存储到listOfLines?什么会导致这种行为?

在此先感谢!

+0

使用'getline',而不是'fgets'。 – BLUEPIXY

+0

@BLUEPIXY你确定OPs平台有吗?看起来像MinGW,所以也许不是。 – hyde

回答

1
  1. 需要字符数组的数组(不是指针数组)

交换:

char *lineOfLines[100];  // array of pointers 
char listOfLines[100][100]; // array of char arrays 
  • 然后使用strcpy
  • 交换:

    listOfLines[n] = lineBuffer; 
    strcpy(listOfLines[n], lineBuffer); 
    

    工作:

    #include <stdio.h> 
    #include <stdlib.h> 
    #include <string.h> 
    
    int main(int argc, char *argv[]) 
    { 
        FILE *unsortedFile; /* prepare file variable */ 
        char lineBuffer[100]; /* prepare variable for each line */ 
        char listOfLines[100][100]; /* prepare line array variable to be sorted */ 
        int n = 0; 
        int i; 
        if (argc == 2) /* if a file has been given */ 
        { 
         unsortedFile = fopen(argv[1], "r"); /* open it readonly */ 
         if (unsortedFile == NULL) /* if it couldn't open */ 
         { 
          printf("Couldn't open the file %s\n", argv[1]); 
          printf("Does it exist?\n"); 
          return -1; /* stop the program here, return non-zero for error */ 
         } 
         printf("original file:\n\n"); 
         while (fgets(lineBuffer, sizeof(lineBuffer), unsortedFile)) 
         { 
          printf("%s", lineBuffer); 
          strcpy(listOfLines[n], lineBuffer); /* store line buffer to the array */ 
          n = n + 1; /* increase n for the next array element */ 
         } 
         printf("\nLines to be sorted: %d\n", n); 
         for (i = 0; i < n; i++) 
         { 
          printf("%s", listOfLines[i]); 
         } 
        } else /* if no or too many args provided */ 
        { 
         printf("\nArgument error - you either didn't supply a filename\n"); 
         printf("or didn't surround the filename in quotes if it has spaces\n\n"); 
         return -1; /* return non-zero for error */ 
        } 
    } 
    
    +0

    我想你应该警告OP不要太多地使用堆栈。它可以堆栈溢出:页。顺便说一句,返回-1在主要 – Stargateur

    +0

    中无效,我对C不是很有经验,只是在排除故障。我恭敬地要求你向我解释你的意思?或者向我指出一些关于它的好文章的方向?我了解StackOverflow是什么,但我没有足够的经验来看到代码的问题。 :) – varlogtim

    +0

    主返回值是[“在0和255之间”](https://www.gnu.org/software/libc/manual/html_node/Exit-Status.html#Exit-Status)。并有链接将解释你的堆栈溢出http://stackoverflow.com/questions/9072415/disadvantages-of-using-large-variables-arrays-on-the-stack http://stackoverflow.com/questions/26158/如何做一个堆栈溢出发生和如何做你防止它 – Stargateur

    3

    listOfLines是一个指针数组。所有这些指针设置为指向lineBuffer

     listOfLines[n] = lineBuffer; 
    

    而且lineBuffer反复地从文件中的行覆盖。最后一行是banana,这是lineBuffer的最终值。

    然后,您的代码将打印listOfLines中的值,这些值都是指向lineBuffer的指针。


    这条线是非常错误的,顺便说一句(已未定义行为):

    n = ++n; 
    

    如果你想增加n,那要么

    n = n + 1; 
    

    ++n; 
    

    基本上,不要在同一个语句中两次修改相同的变量。

    +0

    感谢您的解释! – giggybyte

    相关问题