第11章 字符串和指针
示例代码:
示例代码11-1
/*
用数组实现的字符串和用指针实现的字符串
*/
#include <stdio.h>
int main(void)
{
char str[] = "ABC"; // 用数组实现的字符串
char *ptr = "123"; // 用指针实现的字符串
printf("str = \"%s\"\n", str);
printf("ptr = \"%s\"\n", ptr);
return (0);
}
示例代码11-2
/*
用数组实现的字符串和用指针实现的字符串的相同点
*/
#include <stdio.h>
int main(void)
{
int i;
char str[] = "ABC";
char *ptr = "123";
for (i = 0; str[i]; i++)
putchar(str[i]); // str[i]是第一个字符之后的第i个元素
putchar('\n');
for (i = 0; ptr[i]; i++)
putchar(ptr[i]); // str[i]是第一个字符之后的第i个元素
putchar('\n');
printf("str = \"%s\"\n", str); // str是指向第1个字符的指针
printf("ptr = \"%s\"\n", ptr); // ptr是指向第1个字符的指针
return (0);
}
示例代码11-3
/*
字符串赋值(?)
*/
#include <stdio.h>
int main(void)
{
char str[] = "ABC";
char *ptr = "123";
str = "DEF"; // 错误:不能这样赋值
ptr = "456"; // 正确:指向另一个字符串字面量
printf("str = \"%s\"\n", str);
printf("ptr = \"%s\"\n", ptr);
return (0);
}
示例代码11-4
/*
用数组实现的字符串和用指针实现的字符串(其二)
*/
#include <stdio.h>
int main(void)
{
char str[6] = "ABC"; // 用数组实现的字符串
char *ptr = "123"; // 用指针实现的字符串
printf("str = \"%s\"\n", str);
printf("ptr = \"%s\"\n", ptr);
return (0);
}
示例代码11-5
/*
用“数组实现的字符串”的数组和“用指针实现的字符串”的数组
*/
#include <stdio.h>
int main(void)
{
int i;
char st[3][6] = {"Turbo", "NA", "DOHC"};
char *pt[3] = {"12345", "12", "1234"};
for (i = 0; i < 3; i++)
printf("st[%d] = \"%s\"\n", i, st[i]);
for (i = 0; i < 3; i++)
printf("pt[%d] = \"%s\"\n", i, pt[i]);
return (0);
}
示例代码11-6
/*
判断字符串的长度(指针版)
*/
#include <stdio.h>
// 返回字符串s的长度
size_t str_length(const char *s)
{
size_t len = 0;
while (*s++)
len++;
return (len);
}
int main(void)
{
char st[100];
printf("请输入字符串:");
scanf("%s", st);
printf("字符串%s的长度为%u。\n", st, (unsigned)str_length(st));
return (0);
}
示例代码11-7
/*
复制字符串
*/
#include <stdio.h>
// 将字符串s复制到d
char *str_copy(char *d, const char *s)
{
char *t = d;
while (*d++ = *s++)
;
return (t);
}
int main(void)
{
char s1[128] = "ABCD";
char s2[128] = "EFGH";
printf("字符串s1:"); scanf("%s", s1);
str_copy(s2, s1);
puts("s1复制到了s2。");
printf("s1 = %s\n", s1);
printf("s2 = %s\n", s2);
return(0);
}
示例代码11-8
/*
复制字符串(误例)
*/
#include <stdio.h>
// 将字符串s赋值到d
char *str_copy(char *d, const char *s)
{
char *t = d;
while (*d++ = *s++)
;
return (t);
}
int main(void)
{
char str[128] = "ABCD";
char *ptr = "EFGH";
printf("字符串str:"); scanf("%s", str);
str_copy(ptr, str);
puts("str复制到了ptr。");
printf("str = %s\n", str);
printf("ptr = %s\n", ptr);
return(0);
}
示例代码11-9
// 返回字符串s的长度
size_t strlen(const char *s)
{
size_t len = 0;
while (*s++)
len++;
return (len);
}
示例代码11-10
// 将字符串s2添加到s1之后
char *strcat(char *s1, const char *s2)
{
char *tmp = s1;
while (*s1) s1++; // 前进到s1的末尾处
while (*s1++ = *s2++); // 循环复制直至遇到s2中的‘\0’
return (tmp);
}
// 将字符串s2的前n个字符复制到s1
char *strcat(char *s1, const char *s2, size_t n)
{
char *tmp = s1;
while (*s1) s1++; // 前进到s1的末尾处
while (n--)
if (!(*s1++ = *s2++)) break; // 遇到 ‘\0’就结束循环
*s1 = '\0'; // 在s1的末尾插入‘\0’
return (tmp);
}
示例代码11-11
// 将字符串s2添加到s1之后
char *strcat(char *s1, const char *s2)
{
char *tmp = s1;
while (*s1) s1++; // 前进到s1的末尾处
while (*s1++ = *s2++); // 循环复制直至遇到s2中的‘\0’
return (tmp);
}
// 将字符串s2的前n个字符复制到s1
char *strcat(char *s1, const char *s2, size_t n)
{
char *tmp = s1;
while (*s1) s1++; // 前进到s1的末尾处
while (n--)
if (!(*s1++ = *s2++)) break; // 遇到 ‘\0’就结束循环
*s1 = '\0'; // 在s1的末尾插入‘\0’
return (tmp);
}
示例代码11-12
// 比较字符串s1和s2
int strcmp(const char *s1, const char *s2)
{
while (*s1 == *s2) {
if (*s1 == '\0')
return (0); // 相等
s1++;
s2++;
}
return ((unsigned char)*s1 - (unsigned char)*s2);
}
// 比较字符串s1和s2的前n个字符
int strncmp(const char *s1, const char *s2, size_t n)
{
while (n && *s1 && *s2) {
if (*s1 != *s2) // 不相等
return ((unsigned char)*s1 - (unsigned char)*s2);
s1++;
s2++;
n--;
}
if (!n) return (0); // 相等
if (*s1) return (1); // s1 > s2
return (-1); // s1 < s2
}
示例代码11-13
// stoi函数的运行情况
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char str[] = "12345";
printf("str =\"%s\"\n", str);
printf("atoi(str) = %d\n", atoi(str));
return (0);
}
练习代码:
练习代码e11-1
/*
依次显示字符串中的字符 (不使用下标运算符)
*/
#include <stdio.h>
// 显示字符串(不换行)
void put_string(const char str[])
{
while (*str)
putchar(*str++);
}
int main(void)
{
char str[100];
printf("请输入字符串:");
scanf("%s", str);
put_string(str);
putchar('\n');
return (0);
}
练习代码e11-2
/*
编写如下函数,若字符串str中含有字符c(若含有多个,以先出现的为准),、
则返回指向该字符的指针,否则返回NULL。
*/
#include <stdio.h>
char *str_chr(const char *str, int c)
{
char *p = NULL;
while (c == *str) {
p = str;
str++;
}
return (p);
}
int main(void)
{
char str[100];
char c;
printf("请输入字符串:"); scanf("%s", str);
getchar(); // 清除缓存
printf("请输入要查找的字符:"); scanf("%c", &c);
printf("\n返回的指针地址是:%p。\n", str_chr(str, c));
return (0);
}
练习代码e11-3
/*
编写如下函数,不使用下标运算符,返回字符串str中字符c的个数
(若不存在则为0)。
*/
#include <stdio.h>
int str_chnum(const char *str, char c)
{
int n = 0;
while (*str) {
if (c == *str++) n++;
}
return (n);
}
int main(void)
{
char str[100];
char c;
printf("请输入字符串:"); scanf("%s", str);
getchar(); // 清除缓存
printf("请输入要查找的字符:"); scanf("%c", &c);
printf("\n字符串\"%s\"中含有%d个字符\'%c\'。\n", str, str_chnum(str, c), c);
return (0);
}
练习代码e11-4
/*
不使用下标运算符,写出与代码清单9-13中的str_toupper函数
和str_tolower函数功能相同的函数。
*/
#include <ctype.h>
#include <stdio.h>
// 将字符串中的英文字符转换为大写字母
void str_toupper(char *str)
{
while (*str)
*str = toupper(*str++);
}
// 将字符串中的英文字符转换为小写字母
void str_tolower(char *str)
{
while (*str)
*str = tolower(*str++);
}
int main(void)
{
char str[100];
printf("请输入字符串:");
scanf("%s", str);
str_toupper(str);
printf("大写字母:%s\n", str);
str_tolower(str);
printf("小写字母:%s\n", str);
return (0);
}
练习代码e11-5
/*
不使用下标运算符,编写如下函数,删除字符串str中的所有数字字符
(例如将传入的“AB1C9”变为“ABC”)
*/
#include <stdio.h>
// 返回字符串长度
int length(const *str)
{
int len = 0;
while (*str++) len++;
return (len);
}
// 去除字符串中的数字
void del_digit(char *s)
{
char *p = s;
while (*p)
if ((*p >= '0') && (*p <= '9'))
p++;
else
*s++ = *p++;
*s = '\0';
}
int main()
{
char s[100];
printf("请输入字符串:"); scanf("%s", s);
printf("输入的字符串是:%s。\n", s);
del_digit(s);
printf("去数的字符串是:%s。\n", s);
return (0);
}
练习代码e11-6
/*
编写如下函数,实现与库函数atoi、atol、atof相同的功能。
*/
int len(const char *nptr)
{
int len = 0;
while (*nptr++) len++;
return (len);
}
double power_10(long n)
{
double p = 1;
if (n > 0)
while (--n) p *= 10;
else if (n < 0)
while (n++) p /= 10;
else
p = 1;
return p;
}
// 字符串转换为整形
int strtoi(const char *nptr)
{
int n = len(nptr);
int num = 0;
while (*nptr) {
num += (*nptr - '0') * power_10(n--);
nptr++;
}
return (num);
}
// 字符串转换为长整形
long strtol(const char *nptr)
{
long n = len(nptr);
long num = 0;
while (*nptr) {
num += (*nptr - '0') * power_10(n--);
nptr++;
}
return (num);
}
// 字符串转换为浮点形
double strtof(char *nptr)
{
char *p1 = nptr;
char *p2;
char *p3;
int n1 = 0;
int n2 = 0;
int n3;
double num = 0.0;
while (*p1 != '.') {
n1++;
p1++;
}
p2 = ++p1;
p3 = p2;
while (*p3++) n2--;
while (*nptr != '.') {
num += (*nptr - '0') * power_10(n1--);
nptr++;
}
n3 = n2;
while (*p2) {
num += (*p2 - '0') * power_10(n3 - ++n2);
p2++;
}
return (num);
}
int main(void)
{
char s[100];
printf("请输入一个整数:"); scanf("%s", s);
printf("\n转换成整形:%d\n", strtoi(s));
printf("\n请输入一个长整数:"); scanf("%s", s);
printf("\n转换成长整形:%ld\n", strtol(s));
printf("\n请输入一个浮点数:"); scanf("%s", s);
printf("\n转换成浮点形:%lf\n", strtof(s));
return (0);
}