【问题标题】:simple input. program crashes简单的输入。程序崩溃
【发布时间】:2012-03-05 06:41:09
【问题描述】:
#include <stdio.h>
#include <string.h>

int main(){        
    char *command="0";

    do {   
      printf("[A]dd, [P]rint, [Q]uit\n");
      scanf("%s", command);

    while (strcmp(command, "a") != 0 && strcmp(command, "A") != 0 && strcmp(command, "p") != 0 && strcmp(command, "P") != 0){
        printf("Invalid input. Please enter one of the commands listed above.\n");
        scanf("%s", command);
    }       

       if (strcmp(command, "a") == 0 || strcmp(command, "A") == 0){
           printf("You selected add.\n");
       }
       else if (strcmp(command, "p") == 0 || strcmp(command, "P") == 0){
           printf("You selected print.\n");
       }
    }while (strcmp(command, "q") != 0 && strcmp(command, "Q")!= 0);
    return 0;
}

我希望程序从开头打印的指定命令之一接收用户的一封信。如果他们输入 q 或 Q,我希望程序退出。我花了一段时间才弄清楚如何与循环和 if 的字符串进行比较。现在当我运行程序时它崩溃了。寻找有关其崩溃原因的见解。

【问题讨论】:

  • 可能有助于包含您收到的错误消息。
  • 它在哪里崩溃?附加调试器时,程序崩溃时的状态是什么?实际状态是否符合您的预期状态?
  • 你不能改变command的内容:它指向一个字符串字面量。请尝试使用数组:char command[] = "0";。并确保限制使用 scanf 读取的字符串的长度:scanf("%1s")
  • scanf 正在尝试将 N 个字节写入 command 指向的地址,这是一个字符串文字(只读)。你需要分配足够的内存来存储这N个字节,或者声明一个chars的定长数组。示例:char command[255]; scanf("%254s", command);

标签: c


【解决方案1】:

是的,将您的缓冲区command 变成一个常规数组,并使其更大:

char command[256];

不需要初始化它,scanf 会处理的。此外,它不会影响崩溃,但如果你只检查一个字母,你可以这样做:

if command[0] != 'a' && command[0] != 'A' (etc.)

注意单引号:这是一个字符比较。

【讨论】:

    【解决方案2】:
    char *command="0";
    scanf("%s", command);
    

    您正在写入一个字符串文字(只有 2 个字节),并且字符串文字不需要是可修改的。

    改用这样的东西:

    char command[256];
    scanf("%s", command);
    

    或更好地使用fgets + sscanf 以避免潜在的缓冲区溢出。

    【讨论】:

      【解决方案3】:

      这是一个指向只读内存的指针:

      char *command="0";
      

      这意味着这是错误的:

      scanf("%s", command);
      

      “快速破解”是不好的方法,它是更改命令的定义,使其获得一些读写内存而不是只读内存:

      char command[256] = "0";
      

      但这仍然使您面临缓冲区溢出的严重危险。不要使用scanf

      “更好的方法”是使用fgets 而不是scanf

      char command[256];
      char *p;
      p = fgets(command, sizeof(command), stdin);
      if (!p) { handle error or EOF }
      /* Don't forget that 'command' will probably have '\n' at the end,
         you will have to strip it off */
      

      【讨论】:

      • fgets 和 sccanf 在这种情况下更好吗?
      • 传递给scanf的格式字符串允许限制字符串大小。示例:“%255s”
      • @jweyrich:这很好,但还有 99 个其他理由不使用scanf
      • @TristanPearce:避免使用 sscanfscanffscanfvfscanfvscanfvsscanf。正确使用它们太棘手了。
      【解决方案4】:

      好吧,我首先想到的是您正在使用scanf 将数据读入只读内存——即字符串常量。当您尝试此操作时会发生什么未定义,但可能会导致程序崩溃。你需要为command分配一些读/写内存;例如,将其声明为

      char command[10];
      

      【讨论】:

        猜你喜欢
        • 2012-08-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-21
        • 1970-01-01
        相关资源
        最近更新 更多