char a[10] 到底能放几个元素?

jxbicestare 2003-09-05 10:49:35
#include <stdio.h>
#include <string.h>
main(){
struct abc{
char a[10];
char b[5];
char c[2];
};
struct abc test;
strcpy(test.a,"0123456789");
strcpy(test.b,"01234");
strcpy(test.c,"01");
printf("a:%s\nb:%s\nc:%s\n",test.a,test.b,test.c);
}
我糊涂了,a[10]数组的结束标志到底放在哪儿?
...全文
5130 31 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
31 条回复
切换为时间正序
请发表友善的回复…
发表回复
jxbicestare 2003-09-06
  • 打赏
  • 举报
回复
多谢各位的教导!
jiangxingcq 2003-09-06
  • 打赏
  • 举报
回复
同意楼上的看法
加上a[10]='\0'是必要的
mastkwdge 2003-09-06
  • 打赏
  • 举报
回复
个人认为
 kmlin(大象头上一颗葱) + ianzy(洞中人)
可以完整说明这个问题。
char a[10]有可存10个字符,但“0123456789”是11个字符,

struct abc{
char a[10];
char b[5];
char c[2];
};
a,b,c三个连续分配空间,
char* strcpy(char* dest, const char* src)正如其原型体现的一样,拷贝时是不管dest,srcr的长度的。所以
  strcpy(test.a,"0123456789")后 test.a[0]='0'---,test.a[9]='9',test.b[0]='\0'
赋了11个字符,覆盖了test.b[0]
strcpy(test.b,"01234")后, test.b[0]重新赋值由'\0'变为'0',,,,test.b[4]='4',而
test.c[0]='\0'
strcpy(test.c,"01")后, test.c[0]变为'0',test.c[1]='1',而下一个没有定义的空间
为'\0'
所以最后,a[10],b[5],c[2]这17个位置没有一个是串结束符'\0','\0'紧接着的下边一个位置。
而printf("%s",a),是从a这个位置向后遍历一直至碰到'\0',所以输出01234567890123401
同理printf("%s",b)是0123401. printf("%s",test.c)是012.
事实上,若char x[2]={'0','1'}; strcpy(test.c,x);printf("%s",test.c);就很有可能会出现更多一些乱码。01%#¥%^(& 因紧接c数组后没有上面的那个越界的‘\0'结束符。
因此,这种用这种定长结构存储时,一定要注意'\0'的问题。
1。要么像楼上所说,声明时预留位置, char a[11],.....
但, strcpy(a,"23432444444444444"); /*输入代码,也可为文件、stdin流*/
后,加上a[10]='\0'是必要的,虽然有时是浪费。但个人认为这不是一种好方法,因界  已越,二次重写时仍会破坏,b的数据
2。要么就是ianzy(洞中人)的方法,仍用char a[10],...
但用strncpy代替strcpy,截断式的拷贝。安全多了。不过由于可能没有结束符,输出时
得用域  char a[10];
strncpy(a,"1241241234141",10);
pritnf("%-10s",a); 这里个人习惯,用-10左对齐
    事实上,mp3的ID3v1的标签头就是这种方法,结构排在mp3文件尾后100个字符,大家可以去分析一下。其实,这种定长本身就有一个无法克服的缺陷,即输入长了不行,截去了。所以,喜欢听歌的朋友可能会知道,mp3的ID3v2的标签就是动态变长存储的。
   不好意思,一个问题,让我给搞复杂了。不过最近的冲击波病毒,据说就是歧形数据包引起的,我想多注意一下总是好的。 错误之处,请大家指正。

          

  

   
noscar 2003-09-06
  • 打赏
  • 举报
回复
我同意cxjddd的看法,关键是你怎么用它!是用做字符,还是字符串!
无聊客 2003-09-05
  • 打赏
  • 举报
回复
多分配一个是必须的,没有结束符系统怎么知道一个字符串什么时候结束?
jxbicestare 2003-09-05
  • 打赏
  • 举报
回复
谢谢大家,看来要使用字符串输入输出只能多分配一个内存单元了。
jxbicestare 2003-09-05
  • 打赏
  • 举报
回复
谁有好的解决方法吗?
tings 2003-09-05
  • 打赏
  • 举报
回复
char a[10]还是可以存放10个有效数据的,不信你可以用for 把数组的数据都输出一下,只不过你说明了数组,可以strcpy,包括 %s都是按照字符串来处理的,strcpy的时候,它把0123456789给了char a[10],然后把b[0]给了一个'\0'依次类推,所以这个结束符号都被覆盖了,用%s输出只有最后一个c[1]之后有'\0'结束符号了,但是你的整个输出不太好,因为c[1]之后的'\0'不在你分配的内存中,将来可能被覆盖掉,这样用%s输出就有错误了,建议用数组的操作,就不会有问题了
tings 2003-09-05
  • 打赏
  • 举报
回复
char a[10] 还是存10个有效字符,只不过你是用%s的方式输出,是按字符串的方式输出的,本身这char a[11];char b[6];char c[3];是在内存中在一起的,没有看到结束符就不会停止输出的
tings 2003-09-05
  • 打赏
  • 举报
回复
哦,我明白了 printf("a:%s\nb:%s\nc:%s\n",test.a,test.b,test.c);
你的输出是按照string类型输出的,它就会找结束符,
虽然本身char数组没有结束符

char a[11];
char b[6];
char c[3];
你这样改,就可以输出正确的结果了
jxbicestare 2003-09-05
  • 打赏
  • 举报
回复
那就是说 char a[10] 只能存放9个有效字符?
samsun2000 2003-09-05
  • 打赏
  • 举报
回复
首先 声明test时系统分给你的是一整块内存,你用strcpy把a[10]都填了内容,紧跟着后面就是b[]和c[]的内容。所以调用printf()时,a[10]书组根本没有结束标志。结果就把所有东东都打出来了。
myyan 2003-09-05
  • 打赏
  • 举报
回复
strcpy是把字符串拷贝到数组里面
myyan 2003-09-05
  • 打赏
  • 举报
回复
字符数组是一个数组,里面可以全部放上字符,不需要有\0。
kmlin 2003-09-05
  • 打赏
  • 举报
回复
strcpy,%s那个不是字符串的操作?
在表达式里,编译器向来是把字符数租用指针代替的阿
在c中,你认为什么是字符串?
akun 2003-09-05
  • 打赏
  • 举报
回复 1
字符数组里面要至少留一个给'\0'阿,不能全部写满啊...
hermitma 2003-09-05
  • 打赏
  • 举报
回复
char a[10]能放9个元素,你输入完后在你的字符结尾处自动加上'\0'。
程序改为:
#include <stdio.h>
#include <string.h>
main(){
struct abc{
char a[11];
char b[6];
char c[3];
};
struct abc test;
strcpy(test.a,"0123456789");
strcpy(test.b,"01234");
strcpy(test.c,"01");
printf("a:%s\nb:%s\nc:%s\n",test.a,test.b,test.c);
}

就对了

tings 2003-09-05
  • 打赏
  • 举报
回复
不太明白你的意思,a[10]的结束标志?数组不就是正常的输出吗,没有什么结束标志啊,又不是字符串,我没有走这个程序,估计是正常的输出吧
kmlin 2003-09-05
  • 打赏
  • 举报
回复
我机器上的输出结果为:
a:01234567890123401
b:0123401
c:01
原因:
字符窜test.a的结束标志\n写到了test.b[0]中接着被strcpy(test.b,"01234");覆盖
同理test.b的结束符被strcpy(test.c,"01");覆盖
test.c的结束标志写道test.c[1]后面的空间里。
所以出现上述结果
jxbicestare 2003-09-05
  • 打赏
  • 举报
回复
帮帮忙啊……
加载更多回复(11)

70,020

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧