字符串的赋值

  字符串的输入与输出

  对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的更多相关文章

  1. 听翁恺老师mooc笔记(7)--字符串1

    C语言中字符串的定义 如果定义一个字符数组word,并使用大括号对其初始化,如下图所示: 但是这个不是C语言的字符串,只是字符数组,不是字符串,因为不能使用字符串的方式进行计算.那么C语言的字符串长什 ...

  2. 听翁恺老师mooc笔记(15)--文件的输入与输出

    <>重定向 如果使用标准的printf输出,有一个比较简便的方法,可以将程序的结果写入一个文件.使用<和>符号,将程序运行结果重定向到文件中去,具体使用到的代码如下: ./te ...

  3. 听翁恺老师mooc笔记(14)--格式化的输入与输出

    关于C语言如何做文件和底层操作: 文件操作,从根本上说,和C语言无关.这部分的内容,是教你如何使用C语言的标准库所提供的一系列函数来操作文件,最基本的最原始的文件操作.你需要理解,我们在这部分所学习的 ...

  4. 听翁恺老师mooc笔记(13)--类型定义和联合

    typedef 虽然我们知道使用struct这个关键字定义一个结构类型,然后可以使用该结构类型定义变量.但是每次要使用的时候都需要带着struct这个关键字,那么如何摆脱这个关键字哪?C语言提供了一个 ...

  5. 听翁恺老师mooc笔记(2)-第一个程序--&运算符

    使用devC++写hello world 第一步:文件-新建-源代码.然后输入"输出hello world"程序: 注意:写程序时关闭中文输入法,否则语句输入的分号可能会被识别为错 ...

  6. 听翁恺老师mooc笔记(16)--程序设计与C语言

    问题1:计算机遍布生活的各个方面,若你需要一个功能可以下载APP,我们需要的大部分功能都可以找到对应的APP,如果没有可以自己写一个软件,但是很少人需要这么做,那么我们为什么学习计算机编程语言? 学习 ...

  7. 听翁恺老师mooc笔记(12)--结构中的结构

    结构数组: 和C语言中的int,double一样,一旦我们做出一个结构类型,就可以定义这个结构类型的变量,也可以定义这个结构类型的数组.比如下面这个例子: struct date dates[100] ...

  8. 听翁恺老师mooc笔记(11)--结构和函数

    结构作为函数参数: 声明了一个结构就有了一种自定义的数据类型,这个数据类型和int.float.double一样,int等基本类型可以作为函数的参数,那么这种个自定义的结构类型也应该可以作为函数参数, ...

  9. 听翁恺老师mooc笔记(10)--结构

    定义结构: 在程序里,如果想要表达一个数据就需要一个变量,而每个变量又都需要一个类型,之前学过C语言中有int.double.float.char等这些基础类型,还有指针.数组等.如果你要表达的数据比 ...

随机推荐

  1. shiro的登陆认证(shiro项目中来的一)

    一,图解 二,流程 2.1,创建token令牌,token中有用户提交的认证信息即账号和密码 Subject subject = SecurityUtils.getSubject(); Usernam ...

  2. 【NFS】nfs安装调优

    nfs [root@flymaster ~]# rpm -qa nfs-utils rpcbindnfs-utils-1.2.3-75.el6.x86_64rpcbind-0.2.0-13.el6_9 ...

  3. 【原】storm组件(架构层面)

    Strom集群遵循从主模式,主与从之间通过Zookeeper协作.架构层面上包括三个组件: 1) Nimbus Node 2)Supervisor Nodes 3)Zookeeper 其中Nimbus ...

  4. GridView 多余字符显示省略号,并在Tooltip中显示完整信息

    效果 方法一:TemplateField 关键点 TemplateField的灵活性 CSS:overflow:hidden;text-overflow:ellipsis (溢出时隐藏;文本溢出时省略 ...

  5. Metrics.net + influxdb + grafana 构建WebAPI的自动化监控和预警

    前言 这次主要分享通过Metrics.net + influxdb + grafana 构建WebAPI的自动化监控和预警方案.通过执行耗时,定位哪些接口拖累了服务的性能:通过请求频次,设置适当的限流 ...

  6. JavaScript保留关键字2。

    一些不做解释的关键字是在js中预留的东西. abstract 抽象  . arguments  参数 标识符arguments是指向实参对象的引用,实参对象是一个类数组对象. boolean 布尔值. ...

  7. 八年架构师大咖首次揭秘,年薪50W秘籍!

    序言 我是土生土长的老北京人,你们肯定觉得我很有钱,为啥呢? 因为觉得我是北京户口,其实你们错了,我的房子是靠我自己买的,父母基本上没帮到我什么,当然,我也不需要吧! 我只想说,作为一名程序员,我很自 ...

  8. Java 计算年龄

    public static String getAgeTxt(String birthTime,String beginTime,int level){ if(StringUtils.isBlank( ...

  9. Redis之String

    一.Redis之String简介 1. String是redis最基本的数据类型,一个key对应一个value. 2. String是二进制安全的,可以包含任何数据,例如图片或序列化的对象. 3. S ...

  10. Micropython TurnipBit 电子时钟 青少年编程入门

    电子时钟是一个很常用但是制作非常简单的小玩具了,对于Micropython初学者来说,制作一个电子时钟是非常简单又容易检验自己学习成果的实验了.TurnipBit相比于其他开发板,制作电子时钟就更加简 ...