C - printf 不显示完整的字符串

C - printf doesn't display full string

我正在尝试使用指针而不是 strcat 来连接两个由 space 分隔的字符串。我已经让连接工作了,但是当我尝试打印连接的字符串时,它只打印第一个字符串。

代码:

#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 中,字符串被定义为以 '[=13=]' 字节结尾的字节序列,因此 "A[=14=]" 表示字符串 A"A[=16=]ABCDEF" 也表示string "A", scanf 将此 '[=13=]' 特殊值附加到数组中,该特殊值将字符串定界,因此复制每个字符时您也复制了该字节。

不仅如此,如果你在第一个scanf输入例如ABC,那么数组的内容就是

[A|B|C|[=10=]|?|?|?|?|?|?]
 0 1 2  3 4 5 6 7 8 9

其中 ? 表示 UNINITIALIZED 它们是来自这些位置的内存先前内容的随机垃圾值,因此尝试读取这些值是未定义的行为。

您正在将 '[=13=]' 从第一个字符串复制到结果字符串的中间,我建议 2 个循环

int j = 0;

for (i = 0 ; string1Ptr[i] != '[=11=]' ; ++i)
    fullStringPtr[j++] = string1Ptr[i];

fullStringPtr[j++] = ' ';

for (i = 0 ; string2Ptr[i] != '[=11=]' ; ++i)
    fullStringPtr[j++] = string2Ptr[i];
fullStringPtr[j++] = '[=11=]';

printf 打印在找到 '[=13=]' 之前遇到的每个字符,并且由于您将该值从第一个字符串复制到第二个字符串中,所以它应该只打印第一个字符串,之后的字符'[=13=]' 被省略了。

如果可以包含 string.h header

,则只需使用 strcat
fullStringPtr[0] = '[=12=]';

strcat(fullStringPtr, string1Ptr);
strcat(fullStringPtr, " ");
strcat(fullStringPtr, string2Ptr);

当您从 firstStringsecondString 复制时,fullString 存储为 "Hello[=14=][=14=][=14=][=14=][=14=] World[=14=][=14=][=14=][=14=][=14=][=14=]",但由于 C 字符串以 null 结尾,printf 停止在它找到的第一个 [=16=] 打印字符串。

其他人已经发布了其他解决方案,但我想补充一点,最简单的可能是使用 strcpy and 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 目标缓冲区中嵌入了一些 '[=12=]',并且由于 C 字符串以 '[=12=]' 结尾,因此 printf() 在找到时停止打印目标缓冲区中的第一个 '[=12=]'

要解决此问题,您可以更改字符串连接代码,如下所示:

  1. 将第一个字符串中的字符复制到目标缓冲区(相应地更新字符串指针)
  2. 在目标缓冲区中写入 space </code>(并相应地更新目标字符串指针)</li> <li>将第二个字符串中的字符复制到目标缓冲区(相应地更新字符串指针)</li> </ol> <p>这可以用 C 代码写成这样:</p> <pre><code>#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 != '[=10=]') { *fullStringPtr = *string1Ptr; ++fullStringPtr; ++string1Ptr; } /* Add space */ *fullStringPtr = ' '; ++fullStringPtr; /* Concat string2 to dest buffer */ while (*string2Ptr != '[=10=]') { *fullStringPtr = *string2Ptr; ++fullStringPtr; ++string2Ptr; } /* Terminate full string */ *fullStringPtr = '[=10=]'; /* 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().