前言
本文为业余学习《明解C语言入门篇》的记录,包含代码清单和练习题。
开始学习时间:2022年8月21日
+++++++++++++++++++++++++++++++
第1章 初识C语言
第2章 运算和数据类型
第3章 分支结构程序
第4章 程序的循环控制
第5章 数组
第6章 函数
第7章 基本数据类型
第8章 动手编写各种程序吧
第9章 字符串的基本知识
第10章 指针
第11章 字符串和指针
第12章 结构体
第13章 文件处理
+++++++++++++++++++++++++++++++
第11章 字符串和指针
11-1 字符串和指针
代码清单 11-1
//用数组和指针实现的字符串
#include <stdio.h>
int main()
{
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()
{
char s[]="ABC";
printf("s = \"%s\"\n",s);
s="DEF";
printf("s = \"%s\"\n",s);
return 0;
}
代码清单 11-3
//用指针实现字符串的改写
#include <stdio.h>
int main()
{
char *p="123";
printf("p = \"%s\"\n",p);
p="456";
printf("p = \"%s\"\n",p);
return 0;
}
练习 11-1
//用指针实现字符串的改写
#include <stdio.h>
int main()
{
char *p="123";
printf("p = \"%s\"\n",p);
p="456"+1;
printf("p = \"%s\"\n",p);
/*
输出56,因为p指向字符串数组第一个元素,+1等于将指针指向后一个元素地址。
与printf("p = \"%s\"\n",p+1)效果相同。
*/
return 0;
}
代码清单 11-4
//字符串数组
#include <stdio.h>
int main()
{
char s[][5]={"LISP","C","Ada"};
char *p[]={"PAUL","X","MAC"};
int i;
for(i=0;i<3;i++)
{
printf("s = \"%s\"\n",s[i]);
}
for(i=0;i<3;i++)
{
printf("p = \"%s\"\n",p[i]);
}
return 0;
}
练习 11-2
//求字符串数组中字符串的个数
#include <stdio.h>
#define str_n(arr) ((sizeof(arr))/(sizeof(arr[0])))
int main()
{
char s[][5]={"LISP","C","Ada"};
char *p[]={"PAUL","X","MAC","PC","Linux"};
int i;
int sx=str_n(s);
int px=str_n(p);
for(i=0;i<sx;i++)
{
printf("s = \"%s\"\n",s[i]);
}
for(i=0;i<px;i++)
{
printf("p = \"%s\"\n",p[i]);
}
return 0;
}
11-2 通过指针操作字符串
代码清单 11-5
//判断字符串的长度(使用指针遍历)
#include <stdio.h>
int str_len(char *ptr);
int main()
{
char str[128];
printf("请输入一个字符串:");
scanf("%s",str);
printf("字符串%s的长度是%d。\n",str,str_len(str));
return 0;
}
int str_len(char *ptr)
{
int len=0;
while(*ptr++)
{
len++;
}
return len;
}
代码清单 11-6
//复制字符串
#include <stdio.h>
char* str_copy(char *d,const char*s);
int main()
{
char str[128]="ABC";
char temp[128];
printf("str = \"%s\"\n",str);
printf("请输入要复制的字符串:");
scanf("%s",temp);
str_copy(str,temp);
printf("str = \"%s\"\n",str);
return 0;
}
char* str_copy(char *d,char*s)
{
char *t=d;
while(*d++=*s++)
{
;
}
return t;
}
代码清单 11-7
//复制字符串(误例)
//在VC++6中运行会卡滞几秒后直接结束,不打印ptr字符串。
#include <stdio.h>
char* str_copy(char *d,const char *s);
int main()
{
char *ptr="1234";
char temp[128];
printf("ptr = \"%s\"\n",ptr);
printf("请输入要复制的字符串:");
scanf("%s",temp);
str_copy(ptr,temp);
printf("ptr = \"%s\"\n",ptr);
return 0;
}
char* str_copy(char *d,const char *s)
{
char *t=d;
while(*d++=*s++)
{
;
}
return t;
}
练习 11-3
//改写代码清单11-6,将函数的调用作为printf函数的实参
#include <stdio.h>
char* str_copy(char *d,const char *s);
int main()
{
char str[128]="ABC";
char temp[128];
printf("str = \"%s\"\n",str);
printf("请输入要复制的字符串:");
scanf("%s",temp);
printf("str = \"%s\"\n",str_copy(str,temp));
return 0;
}
char* str_copy(char *d,const char *s)
{
char *t=d;
while(*d++=*s++)
{
;
}
return t;
}
11-3 字符串处理库函数
代码清单 11-8
//返回字符串s的长度
#include <stdio.h>
#include <string.h>
size_t str_len(const char *ptr);
int main()
{
char str[]="String";
printf("字符串%s的长度为%d。\n",str,strlen(str)); //库函数
printf("字符串%s的长度为%u。\n",str,str_len(str)); //案例函数测试
return 0;
}
size_t str_len(const char *ptr)
{
size_t len=0;
while(*ptr++)
{
len++;
}
return len;
}
练习 11-4
//不使用下标,编写函数,显示字符串s
#include <stdio.h>
void put_string(const char *ptr);
int main()
{
char str[128];
printf("请输入一个字符串:");
scanf("%s",str);
printf("str = \"");
put_string(str);
puts("\"");
return 0;
}
void put_string(const char *ptr)
{
while(*ptr)
{
putchar(*ptr++);
}
}
练习 11-5
//不使用下标,编写函数返回字符串s中c的个数,若不存在则返回0
#include <stdio.h>
int char_c(const char *ptr,int c);
int main()
{
char str[128];
char cx;
printf("请输入一个字符串:"); scanf("%s",str);
fflush(stdin);
printf("请输入要查找的字符:"); scanf("%c",&cx);
printf("字符串\"%s\"中字符'c'的个数为%d。\n",str,char_c(str,cx));
return 0;
}
int char_c(const char *ptr,int c)
{
int cn=0;
while(*ptr)
{
if(*ptr==c)
{
cn++;
}
ptr++;
}
return cn;
}
练习 11-6
//不使用下标,编写函数,返回指向字符串s中第一个字符c的指针,否则返回空指针
#include <stdio.h>
char* str_chr(const char *ptr,int c);
int main()
{
char str[128];
char cx;
printf("请输入字符串:");
scanf("%s",str);
fflush(stdin);
printf("请输入要查找的字符:");
scanf("%c",&cx);
printf("指针%#x。\n",str_chr(str,cx));
return 0;
}
char* str_chr(const char *ptr,int c)
{
while(*ptr)
{
if(*ptr==c)
{
return ptr;
}
ptr++;
}
return NULL;
}
代码清单 11-9
//使用strcpy函数的例子
#include <stdio.h>
#include <string.h>
char *str_cpy(char *s1,const char *s2);
char *str_ncpy(char *s3,const char *s4,size_t n);
int main()
{
char str[128];
char strcpy_X[128]={0};
char str_cpy_X[128]={0};
char strncpy_X[128]={0};
char str_ncpy_X[128]={0};
size_t n;
printf("str = "); scanf("%s",str);
printf("n = "); scanf("%u",&n);
printf("strcpy = %s\n",strcpy(strcpy_X,str));
printf("str_cpy = %s\n",str_cpy(strcpy_X,str));
printf("strncpy = %s\n",strncpy(strncpy_X,str,n));
printf("str_ncpy = %s\n",str_ncpy(strncpy_X,str,n));
return 0;
}
char *str_cpy(char *s1,const char *s2)
{
char *temp=s1;
while(*s1++=*s2++)
{
;
}
return temp;
}
char *str_ncpy(char *s3,const char *s4,size_t n)
{
char *temp=s3;
while(n)
{
if(!(*s3++=*s4++))
{
break;
}
n--;
}
while(n--)
{
*s3++='\0';
}
return temp;
}
代码清单 11-10
//使用strcat函数的例子
#include <stdio.h>
#include <string.h>
char *str_cat(char *s1,const char *s2);
char *str_ncat(char *s1,const char *s2,size_t n);
int main()
{
char str[128];
char str1[128];
char str2[128];
size_t n;
printf("str1 = "); scanf("%s",str1);
printf("str2 = "); scanf("%s",str2);
printf("n = "); scanf("%u",&n);
strcpy(str,str1);
printf("strcat = %s\n",strcat(str1,str2));
strcpy(str1,str);
printf("strncat = %s\n",strncat(str1,str2,n));
strcpy(str1,str);
printf("str_cat = %s\n",str_cat(str1,str2));
strcpy(str1,str);
printf("str_ncat = %s\n",str_ncat(str1,str2,n));
return 0;
}
char *str_cat(char *s1,const char*s2)
{
char *temp=s1;
while(*s1)
{
s1++;
}
while(*s1++=*s2++)
{
;
}
return temp;
}
char *str_ncat(char *s1,const char *s2,size_t n)
{
char *temp=s1;
while(*s1)
{
s1++;
}
while(n--)
{
if(!(*s1++=*s2++))
{
break;
}
}
*s1='\0';
return temp;
}
代码清单 11-11
//比较字符串大小
#include <stdio.h>
#include <string.h>
int str_cmp(const char *ptr1,const char *ptr2);
int str_ncmp(const char *ptr1,const char *ptr2,size_t n);
int main()
{
char str1[128];
char str2[128];
int i,j,n;
printf("str1 = "); scanf("%s",str1);
printf("str2 = "); scanf("%s",str2);
printf("n = "); scanf("%d",&n);
i=str_cmp(str1,str2);
j=str_ncmp(str1,str2,n);
printf("比较结果:");
puts(i==0?"str1=str2。":i<0?"str1<str2。":"str1>str2。");
printf("前%d位字符比较结果:",n);
puts(j==0?"str1=str2。":j<0?"str1<str2。":"str1>str2。");
return 0;
}
int str_cmp(const char *ptr1,const char *ptr2)
{
while(*ptr1==*ptr2)
{
if(*ptr1=='\0')
{
return 0;
}
ptr1++;
ptr2++;
}
return (unsigned char)*ptr1 - (unsigned char)*ptr2;
}
int str_ncmp(const char *ptr1,const char *ptr2,size_t n)
{
while(n&&*ptr1&&*ptr2)
{
if(*ptr1 != *ptr2)
{
return (unsigned char)*ptr1 - (unsigned char)*ptr2;
}
ptr1++;
ptr2++;
n--;
}
if(!n)
{
return 0;
}
if(*ptr1)
{
return 1;
}
return -1;
}
代码清单 11-12
//使用atoi函数的例子
#include <stdio.h>
#include <stdlib.h>
int main()
{
char str[128];
printf("请输入字符串:");
scanf("%s",str);
printf("转换为整数后为%d。\n",atoi(str));
return 0;
}
练习 11-7
//不使用下标运算符,实现代码清单9-11的str_toupper和str_tolower函数
#include <stdio.h>
#include <ctype.h>
void str_toupper(char *ptr);
void str_tolower(char *ptr);
int main()
{
char str[128];
printf("str = "); scanf("%s",str);
str_toupper(str);
printf("转换成大写为%s。\n",str);
str_tolower(str);
printf("转换成小写为%s。\n",str);
return 0;
}
void str_toupper(char *ptr)
{
while(*ptr)
{
*ptr=toupper(*ptr);
ptr++;
}
}
void str_tolower(char *ptr)
{
while(*ptr)
{
*ptr=tolower(*ptr);
ptr++;
}
}
练习 11-8
//编写函数,删除字符串str中的数字字符
#include <stdio.h>
void del_digit(char *ptr);
int main()
{
char str[128];
printf("str = ");
scanf("%s",str);
printf("字符串%s删除数字后为\"",str);
del_digit(str);
puts("\"。");
return 0;
}
void del_digit(char *ptr)
{
char temp[128];
char *p=temp;
while(*ptr)
{
if(*ptr<'0' || *ptr>'9')
{
*p=*ptr;
p++;
}
ptr++;
}
*p='\0';
printf("%s",temp);
}
练习 11-9
//使用strlen(),strcpy(),strncpy(),strcat(),strncat(),strcmp()和strncmp函数编写程序
#include <stdio.h>
#include <string.h>
void str_renull(char *ptr);
int main()
{
char str1[128];
char str2[128];
char temp[128];
int n;
printf("str1 = "); scanf("%s",str1);
printf("str2 = "); scanf("%s",str2);
printf("n = "); scanf("%d",&n);
printf("str1长度为%d。\n",strlen(str1));
printf("str2长度为%d。\n",strlen(str2));
printf("temp复制str1(all) = \"%s\"。\n",strcpy(temp,str1));
str_renull(temp);
printf("temp复制str2(%d) = \"%s\"。\n",n,strncpy(temp,str2,n));
str_renull(temp);
strcpy(temp,str1);
printf("str1(all) & str2(all) = \"%s\"。\n",strcat(str1,str2));
strcpy(str1,temp);
printf("str1 & str2(%d) = \"%s\"。\n",n,strncat(str1,str2,n));
strcpy(str1,temp);
printf("str1(all) - str2(all) = %d。\n",strcmp(str1,str2));
printf("str1(%d) - str2(%d) = %d。\n",n,n,strncmp(str1,str2,n));
return 0;
}
void str_renull(char *ptr)
{
while(*ptr)
{
*ptr='\0';
ptr++;
}
}
练习 11-10
//编写函数,实现atoi()、atol()、atof()三个函数的功能
#include <stdio.h>
#include <limits.h>
int StrToInt(const char *nptr);
long StrToLong(const char *nptr);
double StrToDouble(const char *nptr);
int main()
{
char str_int[128];
char str_long[128];
char str_double[128];
printf("str_int = "); scanf("%s",str_int);
printf("str_long = "); scanf("%s",str_long);
printf("str_double = "); scanf("%s",str_double);
printf("\"%s\" => int型 = %d。\n",str_int,StrToInt(str_int));
printf("\"%s\" => long型 = %ld。\n",str_long,StrToLong(str_long));
printf("\"%s\" => double型 = %.10lf。\n",str_double,StrToDouble(str_double));
return 0;
}
int StrToInt(const char *nptr)
{
int result=0;
int sign=1;
if(*nptr=='-')
{
sign=-1;
nptr++;
}
if(*nptr=='+')
{
nptr++;
}
while(*nptr)
{
result=result*10+(*nptr)-'0';
nptr++;
}
return result*sign;
}
long StrToLong(const char *nptr)
{
long result=0;
int sign=1;
if(*nptr=='-')
{
sign=-1;
nptr++;
}
if(*nptr=='+')
{
nptr++;
}
while(*nptr)
{
result=result*10+(*nptr)-'0';
nptr++;
}
return result*sign;
}
double StrToDouble(const char *nptr)
{
double result=0.0;
double n=1.0;
int sign=1;
if(*nptr=='-')
{
sign=-1;
nptr++;
}
if(*nptr=='+')
{
nptr++;
}
while(*nptr)
{
if(*nptr=='.')
{
nptr++;
break;
}
result=result*10+(*nptr)-'0';
nptr++;
}
while(*nptr)
{
n/=10.0;
result=result+((*nptr)-'0')*n;
nptr++;
}
return result*sign;
}
总结
summary
//字符串和字符串数组
#include <stdio.h>
#include <ctype.h>
#define put_str_in(s) (put_str(s),putchar('\n'))
char *str_cpy_toupper(char *d,const char *s);
void put_str(const char *s);
int main()
{
int i;
char s[123],t[128];
char a[]="CIA";
char *p="FBI";
char a2[][5]={"LISP","C","Ada"};
char *p2[]={"PAUL","X","MAC"};
printf("字符串s = "); scanf("%s",s);
printf("转换为大写并复制到了数组t。\n");
printf("字符串t = %s\n",str_cpy_toupper(t,s));
printf("a = "); put_str_in(a);
printf("p = "); put_str_in(p);
for(i=0;i<sizeof(a2)/sizeof(a2[0]);i++)
{
printf("a2[%d] = ",i); put_str_in(a2[i]);
}
for(i=0;i<sizeof(p2)/sizeof(p2[0]);i++)
{
printf("p2[%d] = ",i); put_str_in(p2[i]);
}
return 0;
}
char *str_cpy_toupper(char *d,const char *s)
{
char *temp=d;
while(*d++=toupper(*s++))
{
;
}
return temp;
}
void put_str(const char *s)
{
putchar('\"');
while(*s)
{
putchar(*s++);
}
putchar('\"');
}