【问题标题】:Segmentation fault while operating on user input string对用户输入字符串进行操作时出现分段错误
【发布时间】:2016-01-13 13:19:35
【问题描述】:

您好,我是 C 编码新手,我似乎找不到在 while 循环开始后导致段错误的问题。

int main() {
    char option;
    char nickname;

    printf("Welcome to our chat program. Please select mode (Send,Nickname,Exit): ");

    while (gets(option)) {

        if(!strncmp(option, "Exit", 4)) {
            break;
        }

        if(!strncmp(option, "Nickname", 8)){
            set_nickname(nickname);
        }

        if(!strncmp(option, "Send", 4)){
            if(!nickname){
            nickname = "Anonymous";
            printf("Your nickname was set to Anonymous!");
            }
            send_message(nickname);
        }
    }

【问题讨论】:

  • 你应该用一些警告标志编译:-W -Wall 例如。然后你会看到你的错误。
  • 看起来你只为optionnickname 保存了一个字符,而你正在将它们与多个字符串进行比较。这可能是问题所在。
  • 编译所有警告和调试信息 (gcc -Wall -Wextra -g)。 使用调试器 (gdb) 和valgrind。顺便说一句,gets过时,应该从不使用。使用fgetsgetlinereadline

标签: c arrays string segmentation-fault


【解决方案1】:

代码有很多问题。让我们一一讨论。

  • 首先,char 不足以容纳 字符串,您还需要一个

    • 一个数组
    • 具有正确(动态)内存分配的指针。

    使用第一种方法,你需要改变

    char option;
    char nickname;
    

    #define SIZ 64
    
    char option[SIZ] = {0};
    char nicknamep[SIZ] = {0};
    
  • 那么,您应该使用fgets() 而不是使用gets(),以避免缓冲区溢出的可能性。类似的东西

    fgets(option, SIZ, stdin);
    

    会的。

  • 也就是说,一旦option 成为一个数组,您就不能分配 给它。您需要使用strcpy() 将内容复制到数组中。例如,

    strcpy(nickname, "Anonymous");
    

【讨论】:

    【解决方案2】:

    没有为字符串分配内存。

    你需要这样的东西:

    char option[50];
    char nickname[50];
    

    并在此处使用strcpy()

    nickname = "Anonymous";
    

    并以strlen() 为例检查字符串。

    if(!nickname){
    

    使用带有长度参数的fgets() 也更安全,以防止缓冲区溢出。

    while (gets(option)) {
    

    【讨论】:

      【解决方案3】:

      option 必须是char[???]

      不确定昵称,但它还需要分配内存和/或初始化。你是怎么设置的?你使用什么值?

      您还需要检查 strlen(nickname)>0 而不是 !nickname,这将测试空指针,而不是空字符串。

      【讨论】:

        【解决方案4】:

        永远永远使用gets;它无法正确使用。而是使用fgets,将stdin 作为第三个参数。

        您会注意到fgets 将您要分配的存储长度作为其第二个参数。 gets函数中缺少这个参数是不能正确使用的原因。在您的情况下,您应该将值 1 传递给它,并将您的 char 变量的地址传递给它。然后fgets 会将一个字符读入您的变量中。

        如果您想阅读更多内容,首先需要为要阅读的数据分配更多存储空间。例如,您可以为 80 个字符分配空间:

        char string[80];
        

        您现在可以使用fgets,其中string 作为第一个字符,80 作为第二个字符,stdin 作为第三个字符。然后fgets 将从stdin 中读取最多 80 个字符。

        如果您不想将该数字存储在源代码中的两个位置,则可以改用 sizeof 运算符,或使用宏来预定义缓冲区的大小。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-10-22
          • 2019-08-21
          • 2015-05-20
          • 2017-08-01
          • 2012-06-22
          • 2020-08-20
          • 2013-09-16
          • 2017-05-03
          相关资源
          最近更新 更多