试图用C打印文件的每一行

时间:2018-02-18 17:04:29

标签: c getopt

我正在尝试将文本文件的每一行打印到我作为命令行参数传递的标准输出。代码给了我一个Segmentation故障:11每次我在命令行中传入'-e'作为参数,但其他参数如'n','h'和'V'完全按照它们的方式工作。我只是想知道是否有人可以提供任何帮助。

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

int option;
int x;
char line[1000];
char string[1000];
char evenString[1000];
char *fileName;
int y = 0;
int lineCounter = 10;

if(strcmp(argv[1], "head") == 0){
    fileName = argv[2];
    FILE *fptr = fopen(fileName, "r");
    for(x = 0; x < 10; x++){
        fgets(line, sizeof(line), fptr);
        strcat(string, line);
    }
    printf("%s", string);
    fclose(fptr);
}
else{
    fileName = argv[3];
    FILE *fptr = fopen(fileName, "r");
    while ((option = getopt(argc, argv,"n:hVe")) != -1) {
        switch(option){
            case 'e':
                lineCounter = 22;
                for(y = 1; y < lineCounter; y++){
                    fgets(line, sizeof(line), fptr);
                    if(y % 2 == 0){
                        strcat(evenString, line);
                    }
                }
                fclose(fptr);
                printf("%s", evenString);
                break;
            case 'n':
                lineCounter = atoi(optarg);
                for(x = 0; x < lineCounter; x++){
                    fgets(line, sizeof(line), fptr);
                    strcat(string, line);
                }
                printf("%s", string);
                fclose(fptr);
                break;
            case 'V':
                printf("Name: Patrick Hessionn\nEmail: patrick.hession@ucdconnect.ie\nStudent Number: 16347891\nVariant: Head, Even\n ");
                break;
            case 'h':
                printf("-h: gives you the help for the head command\n-nK: prints the first K lines of the text file\n-V: Outputs the version information\n-e: prints the first 10 even lines of the text file\nhead: will print the first 10 lines of the input file.");
                printf("\nMake sure to format your input as so: 'Program name:', 'argument name:', 'file name:'\n");
                break;
            default ://'?'
                printf("Error!\nYou should format your input as so:\n'Program name:', 'argument name:', 'file name:'\n");
                break;
        }
    }
}

return 0;
}

1 个答案:

答案 0 :(得分:2)

请勿在未初始化的strcat()阵列上使用char

char string[1000];
char evenString[1000];

    ...
    strcat(string, line);

    ...

    strcat(evenString, line);

因为它期望有效的“字符串”作为参数。未初始化的char - 数组不是字符串。在C中,字符串需要至少有一个char设置为'\0'以标记其结尾。这也称为字符串的0 - 终结符,或NUL - 终结符(注意仅一个 ell)或null-terminator(注意 lower 案例和两个 ells)。

正确初始化char - 数组以变为空字符串。

char string[1000] = "";
char evenString[1000] = "";

或者更难以理解

  string[0] = '\0';

  strcpy(string, "");

此外,确实想要测试fopen()是否失败:

  FILE *fptr = fopen(fileName, "r");
  if (NULL == fptr)
  {
    perror("fopen() failed");
    exit(EXIT_FAILURE); /* include stdlib.h for EXIT_xxx macros. */
  }

如果有更多内容,你可以在这里找到另一个微妙的陷阱:

           for(y = 1; y < lineCounter; y++){
                fgets(line, sizeof(line), fptr);
                if(y % 2 == 0){
                    strcat(evenString, line);
                }
            }

这可以通过多种方式解决。一个直接的方法是:

           for(y = 1; y < lineCounter; y++){
                fgets(line, sizeof(line), fptr);
                if(y % 2 == 0){
                    if (sizeof evenString -1 < strlen(evenString) + strlen(line)
                                       /* -1 to take into account the space needed 
                                          for string's '0'-terminator. */
                    {
                       errno = ERANGE; /* include errno.h for errno and Exxx macros. */
                       perror("evenString to short for another line");
                       exit(EXIT_FAILURE);
                    }

                    strcat(evenString, line);
                }
            }

case 'n'相同。