听翁恺老师mooc笔记(8)--字符串2
字符串的赋值
字符串的输入与输出
对C语言的基础类型,比如int、double等类型,scanf、printf有专门的格式转换,而对字符串,scanf、printf使用%s格式字符进行输入与输出。当使用scanf进行读一个字符串的时候,读到什么东西,读到什么位置为止是很微妙的,试一下:
#include <stdio.h>
int main(void){
char word[];
scanf("%s",word);
printf("%s##\n",word); return ;
}
程序在输出时,在%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##,没有回车。
#include <stdio.h>
int main(void){
char word[];
char word2[]; scanf("%s",word);
scanf("%s",word2);
printf("%s##%s##\n",word,word2); return ;
}
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。程序修改如下:
#include <stdio.h>
int main(){
char word[];
char word2[];
scanf("%7s",word);
scanf("%7s",word2);
printf("%s##%s##\n",word,word2);
return ;
}
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,如我们所述一样,二维数组的第二维需要一个确切的大小。
#include <stdio.h>
int main(void){
char a[][]={"hello",};
return ;
}
那么修改上述代码为 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]。
#include <stdio.h>
int main(void){
char a[][]={"hello","world","alksjfklasjlkfjsklfj"};
return ;
}
那么如果我们将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参数表里不是空的,有两个参数,一个是整数,一个是字符串数组,整数是告诉我们后面数组到底有多少字符串的,下面试一下,输出参数中所有字符串,看下到底是些什么?
#include <stdio.h>
int main(int argc, char const *argv[]){
int i;
for (i=;i<argc;i++){
printf("%d:%s\n",i,argv[i]);
}
return ;
}
共有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的更多相关文章
- 听翁恺老师mooc笔记(7)--字符串1
C语言中字符串的定义 如果定义一个字符数组word,并使用大括号对其初始化,如下图所示: 但是这个不是C语言的字符串,只是字符数组,不是字符串,因为不能使用字符串的方式进行计算.那么C语言的字符串长什 ...
- 听翁恺老师mooc笔记(15)--文件的输入与输出
<>重定向 如果使用标准的printf输出,有一个比较简便的方法,可以将程序的结果写入一个文件.使用<和>符号,将程序运行结果重定向到文件中去,具体使用到的代码如下: ./te ...
- 听翁恺老师mooc笔记(14)--格式化的输入与输出
关于C语言如何做文件和底层操作: 文件操作,从根本上说,和C语言无关.这部分的内容,是教你如何使用C语言的标准库所提供的一系列函数来操作文件,最基本的最原始的文件操作.你需要理解,我们在这部分所学习的 ...
- 听翁恺老师mooc笔记(13)--类型定义和联合
typedef 虽然我们知道使用struct这个关键字定义一个结构类型,然后可以使用该结构类型定义变量.但是每次要使用的时候都需要带着struct这个关键字,那么如何摆脱这个关键字哪?C语言提供了一个 ...
- 听翁恺老师mooc笔记(2)-第一个程序--&运算符
使用devC++写hello world 第一步:文件-新建-源代码.然后输入"输出hello world"程序: 注意:写程序时关闭中文输入法,否则语句输入的分号可能会被识别为错 ...
- 听翁恺老师mooc笔记(16)--程序设计与C语言
问题1:计算机遍布生活的各个方面,若你需要一个功能可以下载APP,我们需要的大部分功能都可以找到对应的APP,如果没有可以自己写一个软件,但是很少人需要这么做,那么我们为什么学习计算机编程语言? 学习 ...
- 听翁恺老师mooc笔记(12)--结构中的结构
结构数组: 和C语言中的int,double一样,一旦我们做出一个结构类型,就可以定义这个结构类型的变量,也可以定义这个结构类型的数组.比如下面这个例子: struct date dates[100] ...
- 听翁恺老师mooc笔记(11)--结构和函数
结构作为函数参数: 声明了一个结构就有了一种自定义的数据类型,这个数据类型和int.float.double一样,int等基本类型可以作为函数的参数,那么这种个自定义的结构类型也应该可以作为函数参数, ...
- 听翁恺老师mooc笔记(10)--结构
定义结构: 在程序里,如果想要表达一个数据就需要一个变量,而每个变量又都需要一个类型,之前学过C语言中有int.double.float.char等这些基础类型,还有指针.数组等.如果你要表达的数据比 ...
随机推荐
- hdu3081 Marriage Match II
新年第一篇,又花了一早上,真是蠢啊! 二分+网络流 之前对于讨论哪些人是朋友的时候复杂度过高 直接n3的暴力虽然看起来复杂度高,其实并不是每次都成立 #include<bits/stdc++.h ...
- eclipse远程调试Tomcat方法(测试成功并且说说遇到的坑)
转自:http://blog.csdn.net/afgasdg/article/details/9236877 PS:文中容易引起歧义的地方已经做了修改:另外,本人参照以下步骤操作,结果无法调试,后来 ...
- WebForm 生成并显示二维码
Generate and display QRCode in WebForm. 项目引用 QRCoder生成并显示 QRCode 项目引用 QRCoder How to use QRCoder Via ...
- 洛谷2709 小B的询问(莫队)
题面 题目描述 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R] ...
- wpf研究之道-grid控件
想要说些什么,却不知道从哪开始."形而上谓之道,形而下谓之器".与其坐而论道,不如脚踏实地,从最实用的地方开始. 我们先来看看wpf中的grid控件.grid控件是个网格的布局控件 ...
- Redis持久化方案
Redis可以实现数据的持久化存储,即将数据保存到磁盘上. Redis的持久化存储提供两种方式:RDB与AOF.RDB是默认配置.AOF需要手动开启. 默认redis是会以快照的形式将数据持久化到磁盘 ...
- 17.HTML
HTML简介 htyper text markup language 即超文本标记语言. 超文本: 就是指页面内可以包含图片.链接,甚至音乐.程序等非文字元素. 标准模板 <!DOCTYPE ...
- Java集合中的LinkedHashMap类
jdk1.8.0_144 本文阅读最好先了解HashMap底层,可前往<Java集合中的HashMap类>. LinkedHashMap由于它的插入有序特性,也是一种比较常用的Map集合. ...
- 数组的迭代方法(every、filter、forEach、map、some)
every: 对数组中的,每一项运行给定函数,如果该函数对每一项都返回true,则返回true. var number = [1,2,3,4,5,6]; var result = number.eve ...
- [转]Thunderbird 使用 Exchange 邮箱
[转]Thunderbird 使用 Exchange 邮箱 http://my.oschina.net/MaTech/blog/295238#OSC_h3_1 公司最近邮箱只支持Exchange模式, ...