首页 > 代码库 > 听翁恺老师mooc笔记(8)--字符串2

听翁恺老师mooc笔记(8)--字符串2

  字符串的赋值

  字符串的输入与输出

  对C语言的基础类型,比如int、double等类型,scanf、printf有专门的格式转换,而对字符串,scanf、printf使用%s格式字符进行输入与输出。当使用scanf进行读一个字符串的时候,读到什么东西,读到什么位置为止是很微妙的,试一下:

技术分享
1 #include <stdio.h>
2 int main(void){
3     char word[8];
4     scanf("%s",word);
5     printf("%s##\n",word);
6     
7     return 0; 
8  } 
View Code

  程序在输出时,在%s后面添加两个##,来提示我们输出释放结束。编译运行后输入hello world,结果如下,输出只有hello,没有world,也没有hello和world之间的空格。

hello world
hello##

--------------------------------
Process exited after 5.404 seconds with return value 0
请按任意键继续. . .

  对代码再修改如下,试着能到world,新建了两个字符串,使用scanf读取两次再使用printf输出两次,结果第一次读到的是hello不带空格,第二次读到的是world也不带空格,因为空格是区分hello和world的,是分隔符。如果输入hello会出,然后输入world再回车,输出结果依然是hello##world##,没有回车。

技术分享
 1 #include <stdio.h>
 2 int main(void){
 3     char word[8];
 4     char word2[8];
 5     
 6     scanf("%s",word);
 7     scanf("%s",word2);
 8     printf("%s##%s##\n",word,word2);
 9     
10     return 0; 
11  } 
View Code
hello world
hello##world##

--------------------------------
Process exited after 7.528 seconds with return value 0
请按任意键继续. . .

  所以综上,%s读到的是一个“单词”,这个单词不是英文中的单词,而是读到空格、tab或回车为止。可见scanf是不安全的,它不知道要读入的内容的长度是多少,再使用scanf时,没有给scanf任何字符串word有多大,我们再学数组时知道,数组作为函数参数时,传进去的是个指针。再上述程序中,开了8个字节的一个数组,那么当你输入的东西超过8个会怎么样?在32位编译系统中,当输入超过8个时有可能输出部分结果,也有可能运行结果崩溃,崩溃的原因是输入越界了。

  那么给字符串写入时,怎么使scanf函数安全哪?在%s前面加一个7,因为申请8个字节,有一个字节是结束符\0。程序修改如下:

技术分享
 1 #include <stdio.h>
 2 
 3 int main(){
 4     char word[8];
 5     char word2[8];
 6     
 7     scanf("%7s",word);
 8     scanf("%7s",word2);
 9     printf("%s##%s##\n",word,word2);
10     
11     return 0; 
12  } 
13  
View Code
1234567812345678
1234567##8123456##

--------------------------------
Process exited after 8.191 seconds with return value 0
请按任意键继续. . .

  当输入1234567812345678时,前7个字符给了第一个scanf,而8123456近邻的这7个字符给了第二个scanf。所以在%和s之间的数字表示最多允许读入的字符的数量,这个数组应该比数组的大小小1.所以有数字控制读多少个,而字符后有没有空格、tab等还有没有用,当读入的个数不超过7个时,出现空格、tab或回车等,依然有效,但当超过7个时,只读入7个字符,因为读入的个数由%和s之间的数字确定。那么读入7个后下面的内容会交给其他scanf等。

  常见错误

  误解1:比如下面代码,使用char*定义后就可以直接使用了,以为char*是字符串类型,定义了一个字符串类型的变量string就以为可直接使用了,但实际上char*只是定义了一个指向某一块内存空间的指针,但是这个指针没有被初始化,然后char*是本地变量,本地变量没有默认的初始值,所以很可能指向一个未知的不可写的空间,那么在使用scanf写入一些东西时,系统就会崩溃。(未见每一次都崩溃,但是早晚有一天就崩溃了,或者在这台电脑没有崩溃,换一台电脑运行同一块代码就会崩溃)。

char * string;
scanf(“%s”,string);

  误解2:关于空字符串。比如下面代码,相邻的紧挨着”“意思是这是一个空字符串,第一行制定数组是100,依然是一个有效的字符串,但是这个字符串的buffer[0]=‘\0‘。但第二行没有指定buffer的大小,这个字符串数组的长度是1,不可以写入东西。

char buffer[100]="";
char buffer[]="";

  字符串数组

  如果你想写一个数组去表达很多个字符串,char**a,a是一个指针,指向另一个指针,而那个指针指向一个字符(串),所以这不是我们需要的字符串数组。

  char[][]是什么呢,a是一个二维数组的变量,在二维数组中,第二维一定需要一个确切的大小的,否则编译通不过。试一下这件事情,代码如下,编译时出错,错误提示为:4 11 D:\Cexample\char.cpp [Error] declaration of ‘a‘ as multidimensional array must have bounds for all dimensions except the first如我们所述一样,二维数组的第二维需要一个确切的大小。

技术分享
1 #include <stdio.h>
2 
3 int main(void){
4     char a[][]={"hello",};
5     
6     return 0;
7 }
View Code

  那么修改上述代码为 char a[][10]={"hello",};,表示a这个数组里的每个单元是一个char [10],也就是a[0]相当于一个数组,当然这么写,如果输入超过10个字符时,编译器就会出错:4 54 D:\Cexample\char.cpp [Error] initializer-string for array of chars is too long [-fpermissive]

技术分享
1 #include <stdio.h>
2 
3 int main(void){
4     char a[][10]={"hello","world","alksjfklasjlkfjsklfj"};
5     
6     return 0;
7 }
View Code

  那么如果我们将char a[][]改为char *a[],这个时候就不会出错,在这个时候,a[0]相当于char *。这两种形式是不一样的,当定义char a[][10]时,意思是在内存里有一个很大的矩形,每个a[]都是10个字符。而定义成char *a[]的形式,意思是每个元素都比较小,a[0]是一个指针,指向外面的某个地方。

技术分享

  作业:试着使用字符串数组完成输入月份,那么输出这个月份的英文单词。

  程序参数-主函数参数

  字符串数组还有一个应用就是可作为main函数的参数:int main(int argc,char const *argv[]),main参数表里不是空的,有两个参数,一个是整数,一个是字符串数组,整数是告诉我们后面数组到底有多少字符串的,下面试一下,输出参数中所有字符串,看下到底是些什么?

技术分享
 1 #include <stdio.h>
 2 
 3 int main(int argc, char const *argv[]){
 4     int i;
 5     for (i=0;i<argc;i++){
 6         printf("%d:%s\n",i,argv[i]);
 7     }
 8     
 9     return 0;
10 }
View Code

  共有argc个字符串,使用for循环,输出每一个字符串,输出格式是”i:字符串内容“,i是从0开始。结果截图如下,目前只有一个字符串,也就是i=0时的字符串,该字符串内容和终端左上角是一样的,也就是第0个参数是可执行文件:

 技术分享

  在devc++的运行菜单选择参数,弹出下列对话框,在传递给主程序的参数中输入任意字符串,然后再运行时,结果有四个参数,第0个参数是生成的可执行文件,第1个、2个、3个参数是用户执行该程序的输入,具体有几个参数看用户输入几个。

技术分享

0:D:\Cexample\char3.exe
1:niu
2:xiao
3:xia

--------------------------------
Process exited after 0.02373 seconds with return value 0
请按任意键继续. . .

听翁恺老师mooc笔记(8)--字符串2