分段错误:11在尝试解析字符串时

时间:2016-03-02 23:31:49

标签: c parsing segmentation-fault strtok strcpy

我试图将输入字符串解析为命令字符串和参数字符串数组。

我在使用strtok和strcpy时遇到了一些问题,我认为我的命令字符串没有被正确终止,这导致了seg错误。

#include <stdio.h>
#include <string.h>

#define delims " \t\r\n"

int main() {
    char input[] = "ls -a -f";
    char *buffer;
    char command[256];
    char arguments[256][256];
    int i = 0, j;

    buffer = strtok(input, delims);

    strcpy(command, buffer);

    printf("Command: %s\n\r", command);

    while (buffer != NULL)
    {
        buffer = strtok(NULL, delims);

        strcpy(arguments[++i], buffer);
    }

    buffer = strtok(NULL, delims);

    for (j = 0; j < i; ++i)
    {
        printf("Argument[%d]: %s", j, arguments[j]);
    }

    return 0;
}

当前输出:

Command: ls
Segmentation fault: 11

预期产出:

Command: ls
Argument[0]: -a
Argument[1]: -f

我不会假装对C很好,所以任何正确方向的指针都会非常有用。

2 个答案:

答案 0 :(得分:3)

您的问题可能围绕第.ToString()行。您正在使用它作为数组索引递增hash.delete_if.with_index {|(k, v), i| v.nil? && i != 0 } 然后。循环的第一轮将复制到数组索引1.当您从循环打印时,从索引0开始。由于您没有初始化数组,它们充满了垃圾,当您尝试打印时会发生不好的事情索引0(充满垃圾)作为字符串。

要解决此问题的两个建议:首先,将带有副作用的表达式(如strcpy(arguments[++i], buffer);)移动到自己的行中。这使事情变得更简单,并消除了任何操作顺序问题。其次,一旦你阅读它们就打印掉参数,而不是第二次循环回来。由于您只是打印值,这意味着您不需要整个数组来存储所有参数。您只需要足够的缓冲区来存储当前参数足够长的时间来打印它。

答案 1 :(得分:1)

以下代码:

  1. 干净利落地编译
  2. 删除不需要的局部变量
  3. 输出正确的项目,然后退出
  4. 定义具有有意义名称的幻数
  5. 使用NUL终止数组作为strtok()
  6. 的分隔符
  7. 使用'典型'名称作为strtok()
  8. 的返回值
  9. 始终检查strtok()
  10. 的返回值

    现在是代码:

    #include <stdio.h>
    #include <string.h>
    
    
    #define MAX_CMD_LEN (256)
    #define MAX_ARGS    (256)
    #define MAX_ARG_LEN (256)
    
    int main( void )
    {
        char input[] = "ls -a -f";
        char *token;
        char command[ MAX_CMD_LEN ] = {'\0'};
        char arguments[ MAX_ARGS ][ MAX_ARG_LEN ] = {{'\0'}};
    
        if ( NULL != (token = strtok(input, " \t\r\n" )) )
            strcpy(command, token);
    
        printf("Command: %s\n\r", command);
    
        size_t i = 0;
        while (i<MAX_ARGS && NULL != (token = strtok( NULL, " \t\r\n" ) ) )
        {
            strcpy(arguments[ i ], token);
            i++;
        }
    
    
        for( i=0; *arguments[i]; i++ )
        {
            printf("Argument[%lu]: %s\n", i, arguments[i]);
        }
    
        return 0;
    } // end function: main