雅乐网

计算机技术、学习成长

编程 » C/C++ » C语言字符串和字符串输入输出

C语言字符串和字符串输入输出

字符串是C语言中最重要的数据类型之一,不过C语言中没有自带的字符串类型,而是使用一串以’\0’结尾的字符数组来表示字符串。下面雅乐网总结了一下常用的C语言中字符串的知识

字符串简介

字符串就是以空字符(’\0’)结尾的char数组。例如字符串”Hello”,在内存中是这样表示的

scrn20141109135059

因此,要用一个char数组存放字符串hello,就必须分配5+1个空间,多余的一个用来存放空字符’\0’。

用双引号可以表示字符串,例如 “Hello” ,这是一个表达式,它的值实际上是’H’字符所在的地址。因此,可以像数组名那样用”Hello”,例如

“Hello”[2]就等于’l’。

表示字符串的双引号并不是字符串的一部分,只是告诉编译器这是个字符串,编译器会自动分配一个内存,如上图所示,”Hello”的值就是p的位置。

双引号和单引号的区别

从上面可以看出,双引号包起来的字符串,它的值是一个地址,是字符串第一个字符的地址。

单引号表示的是一个字符,而字符又是ASCII码表示的,所以单引号包起来的一个字符相当于一个int。

‘A’ 表示字符A,它的值是’A’的ascii码,也就是十进制65 。

而”A”表示的是字符串,它的值是一个指向char的地址,他在内存中有两个char空间,’A’和’\0′ 。”A”[0]就是’A’

双引号表示的字符串存储在常量区,字符串的内容不允许被修改。

字符串数组的初始化

初始化字符串数组的时候可以使用””

char m[10] = “Hello”;

m数组初始化成这样

scrn20141109142411

而如果不指定数组大小,char m[] = “Hello” 那么m会分配为6个char 。也就是字符串字符个数+1

只有初始化的时候可以这样赋初始值,一旦声明了数组后,不能用这种形式给数组赋值

char m[10];
m = “Hello”;

这是错误的。因为一旦声明了char m[10] m就是这一块内存的名字了,他不能改变为指向其他的内存。

声明之后还要给数组赋值,只能这样了

m[0] = ‘H’;
m[1] = ‘e’;
m[2] = ‘l’;
m[3] = ‘l’;
m[4] = ‘o’;
m[5] = ‘\0′;

这样之后,m[6]以及后面的值是不知道的。可能是’\0’ 更可能不是。可以先使用memset给数组全体赋初始值0.

memset(m, 0, sizeof(m));

因为’\0’的ascii码就是0,所以现在数组里全部是空字符。

sizeof数组名 得到的是整个数组的大小。

字符串输入

读入一个字符串,首先要预留存储该字符串的空间。

可以使用char m[10]来分配10个字节的空间,它可以存储9个字符,加上一个空字符’\0′

char *gets( char *str );

gets()函数从标准输入获取一个字符串存入str所指向的内存中。

gets()在读取字符传的时候以换行‘\n’(按下回车键)作为字符串的结束标志。遇到回车后,将换行之前的所有字符(不包括\n)的末尾添加一个’\0’字符,存入str所指向的内存。然后丢弃这个换行。这样下次读取的时候,从新的一行开始。

例如代码

char m1[10];
char m2[10];

gets(m1);
gets(m2);

运行后输入abcdef回车123456回车,两个数组的内容是这样的

scrn20141109144522

未知部分是保持原有值的。

gets()的返回值一般读取成功时就是str的值。如果读取失败,例如遇到文件尾,什么也没读进去,就会返回一个NULL

while (gets(name) != NULL)

这样写既可以读取值,又可以检测文件尾。

由于gets不检查数组大小是否足够容纳字符串,因此是不安全的。c11提供了带字符串数目的char *gets_s( char *str, rsize_t n );函数。

char *fgets( char *str, int count, FILE *stream );

fgets函数的第一个参数和gets的参数作用一致。

fgets函数的第二个参数说明了允许读入的最大字符数。

fgets函数的第三个参数是为文件输入而设计的一个文件指针。不过,我们可以使用stdin作为第三个参数,这样会从标准输入读取。

返回值和gets函数类似。成功读入返回str 失败返回NULL

fgets仍然以换行作为字符串结束的标志,不过它会把换行也作为字符串的一部分。如果一直遇不到换行,fgets最多会读取count-1个字符后就会停止。

不管什么情况,fgets总会在读取字符的最后面添加一个’\0′

例如 代码

char m1[10];
char m2[10];

fgets(m1, 5, stdin);
fgets(m2, 5, stdin);

输入 abcdefg回车 两个数组是这样的

scrn20141109145752

​int scanf( const char *format, … );​

scanf读取字符串时使用%s。它和gets函数的主要区别在于字符串的结束标志。scanf是读取单词的形式。

%s时它会读到空白符(空格 制表符\t 换行)不包括空白符时结束并在末尾添加’\0′ 下次读取从下一个非空白符开始,会跳过中间的所有空白符

%10s指定了最多读取10个字符。由于在末尾加上’\0′ 所以最多需要11个存储空间。

字符串输出

int puts( const char *str );

puts的参数是字符串地址,它在屏幕显示字符串,直到遇到空字符\0.

它会在末尾自动添加换行。(和gets不读取换行对应)

int fputs( const char *str, FILE *stream );

fputs的第一个参数是要输出的字符串地址,第二个参数是文件指针。可以使用stdout参数 代表标准输出

fputs不会在字符串末尾添加\n (和fgets读取\n对应)

​int printf( const char *format, … );​

printf使用%s指定字符串格式。它不会自动换行。效率也比puts要低一点。

getchar和putchar

int getchar();

getchar从标准输入读一个字符,并返回ascii码 遇到文件尾则返回EOF

int putchar( int ch );

在标准输出输出ch 。ch会转化为unsigned类型。

成功返回ch的值 不然返回EOF

 

如果文章对你有帮助,欢迎点赞或打赏(金额不限)。你的打赏将全部用于支付网站服务器费用和提高网站文章质量,谢谢支持。

版权声明:

本文由 原创,商业转载请联系作者获得授权。
非商业转载请注明作者 雅乐网 ,并附带本文链接:
http://www.yalewoo.com/c_string_io.html

上一篇:

下一篇:

我要评论

验证码*: 4 + 1 =