strtok() 然后 strcmp() 在 true 时返回 false
strtok() then strcmp() returning false when true
我猜这是一个类型问题,也许你可以告诉我它是如何正确完成的。
我正在读取来自 stdin
的命令输入,我想在用户输入 q
.
时退出
我正在使用 fgets()
将来自 stdin
的用户输入读取到指向字符数组的指针中。然后我使用 strtok()
拼接第一个单词并将其分配给另一个指向字符数组的指针。然后我将它与 q
进行比较,以查看用户是否要使用 strcmp()
函数退出程序。
这是一些代码:
char *input = (char*)malloc(32 * sizeof(char));
char *command = (char*)malloc(8 * sizeof(char));
while (strcmp(command, "q") != 0)
{
memset(input, 0, sizeof(input));
printf("Enter command: ");
fgets(input, 64, stdin);
command = strtok(input, " ");
//if I enter q --> printf("%d", strcmp(command, "q")) == 10
//if I enter w --> printf("%d", strcmp(command, "q")) == 6
}
我想要的是,如果 command == q
那么 printf("%d", strcmp(command, "q"))
应该等于 0
否则它应该打印任何其他整数。
我还应注意,我已确认 command
已正确分配。换句话说,当我输入 q
, command == "q"
.
也许你可以试试这个代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *input = (char*)malloc(32 * sizeof(char));
char *command = (char*)malloc(8 * sizeof(char));
while (strcmp(command, "q") != 0)
{
memset(input, 0, sizeof(input));
printf("Enter command: ");
fgets(input, 64, stdin);
command = strtok(input, " \n"); // Line corrected.
//if I enter q --> printf("%d", strcmp(command, "q")) == 10
//if I enter w --> printf("%d", strcmp(command, "q")) == 6
}
return 0;
}
这里有几个问题。
这里分配的内存
char *command = (char*)malloc(8 * sizeof(char));
这条线泄露的那一刻
command = strtok(input, " ");
作为对分配的内存的唯一引用被覆盖并因此丢失。
此处可能发生缓冲区溢出
fgets(input, 64, stdin);
允许读取更多字节 (64) ito input
因为它指向此处完成的分配
char *input = (char*)malloc(32 * sizeof(char));
假设用户输入的数据不包含像'[blanks]q ...then
commandget assigned
NULL`这样的序列调用
command = strtok(input, " ");
这导致在此处将 NULL
传递给 strcmp()
以在此处测试下一次迭代
while (strcmp(command, "q") != 0)
这样做会调用未定义的行为。
代码未检查相关函数调用的结果,例如 malloc()`` and
fgets()`。
在 C 中不需要转换 malloc()
& friends 的结果,也不推荐这样做。所以不要这样做。它可能很好地隐藏错误。
sizeof (char)
定义为 1
。不用用了
不要用 "Magic Numbers"/"Tokens" 破坏您的代码,例如 32
、8
、64
、"q"
...
如果您想至少执行一次,从概念上讲使用 while 循环是错误的方法。在这种情况下使用 do-while 循环。
修复所有这些问题可能会导致以下代码:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define INPUT_BUFFER_SIZE (64)
#define QUIT_STRING "q"
int main(void)
{
int result = EXIT_SUCCESS; /* Be optimistic. */
char *input = malloc(INPUT_BUFFER_SIZE * sizeof *input);
if (NULL == input)
{
perror("malloc () failed");
result = EXIT_FAILURE;
}
else
{
char *command;
do
{
printf("Enter command:\n");
if (NULL == fgets(input, INPUT_BUFFER_SIZE, stdin))
{
if (!feof(stdin))
{
result = EXIT_FAILURE;
fprintf(stderr, "fgets() failed.\n");
}
break;
}
command = strtok(input, " \n");
} while ((command == NULL) || strcmp(command, QUIT_STRING) != 0);
if (NULL != command)
{
printf("User quit.\n");
}
free(input);
}
return result;
}
我猜这是一个类型问题,也许你可以告诉我它是如何正确完成的。
我正在读取来自 stdin
的命令输入,我想在用户输入 q
.
我正在使用 fgets()
将来自 stdin
的用户输入读取到指向字符数组的指针中。然后我使用 strtok()
拼接第一个单词并将其分配给另一个指向字符数组的指针。然后我将它与 q
进行比较,以查看用户是否要使用 strcmp()
函数退出程序。
这是一些代码:
char *input = (char*)malloc(32 * sizeof(char));
char *command = (char*)malloc(8 * sizeof(char));
while (strcmp(command, "q") != 0)
{
memset(input, 0, sizeof(input));
printf("Enter command: ");
fgets(input, 64, stdin);
command = strtok(input, " ");
//if I enter q --> printf("%d", strcmp(command, "q")) == 10
//if I enter w --> printf("%d", strcmp(command, "q")) == 6
}
我想要的是,如果 command == q
那么 printf("%d", strcmp(command, "q"))
应该等于 0
否则它应该打印任何其他整数。
我还应注意,我已确认 command
已正确分配。换句话说,当我输入 q
, command == "q"
.
也许你可以试试这个代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *input = (char*)malloc(32 * sizeof(char));
char *command = (char*)malloc(8 * sizeof(char));
while (strcmp(command, "q") != 0)
{
memset(input, 0, sizeof(input));
printf("Enter command: ");
fgets(input, 64, stdin);
command = strtok(input, " \n"); // Line corrected.
//if I enter q --> printf("%d", strcmp(command, "q")) == 10
//if I enter w --> printf("%d", strcmp(command, "q")) == 6
}
return 0;
}
这里有几个问题。
这里分配的内存
char *command = (char*)malloc(8 * sizeof(char));
这条线泄露的那一刻
command = strtok(input, " ");
作为对分配的内存的唯一引用被覆盖并因此丢失。
此处可能发生缓冲区溢出
fgets(input, 64, stdin);
允许读取更多字节 (64) ito
input
因为它指向此处完成的分配char *input = (char*)malloc(32 * sizeof(char));
假设用户输入的数据不包含像'[blanks]q ...
then
commandget assigned
NULL`这样的序列调用command = strtok(input, " ");
这导致在此处将
NULL
传递给strcmp()
以在此处测试下一次迭代while (strcmp(command, "q") != 0)
这样做会调用未定义的行为。
代码未检查相关函数调用的结果,例如
malloc()`` and
fgets()`。在 C 中不需要转换
malloc()
& friends 的结果,也不推荐这样做。所以不要这样做。它可能很好地隐藏错误。sizeof (char)
定义为1
。不用用了不要用 "Magic Numbers"/"Tokens" 破坏您的代码,例如
32
、8
、64
、"q"
...如果您想至少执行一次,从概念上讲使用 while 循环是错误的方法。在这种情况下使用 do-while 循环。
修复所有这些问题可能会导致以下代码:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define INPUT_BUFFER_SIZE (64)
#define QUIT_STRING "q"
int main(void)
{
int result = EXIT_SUCCESS; /* Be optimistic. */
char *input = malloc(INPUT_BUFFER_SIZE * sizeof *input);
if (NULL == input)
{
perror("malloc () failed");
result = EXIT_FAILURE;
}
else
{
char *command;
do
{
printf("Enter command:\n");
if (NULL == fgets(input, INPUT_BUFFER_SIZE, stdin))
{
if (!feof(stdin))
{
result = EXIT_FAILURE;
fprintf(stderr, "fgets() failed.\n");
}
break;
}
command = strtok(input, " \n");
} while ((command == NULL) || strcmp(command, QUIT_STRING) != 0);
if (NULL != command)
{
printf("User quit.\n");
}
free(input);
}
return result;
}