C++中的字符串(1)

目录
  • 1、字符串
    • 1.1 字符串定义
    • 1.2 字符串的读入
    • 1.3 排坑

1、字符串

1.1 字符串定义

字符串就是连续的一连串字符,在C++当中, 处理字符串的方式有两种类型。一种来自于C语言,也被称为C风格字符串。另外一种是基于string类库。

C风格的字符串其实就是字符存储在char数组当中。不过它和一般的数组有一些区别,拥有一些特殊的性质。比如一空字符\0结尾,它的ascii码是0,用来标记字符串的结尾。

char str[5] = {'h', 'e', 'l', 'l', 'o'};
char str2[5] = {'h', 'e', 'l', 'l', '\0'};

对于上面的两个例子,第一个例子虽然也是char数组,但是由于它的结尾不是\0,所以它不能看成是字符串。因为很多算法都是以\0的位置为标记的,比如计算字符串长度的算法,以及cout等等。

上面我们采用的是数组常规的初始化方式,这当然是可以的,不过这样会很不方便。一个是需要一位一位地填写字符,会非常地麻烦。另外还需要手动填充\0,也容易忘记,

所以对于字符串而言我们还有更好的初始化方式:

char hello[6] = "hello";
char world[] = "world";

用引号括起来的字符串隐式地包含了结尾的\0,需要注意的是,我们在确定数组长度的时候需要将结尾的\0也计算在内。

这里要提醒大家注意引号的区别, 在C++当中单引号表示单个字符,而双引号表示字符串。所以下面这种写法是错误的:

char c = "S";

并且“S”其实表示的是字符串所在的内存地址,当我们把一个内存地址赋值给一个char类型的时候自然就会报错了。

咦,不是说好的是字符串么,怎么又扯到地址了?不要急,等后面讲到指针的地方就明白了。

1.2 字符串的读入

直接用字符串常量来初始化字符数组只是一种方式,另外一种常用的方式是只定义字符数组的长度,从外部读入数据,

如:

char str[100];

scanf("%s", str);
cin >> str;

无论是使用scanf还是cin,都是一样的效果。

但是没有这么简单,比如我们再来看一段代码:

char name[100];
char level[100];

scanf("%s", name);
scanf("%s", level);

在这段代码当中,我们定义了name和level两个字符串变量。当我们执行的时候,就会发现问题:

我刚输入完名字,还没来得及输level就结束了。如果我们把namelevel分别输出的话就会发现,name的值是lianglevel的值是tang

这说明了什么?说明了我们读入字符串的时候它并不是按行读入的,而是按照空格分隔的!它不像是隔壁的Pythoninput默认就是读入一行,C++的读入默认都是按照空格分隔的。

那问题来了,假如我们需要读入一行应该怎么办呢?也有办法,我们可以使用cin.getline代替之前的scanf或者是cin

我们来看下它的函数签名:

istream& getline ( istream& is, string& str, char delim );
istream& getline ( istream& is, string& str );

C++允许参数列表不同的同名函数重载,这两个签名都是OK的。两者的差别在于第三个参数,但三个参数表示分隔符,如果不传的话,默认是'\n'。第二个参数表示字符串的长度,所以如果要按照行来读入字符串的话,刚刚的代码应该写成:

cin.getline(name, 100);
cin.getline(level, 100);

除了可以使用getline之外,还可以使用getget有好几种变体,一种变体是读入一个字符,它有一种变体也可以读入一行字符串。不过唯一的区别是,get函数不会处理行尾的换行符。如果我们要读入两行字符的话,需要手动将这个换行符处理掉。

cin.get(name, 100); // 读入一行数据
cin.get();   // 读入换行符
cin.get(level, 100);// 读入第二行数据

写成三行看起来有些繁琐,我们还可以进行简化,简化成一行:

cin.get(name, 100).get().get(level, 100);

看起来很像是Java8的流式编程,能够这样做的原因是getgetline函数会返回一个cin的对象。所以我们可以这样连续调用。

相信有些同学已经注意到了,同样的函数名,根据我们传入的参数不同执行了不同的逻辑。这在C++当中叫做函数重载,是一个非常重要的概念。

1.3 排坑

关于getline有一个比较大的坑,当我们同时使用cingetline的时候,有时候会出现问题。

比如下面这段代码:

int a;
char name[100];
cin >> a;
cin.getline(name, 100);

cout << "a = " << a << endl;
cout << "name = " << name << endl;

这段代码很简单,我们定义了两个变量。一个是int型的a,一个是字符串name。我们使用cin读入a,使用getline读入name

这看起来一点问题也没有,但是当我们运行的时候就会出现问题。

会发现我都没有来得及输入name,程序就结束了,而name读到了一个空。

这并不是C++有bug,而是我们在输入32的时候,敲了一个回车。所以在使用getline读入一行的时候,看到了回车,直接退出了,读入了一个空行,这就是为什么我们没有机会输入name的原因。

要解决这个问题怎么办呢?其实也很简单,我们额外读入一个字符,把换行符给读取掉就行了。

int a;
char name[100];
cin >> a;
cin.get(); // getchar() C语言版本
cin.getline(name, 100);

cout << "a = " << a << endl;
cout << "name = " << name << endl;

类似的问题在竞赛的题目当中很常见,我们经常要同时读入字符串和数字,很容易遇到这样的问题。遇到了不要紧张,仔细检查一下数据和逻辑,看看是不是读入到了换行符。

到此这篇关于C++中的字符串(1)的文章就介绍到这了,更多相关C++字符串内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

注:文章转自微信公众号:Coder梁(ID:Coder_LT)

(0)

相关推荐

  • c++ 数字类型和字符串类型互转详解

    目录 一级目录 数字转为字符串 二级目录 字符串转为数字 总结 一级目录 数字转为字符串 二级目录 字符串转为数字 1.数字转为字符串 (1).首先要加头文件 #include < iostream > #include < sstream > #include < string > 这个类在头文件中定义, < sstream>库定义了三种类:istringstream.ostringstream和stringstream,分别用来进行流的输入.输出和输入输

  • C/C++中带空格字符串的输入讲解

    目录 C语言 C++ string类型 总结 C语言 #include <iostream> using namespace std; int main() { char str[100]; gets(str); printf("%s\n",str); return 0; } C++ string类型 #include <iostream> #include <string> using namespace std; int main() { str

  • C++变量,常量,数组和字符串详解

    目录 一.内存和寻址概述 二.变量 1.声明变量 2.变量的作用域 2.1 局部变量 2.2 全局变量 3.c++变量类型 3.1.bool布尔类型 3.2 char字符型 4.常量 总结 一.内存和寻址概述 可编程设备包含微处理器和一定数量的临时存储空间.临时存储器被称为随机存取存储器(RAM). RAM类似于宿舍里成排存物柜的存储区域,每个存物柜都有编号,即地址.要访问特定的内存单元,需要使用指令要求处理器从这里获取值或写入值. 微处理器负责执行应用程序,并从RAM中获取要执行的应用程序以及

  • C++中字符串与整型及浮点型转换全攻略

    目录 一.string 和 char [] 1. string 转 char [] 2. char [] 转 string 二.char [] 与数字互转 1. char [] 转整型和浮点型 2. 整型和浮点型 转char [] 3. 整型转 char [] (特殊函数实现) 首先请出今日主角:stdlib.h (YYDS) 这个库包含有随机数,abs等许多通用函数,当然也有类型的转换 下面我们一点点来看如何完成格式转换 一.string 和 char [] 1. string 转 char

  • C语言面试C++字符串替换空格示例

    字符串替换空格(多换一) 面试题: 面试题需要考虑规范,算法,代码,可移植性,还有鲁棒性等,考虑了这些之后再下手就会很舒服 首先我看到是%20替换空格,万一面试官说换其他的然后你很快的改了出来这也是一种本事,所以函数是必不可缺的,也最好有人机交互的样子,反正他有没有说写死. 代码 这里时间复杂度也是O(n),鲁棒性也不错,基本是可以拿下offer的代码 #include<stdio.h> #include<assert.h> #include<string.h> cha

  • C/C++中字符串流详解及其作用介绍

    目录 概述 字符串流 理解字符串流 输出字符串对象 输入字符串流对象 输入输出字符串流对象 案例一 案例二 字符数组 vs 文件 总结 概述 文件流类和字符串流类都是 ostream, istream 和 iostream 类的派生类, 因此对它们的操作方法是基本相同的. 字符串流 文件流 字符串流 概念 文件流是以外存文件为输入输出对象的数据流 字符串流也 称为内存流, 以内存中用户定义的字符数组 (字符串) 为输入输出的对象 相关流类 ifstream, ofstream 和 fstream

  • C++实现LeetCode(557.翻转字符串中的单词之三)

    [LeetCode] 557.Reverse Words in a String III 翻转字符串中的单词之三 Given a string, you need to reverse the order of characters in each word within a sentence while still preserving whitespace and initial word order. Example 1: Input: "Let's take LeetCode conte

  • C++字符串的处理详解

    目录 字符数组 总结 字符数组 双引号引起的a占两个字符,包含"\0". 字符串处理函数 连接的时候,str2中的1替换str1中的'\0'; 比较函数按照string每一个位置处的ascii值进行比较的. 计算长度的函数是不包含结束标志的. 字符串对象* 优点: 动态存储,字符串长度不再固定:自动检测字符串是否越界:封装了字符串的多种操作:能用运算符进行操作. 对于对象,可以采用方式三. C++对象不能使用gets和puts. c_str返回的是数组的首地址. C风格的字符串不可以直

  • C++字符串输入缓冲区机制详解

    目录 一.缓冲定义 1.缓冲定义 2.为什么引入缓冲区 二.scanf,cin输入缓冲区 1.scanf和cin的缓冲类型 2.scanf和cin的缓冲机制 3.cin.getline和cin.get 4.scanf和cin输入 5.可能遇到的问题 总结 一.缓冲定义 1.缓冲定义 缓冲是在两种不同速度设备之间传输信息时平滑传输过程的常用手段. 2.为什么引入缓冲区 操作系统这门课有明确的说明缓冲的作用,是为了解决高速设备和低速设备之间速度不匹配的问题,直接举个书上的CPU和打印机的例子: 首先

  • 一篇文章带你了解C++语法基础--字符串

    目录 总结 字符与整数的关联在于ASCII码:每一个常用字符都对应一个-128 ~ 127 的数字,二者之间是可以进行相互转换的: #include <iostream> using namespace std; int main(){ char wordOne = 'a'; cout << int(wordOne) << endl; int number = 66; cout << char(number) << endl; return 0;

随机推荐