C 字符串初始化中的明显异常:printf 和 strlen 似乎都出错了?
Apparent oddity in C string initialization: printf and strlen both seem to be in error?
总体问题是; C 中关于字符串初始化的一些奇怪之处似乎没有人评论我可以找到对/是否有一些特定的 Googlemancy 术语来研究我偶然发现的一个奇怪之处/是我还是有某种printf 和 strlen 如何处理 C 中的特定字符串的“错误”或“功能”?
我发现虽然 printf 应该打印字符串,但它只打印了字符串的一部分。我发现虽然 strlen 应该报告字符串的长度,但它只报告了它的一部分。
我是否发现了某种错误,或者这是 C 的一个相当非常晦涩的“特性”,在这种情况下,是此类的详细信息和讨论术语一个“功能”?
考虑这段代码,以及随后的输出:
代码:
/* Header files for program support */
#include <stdio.h>
#include <string.h>
/* The primary program section */
int main(void)
{
/* Variable declaration and initialization*/
char aitch[30] = "Cat";
/* What gets done here */
printf("The string aitch is: %s.\n", aitch);
printf("strlen says aitch is %lu characters long.\n", strlen(aitch));
printf("aitch[10] is what is between >> and <<: >>%c<<.\n\n", aitch[10]);
printf("Now dish out a bunch of chopped liver.\n\n");
/* More variable declaration and initialization*/
aitch[11] = ' '; aitch[12] = 'C'; aitch[13] = 'h'; aitch[14] = 'o';
aitch[15] = 'p'; aitch[16] = 'p'; aitch[17] = 'e'; aitch[18] = 'd';
aitch[19] = ' '; aitch[20] = 'l'; aitch[21] = 'i'; aitch[22] = 'v';
aitch[23] = 'e'; aitch[24] = 'r';
/* Looking over the new stuff */
printf("aitch listed by character at this point is:\n\n");
printf("%c", aitch[0]); printf("%c", aitch[1]);
printf("%c", aitch[2]); printf("%c", aitch[3]);
printf("%c", aitch[4]); printf("%c", aitch[5]);
printf("%c", aitch[6]); printf("%c", aitch[7]);
printf("%c", aitch[8]); printf("%c", aitch[9]);
printf("%c", aitch[10]); printf("%c", aitch[11]);
printf("%c", aitch[12]); printf("%c", aitch[13]);
printf("%c", aitch[14]); printf("%c", aitch[15]);
printf("%c", aitch[16]); printf("%c", aitch[17]);
printf("%c", aitch[18]); printf("%c", aitch[19]);
printf("%c", aitch[20]); printf("%c", aitch[21]);
printf("%c", aitch[22]); printf("%c", aitch[23]);
printf("%c", aitch[24]); printf("\n\n");
/* Hang on, what was that last bit? */
printf("printf still says all of aitch is %s.\n", aitch);
printf("strlen still says all of aitch is %lu characters long.\n",
strlen(aitch));
printf("aitch[10] is still what is between >> and <<: >>%c<<.\n\n", aitch[10]);
printf("Now put something in the empty area.\n\n");
/* More variable declaration and initialization*/
aitch[3] = '_'; aitch[4] = '_'; aitch[5] = '_'; aitch[6] = '_';
aitch[7] = '_'; aitch[8] = '_'; aitch[9] = '_'; aitch[10] = '_';
/* Ok, _Now_ what??? */
printf("printf now says all of aitch is:\n\n%s.\n\n", aitch);
printf("strlen says all of aitch _now_ is %lu characters long.\n",
strlen(aitch));
printf("aitch[10] is now what is between >> and <<: >>%c<<.\n\n", aitch[10]);
}
输出:
% ./a.out
The string aitch is: Cat.
strlen says aitch is 3 characters long.
aitch[10] is what is between >> and <<: >><<.
Now dish out a bunch of chopped liver.
aitch listed by character at this point is:
Cat Chopped liver
printf still says all of aitch is Cat.
strlen still says all of aitch is 3 characters long.
aitch[10] is still what is between >> and <<: >><<.
Now put something in the empty area.
printf now says all of aitch is:
Cat________ Chopped liver.
strlen says all of aitch _now_ is 25 characters long.
aitch[10] is now what is between >> and <<: >>_<<.
char aitch[30] = "Cat";
在这里,aitch
中的前4个char
依次为:C
、a
、t
和[=16 =]
,其中 [=16=]
是空终止符。 C 中的字符串以 null 结尾。 printf
和 strlen
等函数期望以 NULL 结尾的字符串,并且一旦遇到空终止符就会停止处理该字符串。
当您直接写入 aitch[3]
时,您会覆盖空终止符。
在C语言中,一个字符串是:一系列字符,以空字符(0字节)结尾。
char aitch[30] = "Cat";
这声明了一个包含 30 个字符的数组。第一个是'C',第二个是'a',第三个是't',第四个是null(结束字符串),其余都是null(默认)。 (注意:char aitch[30];
本身不会使它们全部为空)
所以你有 space 30 个字符。如果您从第一个字符开始使用 space,则该 space 中存储了一个有效的字符串:'C'、'a'、't'、0。那是一个长度为 3 个字符的字符串。如果您调用 strlen
它将 return 3 因为那是字符串的长度。如果你打印它,它会打印 3 个字符,因为这就是字符串的长度。
请注意,30 个字符的 space 与 30 个字符的字符串不同。 space就是space,字符串就是你实际存储在那里的数据。您有 26 个不属于字符串的字符,您可以根据需要使用它们。
事实上,你有足够的space来存储两个不同的字符串!这正是您在代码中所做的。
如果你确定它们之间没有空字节,它们就会再次成为一个字符串。
请注意,字符串的任何“结尾部分”也是有效的字符串。如果您从数组中的位置 0 开始,您将得到字符串“Cat”。但是如果你从位置 1 开始,你得到“at”,如果你从位置 2 开始,你得到“t”,如果你从位置 3 开始,你得到“”。一切都很好用。
我们这里遇到的是沟通失败---大家的评论和回答都很好,非常感谢回答评论。
问题,可能在其他地方也已经看到,是对 C 的超现实可怕的评论,在那里,在那之外,等等,无法告诉任何东西的质量,无论在哪里找到它,都不需要经过各种各样的梳理,并通过编写演示代码来测试一切。
在这种情况下,一个非常特殊的例子是相当多的书评、在线评论等等,它们声明 char aitch[30] 本质上是一个 30 个字符长的字符串的创建,然后一个初始化这里和那里 。 . . 据此,无论是一组字符还是分开的两个或多个字符都无关紧要,都是一个字符串。
基于“C”中“string”的定义,是的,printf 尤其是 strlen 的行为不正确。
就我而言,我确实正在对 C 进行自我驱动研究和深入挖掘,并且不得不费力地浏览许多此类非常垃圾文档的实例。因此,出于自我防卫,我边走边写自己的笔记,使用绝对有效的示例代码块来支持所有内容。
---关于循环可以放入示例代码的评论,基本上是的,但迂腐地,还没有---我正在做的笔记目前正在首先从函数开始后梳理变量, 循环将持续一两章。
在我继续学习的过程中,这个实例不会是我要 运行 进入的最后一个评论混乱。---不,我不知道下一个混乱会是什么,我只知道会有一个,然后是下一个,然后是下一个。 . . .
总体问题是; C 中关于字符串初始化的一些奇怪之处似乎没有人评论我可以找到对/是否有一些特定的 Googlemancy 术语来研究我偶然发现的一个奇怪之处/是我还是有某种printf 和 strlen 如何处理 C 中的特定字符串的“错误”或“功能”?
我发现虽然 printf 应该打印字符串,但它只打印了字符串的一部分。我发现虽然 strlen 应该报告字符串的长度,但它只报告了它的一部分。
我是否发现了某种错误,或者这是 C 的一个相当非常晦涩的“特性”,在这种情况下,是此类的详细信息和讨论术语一个“功能”?
考虑这段代码,以及随后的输出:
代码:
/* Header files for program support */
#include <stdio.h>
#include <string.h>
/* The primary program section */
int main(void)
{
/* Variable declaration and initialization*/
char aitch[30] = "Cat";
/* What gets done here */
printf("The string aitch is: %s.\n", aitch);
printf("strlen says aitch is %lu characters long.\n", strlen(aitch));
printf("aitch[10] is what is between >> and <<: >>%c<<.\n\n", aitch[10]);
printf("Now dish out a bunch of chopped liver.\n\n");
/* More variable declaration and initialization*/
aitch[11] = ' '; aitch[12] = 'C'; aitch[13] = 'h'; aitch[14] = 'o';
aitch[15] = 'p'; aitch[16] = 'p'; aitch[17] = 'e'; aitch[18] = 'd';
aitch[19] = ' '; aitch[20] = 'l'; aitch[21] = 'i'; aitch[22] = 'v';
aitch[23] = 'e'; aitch[24] = 'r';
/* Looking over the new stuff */
printf("aitch listed by character at this point is:\n\n");
printf("%c", aitch[0]); printf("%c", aitch[1]);
printf("%c", aitch[2]); printf("%c", aitch[3]);
printf("%c", aitch[4]); printf("%c", aitch[5]);
printf("%c", aitch[6]); printf("%c", aitch[7]);
printf("%c", aitch[8]); printf("%c", aitch[9]);
printf("%c", aitch[10]); printf("%c", aitch[11]);
printf("%c", aitch[12]); printf("%c", aitch[13]);
printf("%c", aitch[14]); printf("%c", aitch[15]);
printf("%c", aitch[16]); printf("%c", aitch[17]);
printf("%c", aitch[18]); printf("%c", aitch[19]);
printf("%c", aitch[20]); printf("%c", aitch[21]);
printf("%c", aitch[22]); printf("%c", aitch[23]);
printf("%c", aitch[24]); printf("\n\n");
/* Hang on, what was that last bit? */
printf("printf still says all of aitch is %s.\n", aitch);
printf("strlen still says all of aitch is %lu characters long.\n",
strlen(aitch));
printf("aitch[10] is still what is between >> and <<: >>%c<<.\n\n", aitch[10]);
printf("Now put something in the empty area.\n\n");
/* More variable declaration and initialization*/
aitch[3] = '_'; aitch[4] = '_'; aitch[5] = '_'; aitch[6] = '_';
aitch[7] = '_'; aitch[8] = '_'; aitch[9] = '_'; aitch[10] = '_';
/* Ok, _Now_ what??? */
printf("printf now says all of aitch is:\n\n%s.\n\n", aitch);
printf("strlen says all of aitch _now_ is %lu characters long.\n",
strlen(aitch));
printf("aitch[10] is now what is between >> and <<: >>%c<<.\n\n", aitch[10]);
}
输出:
% ./a.out
The string aitch is: Cat.
strlen says aitch is 3 characters long.
aitch[10] is what is between >> and <<: >><<.
Now dish out a bunch of chopped liver.
aitch listed by character at this point is:
Cat Chopped liver
printf still says all of aitch is Cat.
strlen still says all of aitch is 3 characters long.
aitch[10] is still what is between >> and <<: >><<.
Now put something in the empty area.
printf now says all of aitch is:
Cat________ Chopped liver.
strlen says all of aitch _now_ is 25 characters long.
aitch[10] is now what is between >> and <<: >>_<<.
char aitch[30] = "Cat";
在这里,aitch
中的前4个char
依次为:C
、a
、t
和[=16 =]
,其中 [=16=]
是空终止符。 C 中的字符串以 null 结尾。 printf
和 strlen
等函数期望以 NULL 结尾的字符串,并且一旦遇到空终止符就会停止处理该字符串。
当您直接写入 aitch[3]
时,您会覆盖空终止符。
在C语言中,一个字符串是:一系列字符,以空字符(0字节)结尾。
char aitch[30] = "Cat";
这声明了一个包含 30 个字符的数组。第一个是'C',第二个是'a',第三个是't',第四个是null(结束字符串),其余都是null(默认)。 (注意:char aitch[30];
本身不会使它们全部为空)
所以你有 space 30 个字符。如果您从第一个字符开始使用 space,则该 space 中存储了一个有效的字符串:'C'、'a'、't'、0。那是一个长度为 3 个字符的字符串。如果您调用 strlen
它将 return 3 因为那是字符串的长度。如果你打印它,它会打印 3 个字符,因为这就是字符串的长度。
请注意,30 个字符的 space 与 30 个字符的字符串不同。 space就是space,字符串就是你实际存储在那里的数据。您有 26 个不属于字符串的字符,您可以根据需要使用它们。
事实上,你有足够的space来存储两个不同的字符串!这正是您在代码中所做的。
如果你确定它们之间没有空字节,它们就会再次成为一个字符串。
请注意,字符串的任何“结尾部分”也是有效的字符串。如果您从数组中的位置 0 开始,您将得到字符串“Cat”。但是如果你从位置 1 开始,你得到“at”,如果你从位置 2 开始,你得到“t”,如果你从位置 3 开始,你得到“”。一切都很好用。
我们这里遇到的是沟通失败---大家的评论和回答都很好,非常感谢回答评论。
问题,可能在其他地方也已经看到,是对 C 的超现实可怕的评论,在那里,在那之外,等等,无法告诉任何东西的质量,无论在哪里找到它,都不需要经过各种各样的梳理,并通过编写演示代码来测试一切。
在这种情况下,一个非常特殊的例子是相当多的书评、在线评论等等,它们声明 char aitch[30] 本质上是一个 30 个字符长的字符串的创建,然后一个初始化这里和那里 。 . . 据此,无论是一组字符还是分开的两个或多个字符都无关紧要,都是一个字符串。
基于“C”中“string”的定义,是的,printf 尤其是 strlen 的行为不正确。
就我而言,我确实正在对 C 进行自我驱动研究和深入挖掘,并且不得不费力地浏览许多此类非常垃圾文档的实例。因此,出于自我防卫,我边走边写自己的笔记,使用绝对有效的示例代码块来支持所有内容。
---关于循环可以放入示例代码的评论,基本上是的,但迂腐地,还没有---我正在做的笔记目前正在首先从函数开始后梳理变量, 循环将持续一两章。
在我继续学习的过程中,这个实例不会是我要 运行 进入的最后一个评论混乱。---不,我不知道下一个混乱会是什么,我只知道会有一个,然后是下一个,然后是下一个。 . . .