[英]Function strtok() does not work with strcat() (illegal hardware instruction)
[英]How does strcat affect the strtok?
假設我們需要通過連接輸入的標記將用戶的輸入復制到另一個字符串中,例如"hello world" -> "helloworld"
。
#include <stdio.h>
#include <string.h>
int main(void) {
char buffer[50];
printf("\nEnter a string: ");
while (fgets(buffer, sizeof(buffer), stdin) != 0) {
size_t size = strlen(buffer);
if (size > 0 && buffer[size - 1] == '\n') {
char input[1]; // set it too small
buffer[size - 1] = '\0';
char *tok = strtok(buffer, " "); // works fine
do {
strcat(input, tok); // append to "input" that has not enough space
printf("\nfound token: %s", tok);
tok = strtok(NULL, " "); // produces garbage
} while (tok);
break;
}
}
運行上面的代碼:
Enter a string: hello world
found token: hello
found token: w
found token: r
*** stack smashing detected ***: <unknown> terminated
我很難理解strtok
與strcat
未能 append tok
有何關系。 除了由strcat
復制的tok
之外,它們不共享變量(根據文檔),因此strcat
所做的任何事情都不應影響strtok
行為,並且程序至少應該在第二次strcat
調用時崩潰,對嗎? 但是我們看到strcat
在堆棧粉碎被檢測到之前被調用了 3 次。 你能解釋一下為什么嗎?
對於初學者這個數組
char input[1];
未初始化且不包含字符串。
所以這個 strcat 調用
strcat(input, tok);
調用未定義的行為也是因為數組輸入不足以存儲復制的字符串。 它可以覆蓋陣列之外的 memory。
代碼中存在多個問題:
char input[1];
太小了,什么都做不了。 您不能將行中的標記連接到這個小數組中。 您必須以足夠的長度定義它,即為簡單起見與buffer
的長度相同。strcat(input, tok);
input
必須初始化為空字符串; 有明確的行為。 按照編碼,對strcat
的第一次調用會破壞導致觀察到的行為的其他變量,但請注意,由於這種未定義的行為,可能會發生任何其他事情。char *tok = strtok(buffer, " ");
工作正常,但如果buffer
僅包含空格(如果有的話),可能會返回 null 指針。 然后do
循環將在strcat(input, tok)
上調用未定義的行為。 請改用for
或while
循環。}
,尚不清楚您是要在第一次迭代后break
while
循環還是僅在行尾時中斷。這是修改后的版本:
#include <stdio.h>
#include <string.h>
int main(void) {
char buffer[50];
char input[sizeof buffer] = "";
printf("Enter a string: ");
if (fgets(buffer, sizeof(buffer), stdin)) {
char *tok = strtok(buffer, " \n");
while (tok) {
strcat(input, tok);
printf("found token: %s\n", tok);
tok = strtok(NULL, " \n");
}
printf("token string: %s\n", input);
}
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.