文章目录
1 字符串
C语言的字符串都被存储在char类型的数组中
数组末尾位置\0字符为空字符,C语言用它标记字符串的结束。空字符不是数字0,它是非打印字符,其ASCII码值是(或等价于)0。这意味着数组的容量必须至少比待存储字符串中的字符数多1,即char[40],只能存储39个字符,剩下一个给空字符。
注意:读取空字符的依据是遇到了第1个空白(空格、制表符或换行符)时就不再读取输入
#include<stdio.h>
int main(void) {
char name[40] = "vincent";
printf("%s", name);
}
// 两者的主要区别是:数组名heart是常量,而指针名head是变量
char heart[] = "I love Tillie!";
const char *head = "I love Millie!";
2 strlen()函数
strlen()
函数给出字符串中的字符长度
#include<stdio.h>
#include<string.h>
#define PRAISE "You are an extraordinary being."
int main(void) {
char name[40] = "Serendipity Chance";
printf("%s", name);
// strlen()返回11个字符,sizeof()返回40个存储单元
// strlen()也遵循字符串读取规则,所以只读取了Seredipity
printf("%zd, %zd", strlen(name), sizeof(name));
}
3 strcat()函数
strcat()
函数用于拼接字符串,类型是char*,返回第1个参数,即拼接第2个字符串后的第1个字符串的地址
#include<stdio.h>
#include<string.h>
#define SIZE 80
char * s_gets(char *st, int n);
int main(void) {
char flower[SIZE];
char addon[] = "s smell like old shoes";
puts("What is your favorite flower?");
if (s_get(flower, SIZE)) {
// 将flower输入的字符串再拼接addon字符串
strcat(flower, addon);
puts(flower);
puts(addon);
} else {
puts("End of file encountered!");
}
return 0;
}
char * s_gets(char *st, int n) {
char *ret_val;
int i = 0;
ret_val = fgets(st, n, stdin);
if (ret_val) {
while (st[i] != '\n' && st[i] != '\0')
i++;
if (st[i] == '\n')
st[i] = '\0';
else
while (getchar() != '\n')
continue;
}
return ret_val;
}
4 strncat()函数
strcat()
函数无法检查第1个数组是否能容纳第2个字符串,需要通过strlen()函数查看数组的长度确定是否能插入足够的字符串,注意需要加1个长度存放末尾空字符。
strncat()函数的第3个参数指定了最大添加字符数
#include<stdio.h>
#include<string.h>
#define SIZE 30
#define BUGSIZE 13
char * s_gets(char *st, int n);
int main(void) {
char flower[SIZE];
char bug[BUGSIZE];
char addon[] = "s smell like old shoes.";
int available;
puts("What is your favorite flower?");
s_gets(flower, SIZE);
if ((strlen(flower) + strlen(addon) + 1) <= SIZE) {
strcat(flower, addon);
}
puts(flower);
puts("What is your favorite bug?");
s_gets(bug, addon, BUGSIZE);
available = BUGSIZE - strlen(bug) - 1;
strncat(bug, addon, available);
return 0;
}
char * s_gets(char *st, int n) {
char *ret_val;
int i = 0;
ret_val = fgets(st, n, stdin);
if (ret_val) {
while (st[i] != '\n' && st[i] != '\0')
i++;
if (st[i] == '\n')
st[i] = '\0';
else
while (getchar() != '\n')
continue;
}
return ret_val;
}
输出:
What is your favorite flower?
Rose
Roses smell like old shoes.
What is your favorite bug?
Aphid
Aphids smell // available=7,拼接addon后七位字符后结束
5 strcmp()函数
strcmp()
函数用于对比字符串是否相同。函数返回值为字符之间ASCII码的差值,一般情况下只需要知道返回值如果为0则相同,非0则不相同。
#include<stdio.h>
#include<string.h>
#define ANSWER "Grant"
#define SIZE 40
char * s_gets(char *st, int n);
int main(void) {
char try[SIZE];
puts("Who is buried in Grant's tomb?");
s_gets(try, SIZE);
// 输入不相同,继续输入直到相同
while (strcmp(try, ANSWER)) {
puts("No, that's wrong.Try again");
s_gets(try, SIZE);
}
puts("That's right!");
return 0;
}
char * s_gets(char *st, int n) {
char *ret_val;
int i = 0;
ret_val = fgets(st, n, stdin);
if (ret_val) {
while (st[i] != '\n' && st[i] != '\0')
i++;
if (st[i] == '\n')
st[i] = '\0';
else
while (getchar() != '\n')
continue;
}
return ret_val;
}
6 strncmp()函数
strcmp()
函数比较字符串中的字符,直到发现不同的字符为止;strncmp()
函数在比较字符串时,可以比较到字符不同的地方,也可以只比较到第3个参数指定的字符数后停止。
#include<stdio.h>
#include<string.h>
#define LISTSIZE 6
int main(void) {
const char *list[LISTSIZE] = {
"astronomy", "astounding",
"astrophysics", "ostracize",
"astersm", "astrophobia"
};
int count = 0;
int i;
for (int i = 0; i < LISTSIZE; i++) {
// 对比字符数组元素,只对比前5个字符是否相同
if (strncmp(list[i], "astro", 5) == 0) {
printf("Found:%s\n", list[i]);
count++;
}
}
return 0;
}
7 strcpy()和strncpy()函数
strcpy()
和 strncpy()
都是复制字符串,strcpy()函数返回char*类型第1个参数的值,即一个字符的地址;strncpy()函数的第3个参数可以指明拷贝的最大字符数。
#include<stdio.h>
#include<string.h>
#define SIZE 40
#define TARGETSIZE 7
#define LIM 5
char * s_gets(char *st, int n);
int main(void) {
char qwords[LIM][SIZE];
char temp[SIZE];
int i = 0;
printf("Enter %d words beginning with q:\n", LIM);
// 读取5次,每次最多读入40个字符,首字符是'q'则复制到temp
while (i < LIM && s_gets(temp, SIZE)) {
if (temp[0] != 'q')
printf("%s doesn't begin with q!\n", temp);
else {
// 拷贝输入的字符串
strcpy(qwords[i], temp);
// 拷贝输入字符串的前6位,最后一位留给空字符
// strncpy(qwords[i], temp, TARGETSIZE - 1);
// qwords[i][TARGETSIZE - 1] = '\0';
i++;
}
}
puts("Here are the words accepted");
for (int i = 0; i < LIM; i++)
puts(qwords[i]);
return 0;
}
char * s_gets(char *st, int n) {
char *ret_val;
int i = 0;
ret_val = fgets(st, n, stdin);
if (ret_val) {
while (st[i] != '\n' && st[i] != '\0')
i++;
if (st[i] == '\n')
st[i] = '\0';
else
while (getchar() != '\n')
continue;
}
return ret_val;
}
8 sprintf()函数
sprintf()
函数可以将终端输入的字符串写入字符数组中,而 printf()
是打印到终端
#include<stdio.h>
#define MAX 20
char * s_gets(char *st, int n);
int main(void) {
char first[MAX];
char last[MAX];
char formal[2 * MAX + 10];
double prize;
puts("Enter your first name:");
s_gets(first, MAX);
puts("Enter your last name:");
s_gets(last, MAX);
puts("Enter your prize money:");
scanf("%lf", &prize);
sprintf(formal, "%s, %-19s: $%6.2f\n", last, first, prize);
puts(formal);
return 0;
}
9 其他字符串函数
9 定义常量
#define
可以预定义需要使用的数据
const
关键字声明数据不可更改
10 printf()和scanf()
#include<stdio.h>
#define PAGES 959
int main(void) {
// *959*
printf("*%d*\n", PAGES);
// *959* 因为待打印有3位数字,所以字段宽度自动扩大
printf("*%2d*\n", PAGES);
// * 959* 7个空格和3个数字
printf("*%10d*\n", PAGES);
// *959 * 3个数字和7个空格
printf("*%-10d*\n", PAGES);
// "\"和回车键组合断行
// 输出:Here's another way to print a long string.
// 注意:第二行必须从最左边开始,否则缩进多少就会增加进字符串中
printf("Here's another way to print a \
long string.\n");
// 输出:Here's the newest way to print a long string.
printf("Here's the newest way to print a "
"long string.\n");
}
#include<stdio.h>
int main(void) {
int age;
float assets;
char pet[30];
// 读取基本变量类型的值,在变量名加上一个&
// 把字符串读入字符数组中,不需要使用&
scanf("%d %f", &age, &assets);
scanf("%s", pet);
printf("%d %.2f %s\n", age, assets, pet);
}
11 sizeof运算符和size_t类型
sizeof
运算符以字节为单位返回运算对象的大小。
#include<stdio.h>
int main(void) {
int n = 0;
size_t intsize;
// size_t类型是一个无符号整数类型
intsize = sizeof(int); // sizeof()返回size_t类型
printf("n = %d, n has %zd bytes; all ints have %zd bytes.\n", n, sizeof(n), intsize);
return 0;
}