簡體   English   中英

strcat 如何影響 strtok?

[英]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

我很難理解strtokstrcat未能 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)上調用未定義的行為。 請改用forwhile循環。
  • 代碼中缺少} ,尚不清楚您是要在第一次迭代后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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM