C语言学习周总结005(字符串)
字符串(String)早在我们刚开始学习C语言时就接触到了,也就是在我们第一次敲着代码输出"Hello World!"的时候,不过那时候我们并不知道那是字符串,或者说当时对字符串这种东西并不熟悉,不过经历了这段时间学习我们开始对字符串有了一定的了解,这周就来谈谈字符串。
字符串其实是一种字符型数组,那既然是数组就一定有一些共同特点:
比如字符串里以字符为单位,相邻字符的地址连续存储,字符串的变量名也是指向首个字符的地址,引用时只需引用首地址。
字符串还有自己的特点:
如输入一串字符串存储时,编译器会自动在字符串的末尾加上停止符 '\0' ,而且字符串必须以该停止符结尾才是有效的字符串,否则会编译错误。
字符串的使用:
输入&输出:
只有一行的输入输出(中间无空格):
多行的输入输出(中间有空格,每行以回车结尾,注意每行结尾要将剩余的换行读取掉):
一些常用的字符串库函数:
strlen(s) : 返回字符串s的长度;
strcpy(s1, s2) : 将字符串s2复制给s1,注意s2长度不能大于s1的长度,复制完会覆盖s1的全部字符;
strncpy(s1, s2, n) : 将字符串s2中的前n个字符复制给s1的前n个字符,s1中前n个字符除外的字符不变, 注意n不能大于s1和s2长度的最小值;
strcmp(s1, s2) : 比较两个字符串,若s1>s2返回值大于零,反之返回值小于零,两个字符串相等时返回值为零;
strcat(s1, s2) : 将字符串s2接到字符串s1的末尾
例题:
本题要求编写程序,将给定字符串去掉重复的字符后,按照字符ASCII码顺序从小到大排序后输出。
输入格式:
输入是一个以回车结束的非空字符串(少于80个字符)。
输出格式:
输出去重排序后的结果字符串。
分析:
先读取输入的一行字符串,使用一个全局数组来统计该字符串里每个字符出现的次数,遍历字符串将不重复的字符存入一个新的字符串,重复的字符只存入一次,保证新字符串里所有字符不重复,再对新字符串按ASCII码进行冒泡排序,最后输出排序后的新字符串。
代码:
#include <stdio.h> #include <string.h> int cnt[128]; // 定义全局数组cnt统计字符串中每个字符出现的次数 int main() { char str[81], s[81]; scanf("%[^\n]s", str); // 读取一行字符,遇回车停止读取 getchar(); // 读取掉换行 int i, len = strlen(str); // 字符串str长度len for (i = 0; i < len; i++){ int a = str[i]; cnt[a]++; } // 统计字符出现次数 int lens = 0; // 字符串s长度lens for (i = 0; i < len; i++){ int a = str[i]; if (cnt[a] > 0){ // 先将出现次数大于0的字符存入字符数组s 接着将其对应的次数赋值为0 使下次读取到相同字符时不会存入字符数组s 保证s里的字符不重复 s[lens++] = str[i]; cnt[a] = 0; } } // 将未重复的字符存入s字符数组 s[lens] = '\0'; // 冒泡排序 int j; for (i = 1; i < lens; i++){ int flag = 0; for (j = 0; j < lens-i; j++){ if (s[j] > s[j+1]){ int t = s[j]; s[j] = s[j+1]; s[j+1] = t; flag++; } } if (!flag) // 使用flag标记子循环里是否出现了交换 若无交换则表示排序完毕 可直接跳出循环 该步骤可以有效的减少循环次数 改善程序性能 break; } printf("%s\n", s); // 输出 return 0; }
运行测试:
测试样例1:mosimita
测试结果:
测试样例2: (空)
测试结果:
运行成功!
end:)