[英]C - printf doesn't display full string
我試圖通過使用指針而不是strcat來連接兩個用空格隔開的字符串。 我已經可以使用串聯了,但是當我嘗試打印串聯的字符串時,它只會打印第一個字符串。
碼:
#include <stdio.h>
int main(void){
char string1[10];
char string2[10];
char fullString[21];
char *string1Ptr = string1;
char *string2Ptr = string2;
char *fullStringPtr = fullString;
printf("Enter first string: ");
scanf_s("%s", &string1, 10);
fflush(stdin);
printf("Enter second string: ");
scanf_s("%s", &string2, 10);
fflush(stdin);
for (int i = 0; i < 21; ++i){
if (i < 10){
fullStringPtr[i] = string1Ptr[i];
}
else if (i == 10){
fullStringPtr[i] = ' ';
}
else if (i > 10){
fullStringPtr[i] = string2Ptr[i - 11];
}
}
printf("%s\n", fullString);
//printf("%c", fullString[11]);
getchar();
return (0);
}
如果我輸入Hello作為第一個字符串,輸入World作為第二個字符串,則打印輸出將顯示為“ Hello”。 但是,如果我嘗試在第二個字符串的特定位置打印字符,例如fullString [11],則會得到應該在該位置的字符,在這種情況下為W。
第二個字符串顯然在那里,printf只是不打印它。 我缺少關於printf的東西嗎?
在c中,字符串被定義為帶有終止'\\0'
字節的字節序列,因此"A\\0"
將代表字符串A
而"A\\0ABCDEF"
也將代表字符串"A"
, scanf
附加此'\\0'
特殊值,該值將字符串定界到數組,因此復制每個字符也將復制此字節。
不僅如此,如果在第一個scanf
輸入例如ABC
,則數組的內容將是
[A|B|C|\0|?|?|?|?|?|?]
0 1 2 3 4 5 6 7 8 9
在?
意味着UNINITIALIZED
它們是那些位置上的內存先前內容中的隨機垃圾值,因此嘗試讀取這些值是未定義的行為。
您正在將第一個字符串中的'\\0'
復制到結果字符串的中間,我建議執行2個循環
int j = 0;
for (i = 0 ; string1Ptr[i] != '\0' ; ++i)
fullStringPtr[j++] = string1Ptr[i];
fullStringPtr[j++] = ' ';
for (i = 0 ; string2Ptr[i] != '\0' ; ++i)
fullStringPtr[j++] = string2Ptr[i];
fullStringPtr[j++] = '\0';
printf
打印找到'\\0'
之前遇到的每個字符,並且由於您將該值從第一個字符串復制到了第二個字符串中,因此它應該僅打印第一個字符串,因此省略了'\\0'
之后的字符。
或者如果可以包含string.h
標頭,則只需使用strcat
fullStringPtr[0] = '\0';
strcat(fullStringPtr, string1Ptr);
strcat(fullStringPtr, " ");
strcat(fullStringPtr, string2Ptr);
從firstString
和secondString
復制時, fullString
存儲為"Hello\\0\\0\\0\\0\\0 World\\0\\0\\0\\0\\0\\0"
,但是由於C字符串以空值結尾,所以printf
停止在找到的第一個\\0
處打印字符串。
其他人為此發布了其他解決方案,但我想補充一點,最簡單的方法可能是使用strcpy
和strcat
:
strcpy(fullStringPtr, string1Ptr); // copy to fullString
strcat(fullStringPtr, " "); // add to end of fullString
strcat(fullStringPtr, string2Ptr); // add to end of fullString
printf("%s\n", fullString); // works as expected
問題出在字符串連接代碼中。
您恰好在fullString
目標緩沖區中嵌入了一些'\\0'
,並且由於C字符串以'\\0'
終止,所以printf()
在目標緩沖區中找到第一個'\\0'
時便停止打印。
要解決此問題,您可以更改字符串連接代碼,如下所示:
在目標緩沖區中(並相應地更新dest字符串指針) 可以這樣用C代碼編寫:
#include <stdio.h>
int main(void)
{
char string1[10];
char string2[10];
char fullString[21];
char *string1Ptr = string1;
char *string2Ptr = string2;
char *fullStringPtr = fullString;
printf("Enter first string: ");
scanf_s("%s", string1, 10);
fflush(stdin);
printf("Enter second string: ");
scanf_s("%s", string2, 10);
fflush(stdin);
/* Reality-check: print read strings */
printf("First string: %s\n", string1);
printf("Second string: %s\n", string2);
/* Copy string1 to dest buffer */
while (*string1Ptr != '\0')
{
*fullStringPtr = *string1Ptr;
++fullStringPtr;
++string1Ptr;
}
/* Add space */
*fullStringPtr = ' ';
++fullStringPtr;
/* Concat string2 to dest buffer */
while (*string2Ptr != '\0')
{
*fullStringPtr = *string2Ptr;
++fullStringPtr;
++string2Ptr;
}
/* Terminate full string */
*fullStringPtr = '\0';
/* Print result */
printf("%s\n", fullString);
return 0;
}
輸出:
Enter first string: Hello Enter second string: World First string: Hello Second string: World Hello World
注意
除非您將此代碼編寫為了解指針等的學習經驗,否則請考慮使用內置的字符串復制和串聯函數(例如strcpy()
/ strcat()
,或者使用更好的安全版本,例如strcpy_s()
和strcat_s()
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.