strncpy()分段错误:shady strtok()操作?

时间:2014-03-21 04:45:03

标签: c string segmentation-fault

我正在编写一个程序,它从用户那里获取行并解析它们以完成作业。 我被限制在一定量的内存中,因此下面使用的变量是我唯一可以使用的变量。

我的代码出现了分段错误,使用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 ) );

3 个答案:

答案 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, " " ) );