2

我是 C 编程的新手。我正在尝试制作一个需要一些简单输入的程序。但是,我发现在将我的输入字符串与用户“打算”输入的内容进行比较时,最后还有一个额外的字符。我认为这可能是 '\0' 或 '\r' 但似乎并非如此。这是我的代码片段:

char* getUserInput(char* command, char $MYPATH[])
{
    printf("myshell$ ");
    fgets(command, 200, stdin);
    printf("%u\n", (unsigned)strlen(command));

    if ((command[(unsigned)strlen(command) - 1] == '\0') || (command[(unsigned)strlen(command) - 1] == '\r'))
    {
        printf("bye\n");
    }

return command;
}

代码显示输入时,说“退出”即输入了 5 个字符。但是我似乎无法弄清楚最后一个的身份。“再见”从不打印。有谁知道这个神秘人物可能是什么?

4

3 回答 3

9

The magical 5th element most probably is a newline character: \n

From man fgets() (emphasis by me):

fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A '\0' is stored after the last character in the buffer.

To prove this print out each character read by doing so:

char* getUserInput(char* command, char $MYPATH[])
{ 
  printf("myshell$ ");
  fgets(command, 200, stdin);
  printf("%u\n", (unsigned)strlen(command));

  {
    size_t i = 0, len = strlen(command);
    for (;i < len; ++i)
    {
      fprintf(stderr, "command[%zu]='%c' (%hhd or 0x%hhx)\n", i, command[i], command[i], command[i]); 
    }
  }

  ...
于 2013-10-15T06:29:54.613 回答
2

假设

  1. c中的数组索引以0开头
  2. strlen 返回字符串的长度

所以,如果你有 string "exit",这将是 array = 中的 5 个符号e, x, i, t, \0,strlen 返回 4,但你试图将它减 1,所以你正在检查 string 中的最后一个符号,而不是 NULL 终止符

检查 NULL 终止符的使用command[strlen(command)]- 这将\0永远给你,所以没有任何意义

如果要比较字符串,请使用strcmp函数

更新:您的程序出现问题是因为fgets\n在字符串末尾附加了符号:

换行符使 fgets 停止读取,但它被函数视为有效字符并包含在复制到 str 的字符串中。

于 2013-10-15T06:15:59.933 回答
0

您看不到最后一个字符的原因是因为strlen()不会将 '\0' 计算到字符串的长度中。所以测试 '\0' 不会成功。例如,const char* a = "abc";然后strlen(a)将是 3. 如果你想测试它,你需要通过command[strlen(command)]

在“退出”时获得strlen等于 5 的原因是因为fgets将在输入末尾附加 '\n' 字符。您可以通过以下方式对其进行测试command[strlen(command) -1 ] == '\n'

于 2013-10-15T06:13:27.757 回答