关于C语言字符数组的问题

OOo,TeX,KO,ABI,GIMP,Picasa,ProE,QCAD,Inkscape,Kicad,Eagle
回复
B-E-W-D
帖子: 25
注册时间: 2011-02-05 9:40

关于C语言字符数组的问题

#1

帖子 B-E-W-D » 2012-10-05 13:50

#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]?
头像
枫叶饭团
帖子: 14683
注册时间: 2010-06-16 1:05
系统: Mac OS X
来自: Tencent
联系:

Re: 关于C语言字符数组的问题

#2

帖子 枫叶饭团 » 2012-10-05 13:56

vc6.0用的不是标准C。。。这个完全是编译器的问题,我用gcc你的这两个问题都没有。。。
头像
YeLee
论坛版主
帖子: 26406
注册时间: 2008-08-13 8:48
系统: Fundu i64
来自: 东海硇州,一双管钥。
联系:

Re: 关于C语言字符数组的问题

#3

帖子 YeLee » 2012-10-05 14:10

天啊,难道没有溢出? :em20 :em20 :em20
你再输入长点啊,我就不信没段错误。 :em01 :em01 :em01
◎当我站在道德的高度上俯视别人的时候,发现自己是多么渺小。
♥执着但不偏激,反对而不排斥,坚决捍卫矛盾体的存在方式。
★★★天气预报★★★
fcitx-yatable一个可以使用的码表输入法
[教程]几个实例攻克软件编译难关
Gentoo Development Guide
字体相关
头像
cuihao
帖子: 4793
注册时间: 2008-07-24 11:33
来自: 郑州
联系:

Re: 关于C语言字符数组的问题

#4

帖子 cuihao » 2012-10-05 14:29

str[3]相当于*(str+3),语法上并不错误嘛,所以可以正常编译的。
但LZ你知道不能这么写,这么写会出错就行了。
求人不如求它仨: 天蓝的Wiki 屎黄的Wiki 绿
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语言字符数组的问题

#5

帖子 cuihao » 2012-10-05 14:34

LZ你第一个写法,不要以为“读取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
这就是内存溢出。str[]="" 声明的str只有两字节,剩下的都溢出了。所谓“读取4个字符”没有错误大概是还没有溢出到“程序外的内存”。
求人不如求它仨: 天蓝的Wiki 屎黄的Wiki 绿
Site: CUIHAO.TK    Twitter: @cuihaoleo
Machine: Athlon64 X2 5200+ / 2x2GB DDR2-800 / GeForce GTS 450
AD: ~まだ見ぬ誰かの笑顔のために~
B-E-W-D
帖子: 25
注册时间: 2011-02-05 9:40

Re: 关于C语言字符数组的问题

#6

帖子 B-E-W-D » 2012-10-05 19:00

五楼说的没看懂。到底怎么回事?第一段代码虽然我知道一定是错的,但错在哪里呢?明明是读取一段字符串,再输出啊,数组str没有写出下标,是不是可以读取任意长度的字符串啊?
头像
cuihao
帖子: 4793
注册时间: 2008-07-24 11:33
来自: 郑州
联系:

Re: 关于C语言字符数组的问题

#7

帖子 cuihao » 2012-10-05 21:10

数组定义没给大小的话,就按照后面初始化的字符串分配。比如:

代码: 全选

str[]="fa"
那么分配的str就有三个字节(f、a、终止标记'\0')。

我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: ~まだ見ぬ誰かの笑顔のために~
reallynotme
帖子: 157
注册时间: 2010-11-11 18:13
系统: Ubuntu

Re: 关于C语言字符数组的问题

#8

帖子 reallynotme » 2012-10-06 9:19

这样定义:char str[]="abcd";
str的大小等于后面字符串的大小,加上'\0',在这里就是5

这样定义:char str[]="";
""相当于"\0",也就是str大小为1

至于后面那个没出错,有可能是内存对齐的导致的,简而言之,就是虽然溢出了,但是严重程度不至于程序马上终止,虽然运行不出错,但是根本就不能这么写.

另外我想这个问题不应该在ubuntu论坛上问吧,何况你用的是vc6
还有就是你对c的理解非常不好,建议多看几遍书
至于2楼,真是服了你,你也应该去看多几遍书
cangyueshang
帖子: 132
注册时间: 2011-01-13 16:16

Re: 关于C语言字符数组的问题

#9

帖子 cangyueshang » 2012-10-06 15:48

同意楼上看法,你第一个程序定义了一个空字符串,但这个字符串并不是什么都没有的,而是有“\0”,因此,你的程序一开始是不会出错的,因为数组已经初始化了, 虽然你数组下标什么都没写,并不代表数组可以想写多长写多长,你的数组申请空间的大小在你初始化数组之后就定了,只是C语言编译程序不会检查数组下标是否越界,因此,可能会出现你可以使用到你本身没有申请到那么长的数组空间。
回复