在C中使用系统调用时遇到了一些麻烦。我试图使用read
从stdin
中读取一些输入,然后使用strtok将值加载到数组中,但是我可以似乎做对了(我一直在做段错误)。
这是我开始的代码:
void read_input()
{
char* c;
read(0, c, 128);
printf("%s", c);
}
所以,这工作正常,我可以打印输出。但是,我接下来尝试了几件事,但没有成功。我尝试过:
char arr[128]
,然后使用strcpy
,strncpy
和memcpy
的不同变体将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”。我需要为第一个字符做些什么,类似于最后一个字符吗?
答案 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,请记住,“未定义的行为”包括“显然可以正常工作”。