2013-06-21 41 views
1

我發送的格式如下,從一個程序到另一個:number lastname firstname middlei ID GPA使用memcopy的奇怪結果

接收程序看到正確的字符串,並將該字符串存儲到緩衝區中。該字符串被標記並且在switch語句中使用的數字。下面顯示了相應的案例代碼。

tok = strtok(arg, " "); 
printf("the first token is %s\n", tok); 
memcpy(ptr->student.lname, tok, 10); 
tok = strtok(NULL, " "); 
memcpy(ptr->student.fname, tok, 10); 
tok = strtok(NULL, " "); 
ptr->student.initial = *tok; 
tok = strtok(NULL, " "); 
sscanf(tok, "%lu", &ptr->student.SID); 
tok = strtok(NULL, " "); 
sscanf(tok, "%f", &ptr->student.GPA); 
// few more pointer and location initializations... 
printf("lu %s %s %c %f\n", ptr->student.SID, ptr->student.lname, 
    ptr->student.fname, ptr->student.initial, ptr->student.GPA); 

輸入字符串是:5 lastnamereallylong,firstnamereallylong,X,1234,4.0

其中前程序縮短到:5 lastnamere firstnamer X 1234 4.0

第二個程序的輸出如下:

the first tok is lastnamere 
1234 lastnamereXfirstnamer firstnamer X 4.000000 

是否有人可以幫助我這裏發生了什麼?我可以理解不正確使用memcopy,但我不認爲這會改變原始信息的順序。

回答

2

這裏發生了什麼是未定義的行爲:您正在告訴memcpy要複製任何令牌的前10個字符,但是當令牌長度超過10個字符時,表示該字符串不會爲空封端的。傳遞這樣的字符串到printf("%s", ...)是未定義的行爲。

要解決此問題,您應該通過設置ptr->student.lname[9] = '\0'來強制終止,如果您希望保留固定長度的字符串,或者使用strdup來允許可變長度的字符串。

最後,使用strtok有一個線程安全的替代方案 - 您可以使用strtok_r

+0

使用strncpy()而不是memcpy() – John3136

+0

謝謝你們。我把數組的名字加長了一個,所以我可以添加終止字符。 – user1362058