[C++系列] C语言基础 day11 字符串
in C/C++ with 0 comment

[C++系列] C语言基础 day11 字符串

in C/C++ with 0 comment

关于从零C++系列,从C到C++,从简单到容易,从基础到项目,这一系列将会记录长达约半年的C++学习历程,贯穿标准C语言(包含指针,c标准库,堆内存分配,IO等),linux下的C语言开发,linux kernel,shell,C++,算法与数据结构,linux下C++开发,模版和STL,QT,ORACLE数据库,win32核心编程 windows api,网络编程,MFC,其中贯穿多个项目,多个小项目和几个大项目。一系列笔记,分享是一种精神。希望这套笔记能帮助和我一样在C++路上摸爬滚打的人。共勉。

#练习

编写函数把一个数组里的所有存储区的内容前后颠倒,假设数组里原有的内容是1,2,3,4,5
颠倒后的内容是 5,4,3,2,1
要求使用指针编写函数。

/*
*指针练习
**/
#include<stdio.h>
int *reverse(int *p_num,int size){
int *p_start=p_num;
int *p_end = p_num+size-1;
//p_start指针永远和配对存储区里前面的存储区捆绑,p_end和后面的存储区捆绑。
int tmp = 0;
while(p_start < p_end){//两个指针没有相遇也没有交错
tmp = *p_start;
*p_start = *p_end;
*p_end = tmp;
p_start++;
p_end--;
}
return p_num;
}
int main(){
int arr[] = {1,2,3,4,5};
int *p_num1 = reverse(arr,5);
for(int i = 0;i<= 4;i++){
printf("%d\n",*(p_num1+i));
}
return 0;
}

#字符串

C语言中要求所有文字信息必须记录在一组连续的字符类型的存储区里
所有文字信息必须以 “0"字符作为结尾,这个字符的ASCII就是数字“0”

符合以上这两种特征的东西叫做字符串。
字符串中“0”字符前面的部分是有效字符。
所有的自负串都可以使用字符类型指针表示。

#两种字符串:

字符串字面值是一种字符串,用两个双引号中间的一组字符表示(例如“sdf”,“萨sts”等);
编译器在编译的时候自动在字符串字面值末尾追加一个“0”字符。
编译器会把字符串字面值替换成第一个字符所在的存储区地址

字符串字面值内容在程序执行的过程中是不可以修改的。
多个内容一样的字符串字面值其实是同一个。
程序中多个并列的字符串字面值会被合并成一个。

字符数组也可以用来表示存储区。
只有包含了’0’字符的字符数组才可以当作字符串使用。
可以在声明字符数组的时候用字符串字面值进行初始化,这个时候编译器把字符串字面值最后的’0’字符也初始化到字符数组里。

#include<stdio.h>
int main(){
printf("%c\n",*"abc");//编译器会把字符串字面值替换成第一个字符所在的存储区地址
printf("%p\n","abc");//多个内容一样的字符串字面值其实是同一个。
printf("%p\n","abc");//多个内容一样的字符串字面值其实是同一个。
printf("%d\n",*("abc"+3));//编译器在编译的时候自动在字符串字面值末尾追加一个“\0”字符。
//*"abc" = "z"; 错误 //字符串字面值内容在程序执行的过程中是不可以修改的。
printf("%p\n","ab""c");//程序中多个并列的字符串字面值会被合并成一个。
char str[] = "abc";
printf("%d\n",str[3]);
printf("%s\n","abc");
return 0;
}

字符数组里的字符串内容可以修改。

在printf函数调用语句里使用%s做占位符把字符串里的所有字符都显示在屏幕上。
程序里不可以使用操作符操作字符串。
C语言中提供了一种标准函数用来操作字符串。
为了使用这些标准函数需要包含string.h头文件。
strlen。用来统计字符串里有效字符的个数。 和sizeof的结果不同。

Strcat 用来合并两个字符串的内容。

        第一个参数不可以是字符串字面值。
        这个函数有可能修改不属于数组的存储区,这会导致严重错误。

Strncat 功能和strcat类似

        这个函数可以把后一个字符串的前n个字符合并到前一个字符串的末尾。

Strcmp 用来比较两个字符串的大小。

          根据ASCII码比较字符串的大小。
           如果前一个字符串大,就返回1,如果后一个字符串大,就返回-1,如果一样大就返回0;

Strncmp 只比较两个字符串的前n个字符。

#include<stdio.h>
#include<string.h>
int main(){
char str[10] = "abc";
printf("%lu\n",strlen(str));
printf("%lu\n",sizeof(str));
printf("%s\n",strcat(str,"def"));
printf("%s\n",str);
printf("%s\n",strncat(str,"defgh",3));
printf("%d\n",strcmp("abc","abd"));
printf("%d\n",strncmp("abc","abd",2));
return 0;
}

strcpy 用来把一个字符串内容复制到数组里。
这个函数可能修改不属于数组的存储区,这可能造成严重后果。
Strncpy. 功能和strcpy类似,可以只复制字符串的前n个字符。

            有可能不会复制最后的“\0”字符。

Memset 用来把字符数组里前n个存储区的内容设置成同一字符。
strstr 用来在一个大字符串中查找一个小字符串的位置。返回改位置的指针。

               如果找不到就用null做返回值 

一下两个函数不需要包含string.h头文件。

  1. 把数字转换成一组字符并形成字符串,把这个字符串记录到字符数组里。
    Scanf。 从字符串里获得数字并记录到存储区里。

一下两个函数可以把字符串里的数字转换成数字类型。
为了使用这两个函数需要包含stdlib.h头文件。
atoi 用来把数字开头的字符串转换成整数类型。

  1. 用来把浮点数开头的字符串转换成双精度浮点类型。

可以在scanf函数调用语句里使用%s占位符从键盘得到一个字符串并记录到数组里。
采用这种办法会产生严重错误

fgets也可以从键盘得到一个字符串并记录到字符数组里,这个函数可以避免scanf函数的问题。
这个函数需要三个参数:
1,数组名称
2,数组里存储区个数
3,用stdin表示键盘
如果输入的内容不能把数组充满,就把最后输入的换行字符也读入到数组里。
如果用户输入的内容超过数组的容量就把后面的部分留在输入缓存区里。

应该在每次使用fgets函数从键盘得到字符串以后清理输入缓冲区里可能存在的多余数据。

Ps: 可以使用 scarf(“%1”); scarf(“%c");清理掉上次输入后残留的缓冲区内容。
应该在确保数组里没有’n’换行字符的时候再清理输入缓冲区里的多余数据。

#include<stdio.h>
#include<string.h>
int main(){
char str[10] = {0};
printf("输入一个字符串:");
fgets(str,10,stdin);
if(strlen(str)==9 && str[8] != '\n'){
scanf("%*[^\n]");
scanf("%*c");
}
printf("%s\n",str);
printf("输入一个字符串:");
fgets(str,10,stdin);
printf("%s\n",str);
return 0;
}

#练习

编写程序从键盘得到多个考试成绩,按照如下格式合并成一个字符串并把结果显示在屏幕上。

10,20,30,40,50

考试成绩的个数不超过10个

#include<stdio.h>
#include<string.h>
int main(){
int grade = 0;
char buf[50] = {0},i=0,tmp[10]={0};
while(1){
printf("请输入成绩:");
//arr[i]=atoi(fgets(arr,10,stdin));
scanf("%d",&grade);
if(grade < 0){
break;
}
sprintf(tmp,"%d,",grade);//把当前考试成绩转换成字符串。
strcat(buf,tmp); // 把单个考试成绩转换得到的字符串合并到数组末尾
}
buf[strlen(buf)-1] = 0;
printf("结果是%s\n",buf);

}

练习

编写程序从以上格式的字符串里拆分出所有考试成绩并记录到数组里。
最终把数组里所有考试成绩显示在屏幕上。

#include<stdio.h>
#include<string.h>
int main(){
int arr[10] ={0},pos = 0;
char buf[50] = {0};
int *p_grade = buf;
printf("输入字符串:");
fgets(buf,50,stdin);
if(strlen(buf)==49 && buf[48] !='\n'){
scanf("%*[^\n]");
scanf("%*c");
}
while(1){
arr[pos]=atoi(p_grade);
pos++;
p_grade = strstr(p_grade,',');//从当前考试成绩的开始位置向后找第一个逗号的位置。
p_grade++;//找到后一个考试成绩的开始位置。
if(!p_grade){
break;
}
}
for(int i=0;i<=pos-1;i++){
printf("%d ",arr[i]);
}

printf("\n");
return 0;
}

预习


  1. n
Responses