#include <stdio.h>
int main ()
{
char str[]="";
printf ("please input : ");
scanf ("%s",str);
printf ("%s\n",str);
return 0;
}
用上面这样的写法,最多只能从键盘读取4个字符,如果输入5个,还能正常输出,但会弹出错误警告(XX内存不能为“written”)。这是怎么回事啊?编译器是vc++6.0,系统是xp(应该是32位,学校的机子)。
#include <stdio.h>
int main ()
{
char str[2];
printf ("please input : ");
scanf ("%c",&str[0]);
printf ("%c\n",str[0]);
scanf ("%c",&str[1]);
printf ("%c\n",str[1]);
scanf ("%c",&str[2]);
printf ("%c\n",str[2]);
scanf ("%c",&str[3]);
printf ("%c\n",str[3]);
return 0;
}
还有上面的写法居然没报错,可以读取并输出4个字符,char str[2];不是应该是只有str[0],str[1]两个元素吗?为什么可以有str[2],str[3]?
关于C语言字符数组的问题
-
- 帖子: 25
- 注册时间: 2011-02-05 9:40
- 枫叶饭团
- 帖子: 14683
- 注册时间: 2010-06-16 1:05
- 系统: Mac OS X
- 来自: Tencent
- 联系:
Re: 关于C语言字符数组的问题
vc6.0用的不是标准C。。。这个完全是编译器的问题,我用gcc你的这两个问题都没有。。。
- YeLee
- 论坛版主
- 帖子: 26406
- 注册时间: 2008-08-13 8:48
- 系统: Fundu i64
- 来自: 东海硇州,一双管钥。
- 联系:
Re: 关于C语言字符数组的问题
天啊,难道没有溢出?
你再输入长点啊,我就不信没段错误。




你再输入长点啊,我就不信没段错误。



◎当我站在道德的高度上俯视别人的时候,发现自己是多么渺小。
♥执着但不偏激,反对而不排斥,坚决捍卫矛盾体的存在方式。
★★★天气预报★★★
fcitx-yatable一个可以使用的码表输入法
[教程]几个实例攻克软件编译难关
Gentoo Development Guide
字体相关
♥执着但不偏激,反对而不排斥,坚决捍卫矛盾体的存在方式。
★★★天气预报★★★
fcitx-yatable一个可以使用的码表输入法
[教程]几个实例攻克软件编译难关
Gentoo Development Guide
字体相关
- cuihao
- 帖子: 4793
- 注册时间: 2008-07-24 11:33
- 来自: 郑州
- 联系:
Re: 关于C语言字符数组的问题
str[3]相当于*(str+3),语法上并不错误嘛,所以可以正常编译的。
但LZ你知道不能这么写,这么写会出错就行了。
但LZ你知道不能这么写,这么写会出错就行了。
求人不如求它仨: 天蓝的Wiki 屎黄的Wiki 蓝红黄蓝绿红
Site: CUIHAO.TK Twitter: @cuihaoleo
Machine: Athlon64 X2 5200+ / 2x2GB DDR2-800 / GeForce GTS 450
AD: ~まだ見ぬ誰かの笑顔のために~
Site: CUIHAO.TK Twitter: @cuihaoleo
Machine: Athlon64 X2 5200+ / 2x2GB DDR2-800 / GeForce GTS 450
AD: ~まだ見ぬ誰かの笑顔のために~
- cuihao
- 帖子: 4793
- 注册时间: 2008-07-24 11:33
- 来自: 郑州
- 联系:
Re: 关于C语言字符数组的问题
LZ你第一个写法,不要以为“读取4个字符”没有错误就说明是正确的:
这就是内存溢出。str[]="" 声明的str只有两字节,剩下的都溢出了。所谓“读取4个字符”没有错误大概是还没有溢出到“程序外的内存”。
代码: 全选
#include <stdio.h>
int main ()
{
char str[]="", a='\0', b='\0';
printf ("please input : ");
scanf ("%s",str);
printf ("%s\n",str);
printf ("%c\n",a);
return 0;
}
代码: 全选
cuihao@cuihao-arch /tmp $ gcc a.c
a.c: 在函数‘main’中:
a.c:4:28: 警告:未使用的变量‘b’ [-Wunused-variable]
cuihao@cuihao-arch /tmp $ ./a.out
please input : abc
abc
c
求人不如求它仨: 天蓝的Wiki 屎黄的Wiki 蓝红黄蓝绿红
Site: CUIHAO.TK Twitter: @cuihaoleo
Machine: Athlon64 X2 5200+ / 2x2GB DDR2-800 / GeForce GTS 450
AD: ~まだ見ぬ誰かの笑顔のために~
Site: CUIHAO.TK Twitter: @cuihaoleo
Machine: Athlon64 X2 5200+ / 2x2GB DDR2-800 / GeForce GTS 450
AD: ~まだ見ぬ誰かの笑顔のために~
-
- 帖子: 25
- 注册时间: 2011-02-05 9:40
Re: 关于C语言字符数组的问题
五楼说的没看懂。到底怎么回事?第一段代码虽然我知道一定是错的,但错在哪里呢?明明是读取一段字符串,再输出啊,数组str没有写出下标,是不是可以读取任意长度的字符串啊?
- cuihao
- 帖子: 4793
- 注册时间: 2008-07-24 11:33
- 来自: 郑州
- 联系:
Re: 关于C语言字符数组的问题
数组定义没给大小的话,就按照后面初始化的字符串分配。比如:
那么分配的str就有三个字节(f、a、终止标记'\0')。
我5楼貌似搞错了,按照你的 str[]="" 其实只分配了一个字节(终止标记'\0')。
C是“最低级的高级语言”,没有“读取任意长度的字符串”的。
我那个例子,你好好看看。本来变量a是空的,代码中读取了str,没有改变a。但str读取过多字符后,a的内容也改变了。这就叫“溢出”。
scanf只是从str的第一个位置往后一个个填充读取的字符,不考虑越界没有(所以说C是相当低级的语言……),然后就溢出到其他内存位置,比如变量a中了。
你说的windows报错,就是因为溢出太严重了,以至于入侵到不属于该程序的内存了。
代码: 全选
str[]="fa"
我5楼貌似搞错了,按照你的 str[]="" 其实只分配了一个字节(终止标记'\0')。
C是“最低级的高级语言”,没有“读取任意长度的字符串”的。
我那个例子,你好好看看。本来变量a是空的,代码中读取了str,没有改变a。但str读取过多字符后,a的内容也改变了。这就叫“溢出”。
scanf只是从str的第一个位置往后一个个填充读取的字符,不考虑越界没有(所以说C是相当低级的语言……),然后就溢出到其他内存位置,比如变量a中了。
你说的windows报错,就是因为溢出太严重了,以至于入侵到不属于该程序的内存了。
求人不如求它仨: 天蓝的Wiki 屎黄的Wiki 蓝红黄蓝绿红
Site: CUIHAO.TK Twitter: @cuihaoleo
Machine: Athlon64 X2 5200+ / 2x2GB DDR2-800 / GeForce GTS 450
AD: ~まだ見ぬ誰かの笑顔のために~
Site: CUIHAO.TK Twitter: @cuihaoleo
Machine: Athlon64 X2 5200+ / 2x2GB DDR2-800 / GeForce GTS 450
AD: ~まだ見ぬ誰かの笑顔のために~
-
- 帖子: 157
- 注册时间: 2010-11-11 18:13
- 系统: Ubuntu
Re: 关于C语言字符数组的问题
这样定义:char str[]="abcd";
str的大小等于后面字符串的大小,加上'\0',在这里就是5
这样定义:char str[]="";
""相当于"\0",也就是str大小为1
至于后面那个没出错,有可能是内存对齐的导致的,简而言之,就是虽然溢出了,但是严重程度不至于程序马上终止,虽然运行不出错,但是根本就不能这么写.
另外我想这个问题不应该在ubuntu论坛上问吧,何况你用的是vc6
还有就是你对c的理解非常不好,建议多看几遍书
至于2楼,真是服了你,你也应该去看多几遍书
str的大小等于后面字符串的大小,加上'\0',在这里就是5
这样定义:char str[]="";
""相当于"\0",也就是str大小为1
至于后面那个没出错,有可能是内存对齐的导致的,简而言之,就是虽然溢出了,但是严重程度不至于程序马上终止,虽然运行不出错,但是根本就不能这么写.
另外我想这个问题不应该在ubuntu论坛上问吧,何况你用的是vc6
还有就是你对c的理解非常不好,建议多看几遍书
至于2楼,真是服了你,你也应该去看多几遍书
-
- 帖子: 132
- 注册时间: 2011-01-13 16:16
Re: 关于C语言字符数组的问题
同意楼上看法,你第一个程序定义了一个空字符串,但这个字符串并不是什么都没有的,而是有“\0”,因此,你的程序一开始是不会出错的,因为数组已经初始化了, 虽然你数组下标什么都没写,并不代表数组可以想写多长写多长,你的数组申请空间的大小在你初始化数组之后就定了,只是C语言编译程序不会检查数组下标是否越界,因此,可能会出现你可以使用到你本身没有申请到那么长的数组空间。