簡體   English   中英

在strtok中使用strcpy()

[英]using strcpy() with strtok

我試圖拆分從文件中讀取的行,並使用strcpy()找到的數據復制到字符數組中,但我知道strcpy()在行的末尾需要一個空終止符,否則它將導致段錯誤,盡管我也嘗試過使用具有相同結果的strncpy()strncat()確定的緩沖區大小。 在我的代碼段中,我嘗試僅在令牌的末尾添加一個空終止符。

這是失敗的代碼片段:

    token = strtok(line, s);
    strcpy(update, token);
    token = strtok(NULL, s);
    token = token + '\0';
    strcpy(firstName, token);
    token = strtok(NULL, s);

此函數中的第一個strcpy()調用尚未失敗。 第二次調用strcpy() ,每次嘗試運行它都會失敗。

我其余的代碼可以在這里找到

您需要在復制之前檢查空指針。

token = strtok(line, s);
strcpy(update, token);
token = strtok(NULL, s);
//token = token + '\0';
if(NULL != token)
{
    strcpy(firstName, token);
    token = strtok(NULL, s);
}

strtok返回空指針或指向以NUL終止的字節序列的指針(即有效的C字符串)。

您的token = token + '\\0'; 沒有(幾乎可以肯定)做您想做的事情。 由於token是指針(這是strtok的返回類型),因此它正在執行指針算術。 幸運的是, '\\0'是一種漫長的說0 (目前的瑣事:C語言中的字符文字類型為int ,而不是char類型),因此至少它沒有改變指針。

檢查strtok返回的值。 如果第二次strcpy失敗,則可能是因為strtok失敗並返回了空指針。

就是說,假設您使用單個固定字符串定義定界符,則可以使用sscanf輕松(且更加簡潔)地完成此工作。 例如,如果s包含,.-+ ,則可以使用:

sscanf(input, "%1[^,.-+]%*c%9[^,.-+]", update, firstname);

我現在strtok忽略了對strtok的第三次調用,因為您永遠不會將它的返回值復制到目的地(但是,重復上面的模式當然可以使用更多的變量)。 請注意在%和掃描集( [^...] )之間使用數字。 使用%s或%[...]時,您總是要指定緩沖區的大小. The size you specify should always be one smaller than the buffer into which you're having them write (because they always append a trailing . The size you specify should always be one smaller than the buffer into which you're having them write (because they always append a trailing '\\ 0'`)。

如果s實際上是您從外部來源讀取的字符串(或按某種順序讀取,因此您不能輕易將其內容放入字符串文字中),可以在運行時根據需要合成格式字符串:

char template[] = "%%[^%s]%%*c%%[^%s]";
char format[512];

sprintf(format, template, s, s);
sscanf(input, format, update, firstname);

[盡管格式字符串通常是文字,但這不是必需的。]

編輯:我不認為您最初鏈接代碼,但是它揭示了至少一個問題: char update[1]; 將其用作strcpy的目標是一個問題,因為它總是在末尾附加一個'\\0'來終止該字符串。 在這種情況下,您只分配了一個字符,因此只為終結符留出空間,沒有任何實際數據。 您需要將其擴展為至少兩個字符。 假設您要復制到固定大小的緩沖區中,則可能要在復制之前檢查字符串是否適合您的緩沖區,或者要使用某種復制方式來限制要復制的數據大小(並且仍然始終包含終止符,不同於strncpy )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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