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);
当您从 firstString
和 secondString
复制时,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=]'
。
要解决此问题,您可以更改字符串连接代码,如下所示:
- 将第一个字符串中的字符复制到目标缓冲区(相应地更新字符串指针)
- 在目标缓冲区中写入 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()
.
我正在尝试使用指针而不是 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);
当您从 firstString
和 secondString
复制时,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=]'
。
要解决此问题,您可以更改字符串连接代码,如下所示:
- 将第一个字符串中的字符复制到目标缓冲区(相应地更新字符串指针)
- 在目标缓冲区中写入 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()
.