C 编程:使用 getline 后 strcmp 的意外结果
C programming: Unexpected results from strcmp after using getline
我正在编写一个 C 程序,它将从标准输入中获取命令列表并执行它们。从 stdin 读取后,我使用 strcmp 得到了意想不到的结果。
这是我的程序test_execvp.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
int main(int argc, char const *argv[])
{
char * line_buffer[100];
size_t line_len;
int cmd_count = 0;
char * cmd_buffer[100][100];
for( line_buffer[cmd_count] = NULL; getline(&line_buffer[cmd_count], &line_len, stdin) > 0; line_buffer[++cmd_count] = NULL)
{
line_buffer[cmd_count][strcspn(line_buffer[cmd_count], "\r\n")] = 0;
int cmd = 0;
while( (cmd_buffer[cmd_count][cmd] = strsep(&line_buffer[cmd_count], " ")) != NULL )
{
cmd++;
}
}
printf("cmd_buffer[0][0]: \"%s\"\n", cmd_buffer[0][0]);
printf("cmd_buffer[0][1]: \"%s\"\n", cmd_buffer[0][1]);
printf("cmd_buffer[0][2]: \"%s\"\n", cmd_buffer[0][2]);
printf("strcmp(cmd_buffer[0][1], \"-i\") == %d\n", strcmp(cmd_buffer[0][1], "-i") );
printf("strcmp(cmd_buffer[0][1], \"-o\") == %d\n", strcmp(cmd_buffer[0][1], "-o") );
}
现在看到这个输出:
Emil@EMIL-HP ~/Emil
$ gcc test_execvp.c -o test_execvp
Emil@EMIL-HP ~/Emil
$ cat cmdfile2
./addone –i add.txt
./addone
./addone –o add.txt
Emil@EMIL-HP ~/Emil
$ ./test_execvp < cmdfile2
cmd_buffer[0][0]: "./addone"
cmd_buffer[0][1]: "–i"
cmd_buffer[0][2]: "add.txt"
strcmp(cmd_buffer[0][1], "-i") == 181
strcmp(cmd_buffer[0][1], "-o") == 181
我不明白怎么行:
printf("strcmp(cmd_buffer[0][1], \"-i\") == %d\n", strcmp(cmd_buffer[0][1], "-i") );
可以产生输出:
strcmp(cmd_buffer[0][1], "-i") == 181
如果行:
printf("cmd_buffer[0][1]: \"%s\"\n", cmd_buffer[0][1]);
产生输出:
cmd_buffer[0][1]: "–i"
如果 argv[1]
是“-i”,那么 strcmp
将 return 0。但事实并非如此。仔细看,你会发现它是“-i”,这是一个不同的字符。 (它更长且多字节。)
您的文本文件包含 -
的一些 unicode 同形字符,而不是实际的 -
。这很清楚,因为 181+'-'
是 0xe2
,一个 3 字节字符的前导字节。
我正在编写一个 C 程序,它将从标准输入中获取命令列表并执行它们。从 stdin 读取后,我使用 strcmp 得到了意想不到的结果。
这是我的程序test_execvp.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
int main(int argc, char const *argv[])
{
char * line_buffer[100];
size_t line_len;
int cmd_count = 0;
char * cmd_buffer[100][100];
for( line_buffer[cmd_count] = NULL; getline(&line_buffer[cmd_count], &line_len, stdin) > 0; line_buffer[++cmd_count] = NULL)
{
line_buffer[cmd_count][strcspn(line_buffer[cmd_count], "\r\n")] = 0;
int cmd = 0;
while( (cmd_buffer[cmd_count][cmd] = strsep(&line_buffer[cmd_count], " ")) != NULL )
{
cmd++;
}
}
printf("cmd_buffer[0][0]: \"%s\"\n", cmd_buffer[0][0]);
printf("cmd_buffer[0][1]: \"%s\"\n", cmd_buffer[0][1]);
printf("cmd_buffer[0][2]: \"%s\"\n", cmd_buffer[0][2]);
printf("strcmp(cmd_buffer[0][1], \"-i\") == %d\n", strcmp(cmd_buffer[0][1], "-i") );
printf("strcmp(cmd_buffer[0][1], \"-o\") == %d\n", strcmp(cmd_buffer[0][1], "-o") );
}
现在看到这个输出:
Emil@EMIL-HP ~/Emil
$ gcc test_execvp.c -o test_execvp
Emil@EMIL-HP ~/Emil
$ cat cmdfile2
./addone –i add.txt
./addone
./addone –o add.txt
Emil@EMIL-HP ~/Emil
$ ./test_execvp < cmdfile2
cmd_buffer[0][0]: "./addone"
cmd_buffer[0][1]: "–i"
cmd_buffer[0][2]: "add.txt"
strcmp(cmd_buffer[0][1], "-i") == 181
strcmp(cmd_buffer[0][1], "-o") == 181
我不明白怎么行:
printf("strcmp(cmd_buffer[0][1], \"-i\") == %d\n", strcmp(cmd_buffer[0][1], "-i") );
可以产生输出:
strcmp(cmd_buffer[0][1], "-i") == 181
如果行:
printf("cmd_buffer[0][1]: \"%s\"\n", cmd_buffer[0][1]);
产生输出:
cmd_buffer[0][1]: "–i"
如果 argv[1]
是“-i”,那么 strcmp
将 return 0。但事实并非如此。仔细看,你会发现它是“-i”,这是一个不同的字符。 (它更长且多字节。)
您的文本文件包含 -
的一些 unicode 同形字符,而不是实际的 -
。这很清楚,因为 181+'-'
是 0xe2
,一个 3 字节字符的前导字节。