由fgets引起的分段错误(核心转储) - 我认为

时间:2017-01-03 04:05:59

标签: c

但是当我运行这个程序时,我一直收到这个错误。我认为这是因为fgets功能。我尝试将输入变量初始化为NULL以查看是否有帮助,但事实并非如此。我也有预感,我可能需要malloc来解决问题。但是,我非常感谢您的帮助。

int main(int argc, char* argv[])
{
    char* input = NULL;

    // ensure one and only one command line argument
    if (argc != 2)
    {
        printf("Usage: %s [name of document]\n", argv[0]);
        return 1;
    }

    // open a new document for writing
    FILE* fp = fopen(argv[1], "w");

    // check for successful open
    if(fp == NULL)
    {
        printf("Could not create %s\n", argv[1]);
        return 2;
    }

    // get text from user and save to file
    while(true)
    {
        // get text from user
        printf("Enter a new line of text (or \"quit\"):\n");
        fgets(input, 50, stdin);

        // if user wants to quit
        if (input != NULL && strcmp(input, "quit") == 0)
        {
            free(input);
            break;
        }
        // if user wants to enter text
        else if (input != NULL)
        {
            fputs(input, fp);
            fputs("\n", fp);
            printf("CHA-CHING!\n\n");
            free(input);
        }
    }

    // close the file and end successfuly
    fclose(fp);
    return 0;
}

4 个答案:

答案 0 :(得分:1)

你永远不会malloc - 编辑input,所以是的,fgets正在取消引用NULL指针作为其缓冲区,而这将会死亡。将input更改为堆栈数组(并为其删除free)或实际调用malloc以分配内存,以便input不指向NULL

答案 1 :(得分:0)

  

我认为这是因为fgets功能。

是:将NULL指针传递给fgets会使毫无意义,是不允许的,并且会导致崩溃。

  

我可能需要malloc来解决问题。

您需要将指针传递给fgets合适的缓冲区,以便将输入读入。该缓冲区是malloc,本地数据还是全局数组无关

TL; DR:想想你正在做什么。

答案 2 :(得分:0)

他们的代码存在一些问题。

  1. 您尚未为输入字符指针分配内存。因此,您无法在其中存储字符,因此您会出现分段错误。

  2. 此外,您免费不止一次,这是不正确的。

  3. 因此,具有上述修改的代码将是这样的:

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    int main(int argc, char* argv[])
    {
          char* input = malloc(sizeof(char) * 50);
    
          // ensure one and only one command line argument
          if (argc != 2)
          {
              printf("Usage: %s [name of document]\n", argv[0]);
              return 1;
          }
    
          // open a new document for writing
          FILE* fp = fopen(argv[1], "w");
    
          // check for successful open
          if(fp == NULL)
          {
              printf("Could not create %s\n", argv[1]);
              return 2;
          }
    
          // get text from user and save to file
          while(1)
          {
              // get text from user
              printf("Enter a new line of text (or \"quit\"):\n");
              fgets(input, 50, stdin);
    
              // if user wants to quit
              if (input != NULL && strcmp(input, "quit\n") == 0)
              {
                  free(input);
                  break;
              }
              // if user wants to enter text
              else if (input != NULL)
              {
                  fputs(input, fp);
                  fputs("\n", fp);
                  printf("CHA-CHING!\n\n");
                  // free(input);
              }
          }
    
          // close the file and end successfuly
          fclose(fp);
          return 0;
    }
    

    希望它可以帮助您解决问题。 欢呼声。

答案 3 :(得分:0)

虽然你可以在这里使用malloc(),但这并不是必需的。您可以#define合理的最大行长度,并声明一个字符数组来保存输入。如果您这样做,可以从代码中删除free

您使用fgets()的方式也存在问题。尾随\nfgets()保留,但您的比较忽略了这一点。因此,input永远不会等于"quit",绝对不会NULL。我已经包含了一些代码,在读入input后删除了尾随的换行符;代码还会清除输入流中的所有剩余字符,这在用户输入的字符数超过MAXLINE - 1时就可以实现。然后,对文本输入的测试只是if (input[0])。或者,您可以更改测试以考虑额外的&#39; \ n&#39;字符。

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

#define MAXLINE  1000

int main(int argc, char* argv[])
{
    char input[MAXLINE];
    char *ch;                       // used to remove newline
    char c;                         // used to clear input stream

    // ensure one and only one command line argument
    if (argc != 2)
    {
        printf("Usage: %s [name of document]\n", argv[0]);
        return 1;
    }

    // open a new document for writing
    FILE* fp = fopen(argv[1], "w");

    // check for successful open
    if(fp == NULL)
    {
        printf("Could not create %s\n", argv[1]);
        return 2;
    }

    // get text from user and save to file
    while(true)
    {
        // get text from user
        printf("Enter a new line of text (or \"quit\"):\n");
        fgets(input, MAXLINE, stdin);

        //  remove trailing newline
        ch = input;
        while (*ch != '\n' &&  *ch != '\0') {
            ++ch;
        }
        if (*ch) {
            *ch = '\0';
        } else {         // remove any extra characters in input stream
            while ((c = getchar()) != '\n' && c != EOF)
                continue;
        }

        // if user wants to quit
        if (strcmp(input, "quit") == 0)
        {
            break;
        }

        // if user wants to enter text
        else if (input[0])
        {
            fputs(input, fp);
            fputs("\n", fp);
            printf("CHA-CHING!\n\n");
        }
    }

    // close the file and end successfuly
    fclose(fp);
    return 0;
}