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