簡體   English   中英

C-printf不顯示完整字符串

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

firstStringsecondString復制時, fullString存儲為"Hello\\0\\0\\0\\0\\0 World\\0\\0\\0\\0\\0\\0" ,但是由於C字符串以空值結尾,所以printf停止在找到的第一個\\0處打印字符串。

其他人為此發布了其他解決方案,但我想補充一點,最簡單的方法可能是使用strcpystrcat

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'時便停止打印。

要解決此問題,您可以更改字符串連接代碼,如下所示:

  1. 將第一個字符串中的字符復制到目標緩沖區中(相應地更新字符串指針)
  2. 寫一個空格 在目標緩沖區中(並相應地更新dest字符串指針)
  3. 將第二個字符串中的字符復制到目標緩沖區中(相應地更新字符串指針)

可以這樣用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.

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