2 moefish Moefish 于 2015.06.05 14:56 提问

关于C语言中的字符串输入输出

出于好奇测试了一下,声明的时候:
char ch[5];
scanf("%s",ch);
printf("%s,%d",ch,sizeof ch);

如果输入超过5个字母,字母都还是会全部显示出来的,而ch的大小还是5BYTE。这printf到底是什么黑科技?顺便问一下%s是怎么支持Unicode的?好像汉字啦,Ctrl+字符这一类奇奇怪怪的好像也都可以输出诶,怎么做到的?
好像getchar()也能正常识别汉字并储存的样子……

3个回答

gamefinity
gamefinity   Rxr 2015.06.05 15:13
已采纳

1.关于超过5个字节的问题。你的这样做法,数组实际已经跨过界了。问题是会表现出来的。例如,你在这个ch[5]后面另外定义一个int,先给这个int赋好值,你会发现scanf之后那个int的值变了.如果后面是没有数据的话,有可能会引起段错误..
2.有C/C++有tchar.h,可以完全支持unicode.根据你的控制台/终端的编码方式,ASCII0-31的控制字符,ASCII128-255的字符,也可能有对应的可显示字符的。甚至在一定情况下也可以把GBK的两半拼起来显示为一个汉字。但是如果存在编码转换,例如输入的时候是UTF-8,输出GBK就一定要处理过才行。

gamefinity
gamefinity 回复Moefish: printf看到的只是一块内存,它不知道你的分界线是在哪里的,因此它总是输出直到'\0'.现在的一些更高级的语言,例如Java,c#之类的,就可以安全的判断出字符串的结束位置了,但同时也消耗了更多的机器资源.C更贴近机器本身,因此不会在这方面浪费机器的资源.
2 年多之前 回复
Moefish
Moefish 那printf为何没有在正确的地方停下来?而是强行要打印到结束符?
2 年多之前 回复
Tiger_Zhao
Tiger_Zhao   Rxr 2015.06.05 15:15

这不是黑科技,而是ch之后的不属于ch的内存也被非法使用了。
你可以用下面的代码测试一下长度超过5的情况。

    char ch0[100];
    char ch[5];
    char ch2[100];
    scanf("%s",ch);
    printf("%s",ch0);
    printf("%s",ch);
    printf("%s",ch2);
VisualEleven
VisualEleven   Ds   Rxr 2015.06.05 15:20

这种数组溢出的问题会导致后面的数据被覆盖,有时候会出错,有时候又不会出错,看当时的运行时环境。

Csdn user default icon
上传中...
上传图片
插入图片