我正在编写一个程序,它从用户那里获取行并解析它们以完成作业。 我被限制在一定量的内存中,因此下面使用的变量是我唯一可以使用的变量。
我的代码出现了分段错误,使用gdb发现它来自下面的strncpy()函数调用。我能看到这种情况的唯一原因是由于我使用strtok()导致str出错。如果有人可以指出我是如何错误地使用strtok()或者通过空格解析字符串的替代方法而没有任何添加的变量,我会非常感激。
字符串的格式为“00 COMMAND 0”,我试图将最后一位放入数组中,同时保留COMMAND以便以后计算。 COMMAND的长度从3到4不等。
char str[11];
*count = 0;
while( scanf( "%[^\n]%*c", str ) == 1 )
{
printf( "\n%s\n", str );
strtok( str, " " );
strtok( NULL, " " );
memory[*count] = atoi( strtok( NULL, " " ) );
strtok( str, " " );
strncpy( str, strtok( NULL, " " ), sizeof( str ) );
答案 0 :(得分:2)
strtok通过在标记末尾添加'\ 0'字符来更改str。因此,第二次使用str作为参数调用strtok时,它只会看到字符串的“00”部分。 最简单的解决方法是在第一次通过标记化时保存命令部分:
strtok( str, " " );
strncpy( str, strtok( NULL, " " ), sizeof( str ) );
memory[*count] = atoi( strtok( NULL, " " ) );
当然,您还应该检查strtok的返回值,以确保您没有传递错误的输入。
编辑 - 哎呀。我没有意识到你想把命令存回str。将命令部分复制回str应该是安全的,因为它必须比第一个参数+命令短。虽然看起来确实有点狡猾。使用该命令的另一个指针变量会更好。它只有4-8个字节的字节(取决于你的系统)。
char *command;
strtok( str, " " );
command = strtok( NULL, " " );
memory[*count] = atoi( strtok( NULL, " " ) );
答案 1 :(得分:0)
在我看来,首先要做的是从strtok()
捕获并打印返回值,或者在期望非空返回时检查它们是否为空。
鉴于代码的第二部分:
strtok(str, " ");
strncpy(str, strtok(NULL, " "), sizeof(str));
您正在使用strncpy()
复制字符串str
的一部分。这是未定义的行为:
如果在重叠的对象之间进行复制,则行为未定义。
当您调用未定义的行为时,任何事情都可能发生。
答案 2 :(得分:0)
只需将第二个令牌指针保存到' str'。无需复制。
printf( "\n%s\n", str );
strtok( str, " " ); /* apparently you don't care about this token */
str = strtok( NULL, " " ); /* 'str' now points to COMMAND */
memory[*count] = atoi( strtok( NULL, " " ) );