我不擅长使用C语言。这是我愚蠢的问题。现在我试图从用户那里获得输入,这些用户可能有空格。我需要做的是使用空格作为分隔符来拆分这句话,然后将每个片段放入char *数组。
例如:
假设我有char* result[10];
,输入为:Good morning John
。输出应该是result[0]="Good";
result[1]="morning";
result[2]="John";
我已经尝试scanf("%[^\n]",input);
和gets(input);
但是仍然很难处理C中的String。我也试过了strtok
,但它似乎只用NULL
替换了空格。因此结果将是GoodNULLmorningNULLJohn
。显然这不是我想要的。请帮助我愚蠢的问题。谢谢。
修改
这是使用strtok
时我不明白的地方。这是一个测试代码。
substr
仍然显示Hello there
。似乎subtok
仅替换空格位置的null
。因此,我无法在substr
声明中使用if
。
int main()
{
int i=0;
char* substr;
char str[] = "Hello there";
substr = strtok(str," ");
if(substr=="Hello"){
printf("YES!!!!!!!!!!");
}
printf("%s\n",substr);
for(i=0;i<11;i++){
printf("%c", substr[i]);
}
printf("\n");
system("pause");
return 0;
}
答案 0 :(得分:3)
从不使用gets
,在C99中已弃用并从C11中删除。
IMO scanf
不是一个很好的功能,当你不知道前面的元素数量时,我建议fgets
:
#include <stdio.h>
#include <string.h>
int main(void)
{
char str[128];
char *ptr;
fgets(str, sizeof str, stdin);
/* Remove trailing newline */
ptr = strchr(str, '\n');
if (ptr != NULL) {
*ptr = '\0';
}
/* Tokens */
ptr = strtok(str, " ");
while (ptr != NULL) {
printf("%s\n", ptr);
ptr = strtok(NULL, " ");
}
return 0;
}
答案 1 :(得分:1)
gets
,因为无法判断缓冲区的大小。 fgets
在这里没问题,因为遇到第一个新行时它会停止读取。您可以使用strtok将所有已拆分的单词存储到字符串数组中,例如:
#include <stdio.h>
#include <string.h>
int main(void) {
char s[256];
char *result[10];
fgets(s, sizeof(s), stdin);
char *p = strtok(s, " \n");
int cnt = 0;
while (cnt < (sizeof result / sizeof result[0]) && p) {
result[cnt++] = p;
p = strtok(NULL, " \n");
}
for (int i = 0; i < cnt; i++)
printf("%s\n", result[i]);
return 0;
}
答案 2 :(得分:0)
由于大多数其他答案都没有涉及你要问的另一件事:
strtok
将不会分配临时内存,并将使用您的给定字符串替换零终止的每个分隔符。这就是Good morning John
成为GoodNULLmorningNULLJohn
的原因。如果它不这样做,每个令牌将在其尾部打印整个字符串的其余部分,如:
result[0] = Good morning John
result[1] = morning John
result[2] = John
因此,如果您想保留原始输入和每个单词的char *数组,则需要2个缓冲区。除此之外别无他法。只要使用char *指针的结果数组,您还需要令牌缓冲区保留在作用域中,否则会指向无效的内存并导致未定义的行为。
所以这可能是一个解决方案:
int main()
{
const unsigned int resultLength = 10;
char* result[resultLength];
memset(result, 0, sizeof result); // we should also zero the result array to avoid access violations later on
// Read the input from the console
char input[256];
fgets(input, sizeof input, stdin);
// Get rid of the newline char
input[strlen(input) - 1] = 0;
// Copy the input string to another buffer for your tokens to work as expected
char tokenBuffer[256];
strcpy(tokenBuffer, input);
// Setting of the pointers per word
char* token = strtok(tokenBuffer, " ");
for (unsigned int i = 0; token != NULL && i < resultLength; i++)
{
result[i] = token;
token = strtok(NULL, " ");
}
// Print the result
for (unsigned int i = 0; i < resultLength; i++)
{
printf("result[%d] = %s\n", i, result[i] != NULL ? result[i] : "NULL");
}
printf("The input is: %s\n", input);
return 0;
}
打印:
result[0] = Good
result[1] = morning
result[2] = John
result[3] = NULL
result[4] = NULL
result[5] = NULL
result[6] = NULL
result[7] = NULL
result[8] = NULL
result[9] = NULL
The input is: Good morning John