将缓冲区转换为char数组以用于strtok

时间:2019-02-04 16:19:36

标签: c arrays system-calls

在C中使用系统调用时遇到了一些麻烦。我试图使用readstdin中读取一些输入,然后使用strtok将值加载到数组中,但是我可以似乎做对了(我一直在做段错误)。

这是我开始的代码:

void read_input()
{
    char* c;
    read(0, c, 128);
    printf("%s", c);
}

所以,这工作正常,我可以打印输出。但是,我接下来尝试了几件事,但没有成功。我尝试过:

  1. 创建数组char arr[128],然后使用strcpystrncpymemcpy的不同变体将c复制到arr中,但是他们没有用,我遇到了段错误。

实际上,这就是我尝试过的全部。我不确定如何将c复制到arr中,以便可以使用strtok。谁能解释?

谢谢

编辑:

好的,这是我的新代码:

void
read_input()
{
    char arr[129];
    int r = read(0, arr, 129);
    printf("%s", arr);

    arr[r] = '\0';

    char* pch;

    pch = strtok(arr, " \n");

    while(pch != NULL)
    {
        printf("%s\n", pch);
        pch = strtok(NULL, " \n");
    }
}

我正在尝试从stdin读取诸如“嗨,我叫约翰”的输入。这是我从printfs获得的输出:

hi my name is john
�����hi
my
name
is
john

为什么第一个令牌看起来像这样?我注意到,如果我不添加arr[r] = '\0',那么“ john”将类似于“ hi”。我需要为第一个字符做些什么,类似于最后一个字符吗?

2 个答案:

答案 0 :(得分:1)

您可以直接这样做:

void read_input()
{
    char arr[128];
    read(0, arr, 128);
    printf("%s", arr);
}

或动态内存分配路径:

char *arr = malloc((sizeof(*arr) * 128) + 1);
if (arr == NULL)
{
    // handle error
}
int r = read(0, arr, 128);
arr[r] = '\0';
printf("%s", arr);

答案 1 :(得分:1)

您的第二个程序不起作用,因为您将NUL终止符放在了对printf的调用之后。您需要之前 printf

char arr[129];              // 128 + 1 for the NUL terminator
int r = read(0, arr, 128);
arr[r] = '\0';
printf("%s\n", arr);        // \n for better readbility of the output

NUL终止符也需要一个字节,因此129也是如此。

带有printf格式说明符的

%s打印NUL终止的字符串。由于您没有将NUL放在printf之前,后者会显示所有字符,直到遇到NUL为止,因此输出如下:

hi my name is john
�����
...

此输出可能会有所不同,具体取决于arr缓冲区的先前内容。

第一个版本是错误的,因为c指针没有初始化,它没有指向任何地方。在这种情况下,程序可能似乎可以正常运行,但这就是所谓的“未定义的行为”,google,请记住,“未定义的行为”包括“显然可以正常工作”。