C - printf不显示完整字符串

时间:2015-01-11 20:11:18

标签: c string pointers printf

我试图通过使用指针而不是strcat来连接两个字符串,用空格分隔。我已经使串联工作,但当我尝试打印连接字符串时,它只打印第一个字符串。

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);

    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的东西我不见了吗?

3 个答案:

答案 0 :(得分:4)

在c字符串中定义为带有终止'\0'字节的字节序列,因此"A\0"表示字符串A"A\0ABCDEF"也表示字符串{ {1}},"A"将此scanf特殊值附加到数组中,因此复制每个字符也会复制此字节。

不仅如此,如果您在第一个'\0'输入例如ABC,那么数组的内容将是

scanf

其中[A|B|C|\0|?|?|?|?|?|?] 0 1 2 3 4 5 6 7 8 9 表示?它们是来自这些点的内存的先前内容的随机垃圾值,因此尝试读取这些值是未定义的行为。

您正在将UNINITIALIZED从第一个字符串复制到结果字符串的中间,我建议使用2个循环

'\0'

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'之后的字符{1}}被忽略。

如果您可以添加'\0'标题

,只需使用strcat即可
string.h

答案 1 :(得分:3)

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

答案 2 :(得分:1)

问题在于字符串连接代码。

您恰好在'\0'目标缓冲区中嵌入了一些fullString,并且由于C字符串为'\0' - 终止,printf()在找到第一个时停止打印目标缓冲区中的'\0'

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

  1. 将第一个字符串中的字符复制到目标缓冲区(相应地更新字符串指针)
  2. 在目标缓冲区中写入空格(并相应地更新dest字符串指针)
  3. 将第二个字符串中的字符复制到目标缓冲区(相应地更新字符串指针)
  4. 这可以用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(),或者更好的更安全版本,如{{1 }和strcpy_s()