C语言学习笔记——字符串操作( 二 )


输出结果如下:
[root@gavinpan p2]# ./p_and_s Don't be a fool!msg = Don't be a fool!; &msg = 0x7ffcb7cb1348; value = http://www.kingceram.com/post/0x4006d8copy = Don't be a fool!; © = 0x7ffcb7cb1340; copy = 0x4006d8
其中,&msg = 和© = 说明指针msg和copy分别存储在地址为和的内存中;最后一项value =http://www.kingceram.com/post/,说明两个指针指向了同一个位置,因此,程序并未拷贝字符串 。
字符串输入不安全的gets()函数
gets()函数读取整行输入,直到遇到换行符,然后丢弃其余字符,存储其余字符;并在这些字符的末尾添加一个空字符\0 。
使用示例:
char words[10];gets(words);puts(words);
gets()函数唯一的参数是words,它无法坚持该数组是否装得下输入行 。因此,gets()函数只知道数组的开始位置,但不知都数组中有多少个元素 。
一旦输入的字符过长,就会导致缓冲区溢出( ),即多余的字符超出了指定的目标空间 。如果这些多余的字符只是占用了尚未使用的内存,就不会立即出现问题;但如果它们擦写掉了程序中的其他数据,就会导致程序异常终止;或者其他情况 。
gets()的替代品 fgets()函数
该函数专门设计用于处理文件输入 。`使用示例如下:
char words[10];fgets(words, 10, stdin);fputs(words, stdout);
fgets()与gets()的区别如下:
1 第2个参数指明了读入字符的最大数量 。如果该参数为n,那么fgets()将读入n-1个字符,或者遇到第一个换行符为止 。
2 如果fgets()读到一个换行符,会把它存储咋字符串中 。而gets()则会丢弃换行符 。
3 第3个参数,指明要读入的文件 。若要从键盘读取输入,则以stdin(标准输入)作为参数 。stdin定义在stdio.h中 。
fgets()通常与fputs()配对使用 。fputs()的第二个参数,指明它要写入的文件,如果要输出到屏幕,则使用(标准输出)作为参数 。
fgets()的返回值是指向char的指针 。如果一切顺利,返回的地址与第1个参数相同;如果读到文件结尾,则会返回空指针(null ) 。代码示例如下:
/* fgets2.c -- 使用fgets()和fputs() */#include #define STLEN 10int main(void) {char words[STLEN];puts("Enter strings (empty line to quit):");while (fgets(words, STLEN, stdin) != NULL && words[0] != '\n') {fputs(words, stdout);}puts("Done.");return 0;}
输出:
Enter strings (empty line to quit):hellohelloc primer plusc primer plusDone.
系统使用缓冲的I/O 。意味着在按下键之前,输入都被存储在缓冲区 。按下键会在输入中增加一个换行符\n,并把整行输入发送给fgets() 。对于输出,fputs()把字符发送给另一个缓冲区,当发送换行符时,缓冲区的内容被发送至屏幕上 。
fgets()会存储输入中的换行符\n,那么如何处理换行符呢?参见如下示例:
/* * fgets3.c* 处理通过fgets()获取的字符串中的换行符,* 若无换行符,则丢弃多余字符 。**/#include #define STLEN 10int main(void) {char words[STLEN];puts("Enter strings (empty line to quit):");while (fgets(words, STLEN, stdin) != NULL && words[0] != '\n') {int i = 0;while (words[i] != '\n' && words[i] != '\0') {i++;}if (words[i] == '\n') {// 处理换行符words[i] = '\0';} else {while (getchar() != '\n') {// 丢弃输入中的多余字符continue;}}puts(words);}puts("Done.");return 0;}
输出: