Educoder-程序设计基础: 字符串
字符串的表示
char str1[100] = {'A', 'd', 'a','\0'};
char str2[100] = "Ada";
char str3[100];
str3 = "Ada" // 错误!表示一个储存多个字符的数组,且不能用=赋值
strcpy(str3, "Ada"); // 正确
- 上述代码中,第一行定义了一个名叫str1的字符数组,数组中的前4个元素分别是字符
'A', 'd', 'a', '\0'
。\0
是一个转义字符,表示字符串结束。str1表示字符串"Ada"。
- 第二行定义了一个名叫str2的字符数组,效果等同于第一行代码str1的定义,但写法更简洁明了。注意字符串用双引号括起来,不能用单引号。
- 第三行定义了一个名叫str3数组,数组容量是100。请问str3最多能表示多长的字符串呢?没错,答案是99,因为数组需要用一个字符存储字符串结束标记
'\0'
。如果一个字符数组没有存储'\0'
,它只是一个存储多个字符的数组,不是字符串。如何实现对字符数组赋值字符串呢?没错!可借用strcpy函数,如第五行所示。 - 在定义字符数组的时候可以通过
=
用字符串初始化字符数组,例如第一、二行的代码。当定义了字符数组后,就不能用=
对两个字符串赋值了,所以第四行的代码是错误的。
字符串的输入和输出
scanf读入字符串时,会用空格分隔字符串,因此上述代码只能读取空格前的部分"Hello"
。若想读入带空格的字符串,改用gets、gets_s或fgets
char str1[100];
scanf("%s", str1); // 不能读入空格,只能读入空格前的字符串内容。
char str2[100];
gets(str2); // 在vs2012下,使用gets(str2)读入带空格的字符串
gets_s(str2); // 在vs2019下,使用gets_s读入带空格的字符串
fgets(str2, 100, stdin); // 在EduCoder的编译器环境下,用fgets。str2是字符串数组名,100表示最多读入100个字符,stdin表示标准输入,做题时不需要改变stdin参数。
字符串的遍历
1.对整形数组遍历
int a[100]={1,2,3};
int a=3;
for(int i=0;i<3;i++){
//遍历a[i];
}
2.对字符串遍历
char str[100];
gets(str);
for(int i=o;str[i]!='\0';i++){
//遍历str[i];
}
第1关:求字符串的长度
#include <stdio.h>
#include <string.h>
int main()
{
//****补全代码****
char a[100];
int i, len = 0;
fgets(a, 100, stdin);
for (i = 0; a[i] != '\0'; i++)
len++;
printf("%d", len);
return 0;
}
第2关:奇数个数
本关任务:输入一个多位数,将多位数看作一串字符,输出其中奇数数字的个数
#include <stdio.h>
#include <string.h>
int main()
{
//****补全代码****
char str[100];
scanf("%s", str);
int i, sum = 0;
for (i = 0; str[i] != '\0'; i++) {
if (str[i] % 2 != 0)
sum++;
}
printf("%d", sum);
return 0;
}
第3关:统计字符个数
#include <stdio.h>
#include <string.h>
int main()
{
char str[100];
fgets(str, 100, stdin);
//****补全代码****
int i, a = 0, b = 0, c = 0;
for (i = 0; str[i] != '\0'; i++)
{
if (str[i] >= 'a' && str[i] <= 'z' || str[i] >= 'A' && str[i] <= 'Z')
a++;
else if (str[i] >= '0' && str[i] <= '9')
b++;
else
c++;
}
printf("%d %d %d", b, a, c);
return 0;
}
第4关:统计元音字母
本关任务:编写一个程序统计字符串中元音字母aeiou
出现的次数
#include <stdio.h>
#include <string.h>
int main()
{
char str[100];
fgets(str, 100, stdin);
//****补全代码****
int i, a = 0, b = 0, c = 0, d = 0, e = 0;
for (i = 0; str[i] != '\0'; i++)
{
if (str[i] == 'a' || str[i] == 'A')a++;
else if (str[i] == 'e' || str[i] == 'E')b++;
else if (str[i] == 'i' || str[i] == 'I')c++;
else if (str[i] == 'o' || str[i] == 'O')d++;
else if (str[i] == 'u' || str[i] == 'U')e++;
}
printf("a:%d\ne:%d\ni:%d\no:%d\nu:%d\n", a, b, c, d, e);
return 0;
}
第5关:字母变大写
本关任务:编写小程序,把字符串的所有小写字母变成大写,其它字符不变。 注:不使用库函数
#include <stdio.h>
#include <string.h>
int main()
{
char str[100];
int i;
fgets(str, 100, stdin);
//****补全代码****
for (i = 0; str[i] != '\0'; i++)
{
if (str[i] >= 97 && str[i] <= 122)
str[i] = str[i] - 32;
}
puts(str);
return 0;
}
第6关:判断用户名合法性
你需要为某网站的用户注册功能判断用户名是否合法。假设用户名只能由数字、字母、下划线_
组成,且用户名的长度最少为4,最多不超过20
#include <stdio.h>
#include <string.h>
int main()
{
char str[100];
fgets(str, 100, stdin);
//****补全代码****
int len = 0, i, j;
j = strlen(str); //判断字符串长度
for (i = 0; str[i] != '\0'; i++)
{
if (str[i] >= 'A' && str[i] <= 'Z' || str[i] >= 'a' && str[i] <= 'z' || str[i] >= '0' && str[i] <= '9' || str[i] == '_')
len += 1; //有效情况下加1
}
if (j >= 4 && j <= 20) //判断长度是否合法
{
if (len == j)
printf("yes"); //判断字符串长度是否等于有效长度
else
printf("no");
}
else
printf("no");
return 0;
}
第7关:合法密码
本关任务:接下来,你将要完成网站注册功能的后半部分工作:判断密码的合法性。一个“好”的密码应该:
- 包括数字字符、字母字符和其它字符(
'!','@','#','$','%','^','&','-','_'
)中至少两类; - 长度至少为6。
#include <stdio.h>
#include <string.h>
int main()
{
char str[100];
fgets(str, 100, stdin);
//****补全代码****
int i, a = 0, b = 0, c = 0, len;
len = strlen(str);
for (i = 0; str[i] != '\0'; i++)
{
if (str[i] >= '0' && str[i] <= '9')
a++;
if (str[i] >= 'a' && str[i] <= 'z' || str[i] >= 'A' && str[i] <= 'Z')
b++;
if (str[i] == '!' || str[i] == '@' || str[i] == '#' || str[i] == '$' || str[i] == '%' || str[i] == '^' || str[i] == '&' || str[i] == '_' || str[i] == '-')
c++;
}
if (len >= 6)
{
if (a == 0 && b == 0 || a == 0 && c == 0 || b == 0 && c == 0)
printf("no");
else
printf("yes");
}
else
printf("no");
return 0;
}
第8关:大整数表示
#include <stdio.h>
#include <string.h>
int main()
{
char str[100];
fgets(str, 100, stdin);
int len, s, flag = 1;
len = strlen(str);
s = len;
for (; len > 0; len--)
{
//这个flag是防止第一位就打,
//eg.123456789->123,456,789 不加flag的话就会变成 ,123,456,789
if (flag == 0)
if (len % 3 == 0)
printf(",");
printf("%c", str[s - len]);
flag = 0;
}
return 0;
}
第9关:回文判断
本关任务:编写一个小程序,判断一个字符串是否回文。“回文”的意思是从左到右和从右到左的读取结果相同。例如“ada”就是回文
#include <stdio.h>
#include <string.h>
int main()
{
char str[100];
fgets(str, 100, stdin);
int i, j, len;
len = strlen(str);
for (i = 0, j = len - 1; i <= j && str[i] == str[j]; i++, j--);//条件成立的话i会增加,j会减小
if (i > j)
printf("yes"); //如果是回文的话i会大于j
else
printf("no");
return 0;
}
第10关:统计单词个数
编写一个小程序,输入一个句子,统计当中包含多少个单词。一个单词由连续的字母组成,非字母字符用来分割单词
这道题初看有点难度,有多个非字母的字符。我们可以一步一步简化题目。
- 首先,通过分析可得,字符串中的非字母字符起分割单词的作用。为了方便代码处理,我们可以把所有非字母字符用一个统一的符号表示,例如,都转换成空格。以输入样例为例,用代码把
I like to read it, read it 100 times!
变成I like to read it read it times
这样,我们能通过“数”字符串中有多少个分割来计算字符串中有多少个单词了。例如,例子中有8处空格(分割),分别位于I、like、to、read、it、read、it times
之后。由于句子以分割结束(times后面有一个' '
分割),因此句子中有8个单词。
-
接下来,程序要“数”字符串中的空格,来判断句子中有多少个单词。
- 多个连续的空格只能算一个分割。因此,在扫描到一个空格
' '
的时候,要判断前一个字符是否也是空格' '
。注意,字符串的首个字符没有“前一个字符”。 - 如果字符串以分割结束,则单词数 = 分割数。如果字符串以字母结束,则单词数 = 分割数+1。
- 多个连续的空格只能算一个分割。因此,在扫描到一个空格
#include <stdio.h>
#include <string.h>
int main()
{
char str[100];
fgets(str, 100, stdin);
int a = 0, i;
if (str[0] != ' ');
a = 1;
for (i = 1; str[i] != '\0'; i++)
{
if (str[i] >= 'a' && str[i] <= 'z' || str[i] >= 'A' && str[i] <= 'Z');
else
str[i] = ' ';
if (str[i] != ' ' && str[i - 1] == ' ')
a++;
}
printf("%d", a);
return 0;
}
第11关:比较字符串大小
写一个小程序,输入两个字符串,按字典序判断字符串的大小
#include <stdio.h>
#include <string.h>
int main()
{
char s1[100], s2[100];
scanf("%s", s1); // 读入第一行字符串
scanf("%s", s2); // 读入第二行字符串
//****补全代码****
if (strcmp(s1, s2) > 0) //字符串比较函数
printf(">");
else if (strcmp(s1, s2) == 0)
printf("=");
else
printf("<");
return 0;
}
第12关:字符串排序
本关任务:编写一个小程序,对一组字符串按字典序从小到大排序
#include <stdio.h>
#include <string.h>
int main()
{
//****补全代码****
//请用scanf读入字符串
char str[20][100], temp[100];
int n, i, j;
scanf("%d", &n);
for (i = 0; i <= n; i++)
scanf("%s", &str[i]);
for (i = 0; i < n - 1; i++)
{
for (j = i + 1; j < n; j++)
if (strcmp(str[j], str[i]) < 0)
{
strcpy(temp, str[i]); //换位
strcpy(str[i], str[j]);
strcpy(str[j], temp);
}
}
for (i = 0; i < n; i++)
printf("%s\n", str[i]);
return 0;
}
第13关:大整数加法
本关任务:编写一个小程序实现大整数加法
#include <stdio.h>
#include <string.h>
int main()
{
char s1[100], s2[100];
scanf("%s", s1); // 读入第一行字符串
scanf("%s", s2); // 读入第二行字符串
//****补全代码****
int m, n, len, i, j, k;
int a[100], b[100], c[100];
m = strlen(s1);
n = strlen(s2);
len = (m > n) ? m : n;
for (i = 0; i < m; i++)
a[i] = s1[i] - '0';
for (j = 0; j < n; j++)
b[j] = s2[j] - '0';
for (i = m - 1, j = n - 1, k = len - 1; i >= 0 && j >= 0; i--, j--, k--)
c[k] = a[i] + b[j];
for (; i >= 0; i--, k--)
c[k] = a[i];
for (; j >= 0; j--, k--)
c[k] = b[j];
for (k = len - 1; k > 0; k--)
{
if (c[k] > 9)
{
c[k] = c[k] % 10;
c[k - 1] += 1;
}
}
for (k = 0; k < len; k++)
{
printf("%d", c[k]);
}
return 0;
}