我对C很陌生,但是在理解指针方面仍然遇到问题。
int main() {
char input[20];
char* ptr;
node* head = NULL;
head = (node*) malloc(sizeof(node));
do {
printf("Eingabe: ");
fgets(input,20,stdin);
if (*input == '0') {
break;
}
ptr = strtok(input," ");
while(ptr!=NULL){
int val = atoi(ptr);
push(head,val);
ptr = strtok(NULL, " ");
}
bubbleSort(head);
printf("Ausgabe: ");
printList(head);
printf("\n");
} while(*input != '0');
free(head);
return 0;
}
在这段代码中,strtok(input," ");
函数strtok
返回第一个令牌的地址还是该令牌的值?
我当时想,如果您想要该值,则必须用星号取消引用它。
我试图用星号打印ptr
,这给了我该令牌的地址而不是值。这甚至让我更加困惑。有人可以向我解释一下吗?
答案 0 :(得分:3)
可以说您的输入看起来像这样:
--------------------
|2|3| |5| |1|2|3|\0|
--------------------
最后的\0
是字符串终止符。之后的所有内容都会被忽略。
第一次调用ptr = strtok(input, " ")
时,strtok
将返回第一个字符(非空格)的位置。它还将用\0
替换第一个空格,并使用内部保存的指针来记住它的距离。
情况将如下所示:
---------------------
|2|3|\0|5| |1|2|3|\0|
---------------------
^ ^
ptr internal pointer
因此ptr
是指向数组内部位置的指针(ptr
的类型为char*
)。
然后调用atoi(ptr)
将字符串23\0
转换为整数23
。之所以有效,是因为strtok
用\0
替换了空格。
然后您致电ptr = strtok(NULL, " ")
。将NULL
作为第一个参数传递,告诉strtok
在寻找下一个标记时,将其内部保存的指针用作起点。结果就是这样(为清楚起见添加了额外的空格):
-------------------------
|2|3|\0|5| \0|1|2|3|\0|
-------------------------
^ ^
ptr internal pointer
所以atoi
看到的是5\0
,即字符串"5"
,它转换为整数5
。然后,再次调用strtok(NULL, " ")
,然后从123
获得结果atoi
。然后,以下strtok
返回NULL
,因为它找不到更多的令牌,因此您从下一行输入重新开始。
答案 1 :(得分:1)
在此声明中
ptr = strtok(input," ");
函数strtok
返回一个指向所输入字符串的第一个元素的指针,该指针不等于balnk字符。也就是说,该函数将返回指向由空白字符分隔的子字符串的第一个字符的指针。
请注意,最好写至少像
ptr = strtok(input,"\n ");
因为功能fgtes可以将换行符附加到输入的字符串中。
请考虑以下演示程序
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char s[] = "123 456 789";
char *p = strtok( s, " " );
while ( p != NULL )
{
int x = atoi( p );
printf( "%d\n", x );
p = strtok( NULL, " " );
}
}
其输出为
123
456
789
在第一次调用strtok之后,该函数按以下方式更改了源字符串,将终止符替换为空白字符
"123 456 789" ===> "123\000456 789"
^^^^
并返回指向提取的子字符串"123"
在第二个调用中,该函数处理字符串"456 789"
。
同样,它通过插入终止零字符来构建子字符串
"456 789" ===> "456\000789"
并返回一个指向子字符串“ 456”的指针。依此类推。