字符是C/C++读入数据最主要的类型。本篇将介绍单个字符数组/多个字符串及二维数组的输入输出方式与相关函数。

目录

单个字符串处理

​编辑

输入

逐个元素输入

整体串形式输入

输出

逐个输出

整体串形式输出

任一元素开始串形式输出

多个字符串处理

输入

gets_s(VS)

gets(Dev C++)

fgets(VS / Dev C++)

二维数组的输入输出


单个字符串处理

输入

逐个元素输入

在对字符数组进行输入操作时,可以逐个元素进行输入,甚至指定输入某个位置的某个元素。下面将从C和C++两种方式进行介绍:

C语言:scanf ( "%c", &数组元素 )

C++:cin>>数组元素

当然这就是最简单的输入方法,我们可以从下面两段代码理解:

/* C++基本实现 */
char s[20];
cin >> s[3] >> s[6];   //输入 Tj
cout << s[3] << s[6];  //输出 Tj/* C语言基本实现 */
char v[20];
scanf("%c%c",&v[3],&v[6]);   //输入Sp
printf("%c%c",v[3],v[6]);  //输出Sp

scanf在使用时,需要加上取地址符 &,因为scanf规定后面必须是变量的地址。

那么我们再来讨论一下非正常输入的情况。在上段代码中那,要求输入两个字符,但是输入三个字符会怎么样呢?其实这和 cin 输入的普通处理相同,多余的数据会被存放在缓冲区中,而真正起作用的就是输入的前两个参数。

但是如果输入了呢?这里就有一个需要引起注意的地方。先看一段代码:

/* CASE 1: C++ */
char s[20];
cin >> s[2] >> s[3] >> s[4];
cout << int(s[2]) << ' ' << int(s[3]) << ' ' << int(s[4]) << endl;
//这时如果只输入两个字符,然后按回车(一个或多个),光标会一直跳动等待输入/* CASE 2: C */
char s[20];
scanf("%c%c%c",&s[2],&s[3],&s[4]);
cout << int(s[2]) << ' ' << int(s[3]) << ' ' << int(s[4]) << endl;
//这时表现就和上面不同了
//如输入 ab ,按回车后不再等待,而第三位输出的是回车的ascii码

可以用一句话总结一下以上规律:多次逐个输入时,C处理回车的方式时当作字符读入,而C++不作为字符读入 ,等待继续输入。

整体串形式输入

看完上面的逐个输入,会觉得这是一种这时一种非常繁琐的方式。如果用逐个读入的方式读入整个字符串,需要使用一个循环才可完成全部输入操作。这里将介绍整体字符串形式输入的方式:

C语言:scanf ( "%s", 数组名 )

C++:cin>>数组名

这里我们可以把C方式和逐个输入比较一下,会发现这里不再需要加取地址符&,这是因为C/C++ 规定,数组名代表数组的首地址。样例代码如下:

/* C方式 */
char s[20]={'\0'};
scanf("%s",s);
cout<<s<<endl;/* C++方式 */
char s[20]={'\0'};
cin>>s;
cout<<s<<endl;//这两个程序的结果是一样的
//如输入 hello ,都会输出hello(后面都是尾零不输出)

在逐个输入时,如果多输入,在本次读取也不会产生问题,只是存储在缓冲区中。但是在整体输入时,如果输入字符个数超过数组大小便会导致弹窗报错。

同时,极容易忽视的一点是,输入的字符个数应当严格小于数组大小,因为字符串后面有一个隐式的尾零,也占数据的一位空间。这也导致字符串方式输入的字符数组最后总有一个尾零。

在字符串形式输入时,无论是C还是C++,回车都不会被当作一个字符读入。(回顾:逐个读入时C方式会读取回车当作普通字符存储)。我们可以用下面的代码加以验证:

char s[3];
scanf("%s", s);
for (int i = 0; i < 3; i++) {cout << int(s[i]) << ' ';
}
cout << endl;//这时输入一个字符a ,输出三个数字:97 0 -52

可以看到输出结果没有回车,同时中间的数字0就是尾零的ascii码。最后的-52表示这里字符数组没有被输入,是一个随机值。这里可以在定义数组时简单操作,使数组初始元素都为尾零:

char s[3]={'\0'};  //此处操作
scanf("%s", s);
for (int i = 0; i < 3; i++) {cout << int(s[i]) << ' ';
}
cout << endl;//这时输入一个字符a ,输出三个数字:97 0 0
//可以看到最后一位变成了0,也是尾零

输出

逐个输出

可以逐个输入,当然也可以逐个输出。逐个输出就是普通的字符输出方式:

C语言:printf ( "%c" , 数组元素 )

C++:cout<<数组元素

这个输出方式操作比较简单,看一段代码简单加深下印象:

char s[]="Henry";
cout<<s[3]<<'*';
printf("%c",s[4])<<endl;
//输出结果是 r*y

整体串形式输出

整体串形式输入输出大同小异:

C语言:printf ( "%s", 数组名 )

C++:cout<<数组名

当然尾零虽然在数组中,但是其存在意义是标志字符串的结束,所以不会被输出。

此外需要注意的是,在整体输出时,如果字符串中间某位置存在显式尾零,则输出时只会输出到第一个尾零的前一个字符为止:

char s[]="Henry\0 is so handsome!";
cout<<s<<endl;
printf("%s",s);//输出的内容是两行的 Henry
//太可惜了,区区一个尾零让读者不知道博主有多帅!所以一定要注意尾零哦!

尾零虽然不输出,但是也是必不可少的。如果手动取出末尾的尾零(换成其他字符),则在正常字符后会出现一堆乱字符:

乱字符表示数组已经越界读取。此时无论乱字符出现多少都是正常的,这是因为会一直读到遇到第一个尾零为止。所以乱字符的多少完全取决于外部尾零的尾零。所以以字符串形式输出不含尾零的字符数组是不可取的方法。

任一元素开始串形式输出

在了解了逐个输出和串形式整体输出后,问题出现了:如果想从串中间某位置开始输出后面所有内容,用逐个输出显得过于繁杂,而串整体输出又达不到预期目的(起点固定)。这时便可以引入任一元素开始串形式输出的方法:

char s[]="hello world";
printf("%s\n",&s[6]);
cout<<&s[6]<<endl;
//输出是两行world

所以可以归纳为:

C语言:printf ( "%s", &数组元素名 )

C++:cout<<&数组元素名

这里发现在开始字符处都要加上取地址符。其实可以和串整体输出联系起来:串整体输出时,直接用数组名,其实是因为数组名表示了数组的首地址,所以换言之也是读取了地址,再从地址开始一直读取到尾零为止。

同样输入也可以用相同的方式进行起始点控制:

C语言:scanf ( "%s", &数组元素名 )

C++:cin>>&数组元素名


多个字符串处理

输入

多个字符串的输入方式和单个字符串没有太大的区别,只是输入时参数变为两个:

C语言:scanf ( "%s%s" ,a,b )

C++:cin>>a>>b

看似没有什么特别的地方。但是这里有一个需要考虑的问题:编译器怎么区分输入的是两个字符串。换言之输入时什么符号作为这两个字符串的间隔?

将这个代码稍加改进,可以做以下的探究:

char a[20],b[20],c[20],d[20];/* C++方式 */
cin>>a>>b;             //输入 ab cd(中间有空格)
cout<<a<<'#'<<b<<endl; //输出 ab#cd/* C方式 */
scanf("%s%s",c,d);     //输入 mn pq(中间有空格)
printf("%s#%s",c,d);   //输出 mn#pq

通过这一段代码我们可以清晰地看到作为分隔符的这个字符就是空格(当然回车也可以,但在这里不做讨论),也就是说使用cin和scanf(一般情况下)从键盘上输入的字符串不会读入空格,空格在此处是一个分隔符而不是输入串中的合法字符。

为了读入空格,除了对cin和scanf进行高级设置之外,还可以使用这几个可以读入空格的函数:

gets_s vs2019/22中可使用
gets Dev C++中可以使用
fgets vs和Dev中都可以使用

下面就是对这几个函数使用方法的详细介绍:

gets_s(VS)

在gets_s函数中,字符串输入结束的标志只有回车。可以操作下面的示例代码:

/* 注意:只能在VS编译器中编译 */
char m[20],n[20];
gets_s(m);
gets_s(n);
cout<<m<<endl<<n<<endl;//输入两个中间含空格的字符串,并用回车间隔,输出一样的字符串(含空格)

可以读取空格就是 gets_s 函数神奇的地方。同时输入时也要注意,输入的字符个数应当严格小于数组长度。因为串方式输入后面会附带一个隐式尾零,所以需要留下部分空间。

gets(Dev C++)

使用方法和 gets_s 完全相同,同时也要注意输入个数的问题,在dev中运行。

fgets(VS / Dev C++)

标准函数语句:fgets ( 字符数组名,最大长度,stdin )

fgets 与 gets 和 gets_s 的最大区别就是回车的读取。当连续利用两个 fgets 读入字符串时,输出会多两个换行,因为此处换行虽然具有结束字符串输入的作用,但是也会被 fgets 读入。


二维数组的输入输出

二维数组的输入输出使用和一维数组完全相同的方式。需要注意的是,二维数组双下标表示元素(实现逐个输入输出),单下标表示一维数组(实现串方式输入输出)。

C/C++字符数组的输入输出方式详解相关推荐

  1. 字符数组和字符串的区别,C语言字符数组和字符串区别详解

    C 语言中并不存在字符串这个数据类型,而是使用字符数组来保存字符串.那么,字符数组就一定是字符串吗? 不一定,字符数组和字符串千万不要混淆.字符串是一种特殊的字符数组,并且C语言提供了大量适用于字符串 ...

  2. php和c语言的字符数组中,字符数组和字符串的区别,C语言字符数组和字符串区别详解...

    C 语言中并不存在字符串这个数据类型,而是使用字符数组来保存字符串.那么,字符数组就一定是字符串吗? 对于这个问题,大多教科书中的回答是"是".其实不然,字符数组和字符串是完全不相 ...

  3. 字符常见的编码方式详解

    字符常见的编码方式 本人是做嵌入式开发的,当初第一次接触MDK时,被一个问题疑惑过,那就是在keil中的汉字注释复制到别的地方会出现乱码,还有编代码的时候,总会选择UTF-8编码方式.带着这些疑问我在 ...

  4. c++ string 删除字符_算法笔记|(5)第二章C、C++的快速入门字符数组的存放方式string.h文件...

    字符数组的存放方式 由于字符数组是由若干个char类型的元素组成的,因此字符数组的每一位都是一个char字符,除此之外,在一维字符数组或者二维字符数组的第二维的末尾都有一个空字符\0表示存放的字符串的 ...

  5. Python中数组切片的用法详解

    Python中数组切片的用法详解 一.python中"::-1"代表什么? 二.python中":"的用法 三.python中数组切片 三.numpy中的整数数 ...

  6. Java快速输入输出使用详解(解决Java输入输出超时问题)

    Java快速输入输出使用详解 一.背景:   Scanner类输入时,虽然方式很简单,但是输入实在太慢了,经常遇到大的数据量时候就超时.(你觉得数据有点多时就用快速输入即可)   某些题目用Scann ...

  7. 操作系统I/O控制方式详解

    操作系统I/O控制方式详解 一.导读 二.I/O控制方式 1.直接程序控制方式 2.中断驱动控制方式 3.直接存储器访问(DMA)控制方式 4.通道控制方式 I/O控制方式有几种?分别适用何种场合? ...

  8. LSTM入门必读:从入门基础到工作方式详解 By 机器之心2017年7月24日 12:57 长短期记忆(LSTM)是一种非常重要的神经网络技术,其在语音识别和自然语言处理等许多领域都得到了广泛的应用

    LSTM入门必读:从入门基础到工作方式详解 By 机器之心2017年7月24日 12:57 长短期记忆(LSTM)是一种非常重要的神经网络技术,其在语音识别和自然语言处理等许多领域都得到了广泛的应用. ...

  9. 三位数组的轴python_关于numpy数组轴的使用详解

    概述 按照图一中aixs=0,对aixs=0上下对应的数据进行相加在学习numpy的时候,最难理解的就是轴的概念,我们知道坐标系中有轴的概念,那么两个轴是否有关联呢?为了便于理解,特写此博客进行梳理. ...

最新文章

  1. 英语是缺乏AOP的语言,汉语是具备AOP的语言。
  2. 【深度学习入门到精通系列】医学图像预处理—伽马变化代码
  3. erlang进程的调度效率
  4. ASP.NET Core 中间件Diagnostics使用
  5. ROCKOUT软件测试工程师,具透丨这才是让 iMessage 变得好玩有用的原因:iMessage App Store 详解...
  6. openwrt 编译时提示缺少libstdc++,libpthread.so.0文件
  7. linux mysql jdk路径配置,Linux下的jdk1.5+eclipse+mysql开发环境配置的经验总结
  8. Symbian 5800 重力开发的一些数据
  9. velocity 将数字转为以万为单位,保留2位小数
  10. 淘宝B2C上线 马云初试将阿里巴巴三合一
  11. linux命令dstat,linux系统监控:dstat命令
  12. 内外网切换,内网固定ip
  13. 高斯白噪声仿真-复信号分析
  14. code405是什么意思_HTTP返回reponse code 405
  15. ps-ef命令linux,【Linux】- ps -ef |grep 命令
  16. 4 个 Linux 技巧,你值得拥有
  17. Docker学习笔记 — Swarm搭建Docker集群
  18. PS渐变自行车的做法
  19. element组件---Form
  20. 用友 针式打印机纸张设置

热门文章

  1. 南开大学python编程基础_《Python编程基础》20春期末考核(参考答案)南开大学 答案...
  2. Django修改mysql连接密码的一个坑
  3. FAQ-华为AP命名规则整理
  4. 连锁不平衡以及连锁不平衡衰减
  5. 《传统蒙古文信息交换与处理字形编码》第1次征求意见稿 (0.0.1版)
  6. 如何利用免费小说引流?小说平台怎么免费推广引流?
  7. 基于 Java8 的国产开源 IoT 企业级物联网平台
  8. 发动机冷却系统的控制论文综述
  9. php中进制转换,php的进制转换
  10. 星巴克、瑞幸、喜茶数字运营策略