C++基础之C字符串和String


C字符串在C语言中非常流行,但是被C++中更健壮、更方便、更有用的string类型替代了。


1.C 字符串

C字符串是一个字符数组,以’\0’空终结符结尾,显示了内存中的字符串是如何结尾的。每一个字符串值都是一个C字符串,因此可以声明一个数组并用字符串值来初始化它。

char city1[8] = "Beijing";  // C-string
char city2[] = {'B','e','i','j','i','n','g'};    // Not a C-string

注意,city1数组大小是8,最后一个字符是’\0’。

1.1 输入和输出C字符串

标准输入输出:
接受一个字符串,遇到“空格”、‘“TAB”、“回车”结束。

char s[8];
cin >> s;   // scanf("%s",s);
cout << s << endl;

cin.getline(char array[], int size, char delimitchar)
当遇到 终结符delimitchar(默认是“\n”)或者读取了size-1个字符后函数停止读入字符,最后一个字符被空终结符替代。

char s1[10];
char s2[10];
cin.getline(s1,10);  //遇到"\n"结束
cin.getline(s2,8,' '); //遇到' '结束 ,且只读入7个字符

sscanf(const char* str,const char* format_string, [args])
sscanf()类似于scanf(),只不过scanf()是从标准输入到变量,而sscanf()是从字符串输入到变量。

char str[100] = "12345";
	int a;
	sscanf(str, "%d", &a);
	int b = 678;
	sprintf(str, "%d", b);
	cout << str << endl << a << endl;
	// 678 12345

sprtinf(char* buffer,const char* format_string [,args])
sprintf函数类似于printf(),都需要一个格式化串format_string,以及相应代替的字符args,作用是将字符串输出到缓冲区buffer。

char str[100];
double f = 3.1415926;
sprintf(str, "%.3lf", f); // 3.142
printf("%s\n", str);
char s1[] = "hello";
char s2[] = "world";
sprintf(str, "%s %s", s1, s2); // hello world
printf("%s\n", str);
1.2 C字符串函数

所有函数均在头文件<cstring>下,除了转换函数atoi、atof、atol、itoa、ftoa在头文件<cstdlib>下。

函数描述
size_t strlen(char s[])返回字符串的长度
strcpy(char s1[] , const char s2[])将字符串s2复制到s1中
strncpy(char s1[] , const char s2[], size_t n)将字符串s2中前n个符号复制到s1中
int strcmp(char s1[], char s2[])若s1等于s2,则返回0;若s1小于s2,则返回-1;若s1大于s2,z则返回1
char *strcat (char *dest,const char *src)将参数src字符串拷贝到参数dest所指的字符串尾,第一个参数dest要有足够的空间来容纳要拷贝的字符串,返回dest字符串参数的起始地址;
int atoi(char s[])返回字符串对应的int型值
double atof(char s[])返回字符串对应的double型值
long atol(char s[])返回字符串对应的long型值
char* strchr(const char* s,char c)查找字符串s中字符c首次出现的位置,并返回该位置的指针;若s中不存在c,则返回NULL
char* strstr(const char* str1,const char* str2)查找字符串中str1中字符串str2首次出现的位置,并返回该指针;若不存在,则返回NULL

注,
atoi 相当于 array to integer
strchr 相当于 string -char
strstr 相当于 string - string
对于为什么C字符串的赋值、比较、连接操作不能直接进行,因为其本质上是字符数组,对数组的操作不能像基本数据类型那么直接

一下函数均在头文件ctype.h

函数描述
isalpha(char c)字符c是否是大写
isdigit(char c)字符c是否是数字
isprint(char c)字符c是否是可打印字符
toupper(char c)转换大写
tolower(char c)转换小写

注,
当你明白了字符在计算机中以ASCII码存储
则上面函数是可以自己实现的,例如

char toUpper(char c) {
	if (c >= 'a' && c <= 'z') return c - 'a' + 'A';
	else return c;
} 
2.String

String是C++中的字符串型,包含在头文件<string>中。

2.1 string的输入和输出

标准输入输出:
接受一个字符串,遇到“空格”、‘“TAB”、“回车”结束。

string s;
cin>>s;
cout << s << endl;

getlin(cin,str,delimitchar)
包含在头文件<string>中,接受一个字符串,可以接收空格,也可以自己指定终结符delimitchar。

注意,cin.getline()属于istream流;
getline()属于string流,是两个不同的函数。

getchar()
接受一个字符,需要包含头文件<string>

2.2 string的常用函数
函数描述
stoistring转int
stofstring转float
stodstring转double
to_string数字转string
substr(begin [,n])返回从begin位置开始的n个字符组成的子串
size()或length()返回字符串的长度
str1.compare(str2)字符串比较

注意:
在 C++中string是一个类,所以调用某些函数的格式object.substr(begin,n);

测试程序:

#include <iostream>
#include <string>

using namespace std;

int main() {
    string str = "123";
    int a = stoi(str);
    cout << a;
  	str = "123.44";
    double b = stod(str);
    cout << b;
    return 0;
}
/*
stoi如果是非法输入:
1.会自动截取最前面的数字,直到遇到不是数字为止
    (所以说如果是浮点型,会截取前面的整数部分)
2.如果最前面不是数字,会运行时发生错误
*/

/*
 stod如果是非法输入:
 1.会自动截取最前面的浮点数,直到遇到不满足浮点数为止
 2.如果最前面不是数字或者小数点,会运行时发生错误
 3.如果最前面是小数点,会自动转化后在前面补0
 */

/*
相应的还有:
stof(string to float)
stold(string to long double)
stol(string to long)
stoll(string to long long)
stoul(string to unsigned long)
stoull(string to unsigned long long)
*/
3.cin和getline()连用陷阱
#include<iostream>
#include<string>

using namespace std;

int main(){
	string name;
	string local;
	cout<<"输入你的名字:\n";
	cin>>name;
	cout<<"输入你的所在地:\n";
	getline(cin,local);
	cout<<"名字:"<<name<<endl;
	cout<<"所在地:"<<local<<endl;
}

输入和输出

输入你的名字:
jack
输入你的所在地:
名字:jack
所在地:

可以看见在请求输入所在地的时候,自动跳过了。

而输入jack c
则输出
名字:jack
所在地: c

原因:在输入流中,jack后面还留有一个换行符被getline()所吸收,且停止读入了。

解决办法
使用getchar()或者cin.get()等方法将换行符吸收掉。

#include<iostream>
#include<string>

using namespace std;

int main(){
	string name;
	string local;
	cout<<"输入你的名字:\n";
	cin>>name;
	getchar(); //cin.get();
	cout<<"输入你的所在地:\n";
	getline(cin,local);
	cout<<"名字:"<<name<<endl;
	cout<<"所在地:"<<local<<endl;
}
4.常用的C字符串输入输出

在前文,我们知道scanf()遇到空格、回车、换行以及Tab会停止,有时候为了输入包含这些字符的字符串,我们需要其他的输入函数。

4.1 getchar()

从标准输入stdin中读取一个字符,返回值为int。
当用户键入回车之后,getchar才开始从stdin流中每次读入一个字符,
getchar函数的返回值是用户输入的第一个字符的ASCII码,出错返回-1。
如用户在按回车之前输入了不止一个字符,其他字符会保留在键盘缓存区中,等待后续getchar调用读取。

4.2 int fgetc(FILE* stream)

读取一个打开的文件stream,然后读取一个字符后返回一个Int值。
同时getchar()等效于fget(stdin)。

至于为什么返回int值

因为文件结束符EOF是一个宏定义,#define EOF -1,值为-1,若返回char值,则EOF的值为0xFF,本身是另外一个字符的ASCII码值。所以一般返回一个int值,再判断它是不是EOF后将其转换成char值。

4.3 char *fgets(char * buf, int size, FILE *stream);
  • 从 stream 流中读取 size - 1 个字符存储到字符指针变量 buffer 所指向的内存空间
  • 然后在末尾添加一个\0,且一旦读到回车\n,则读取停止
  • 所以可用于读取一行,而这个“\n”也会是buf字符串中最后一个有效字符(再往后就是字符串结束 符“\0”了)。
  • 它的返回值是一个指针,指向字符串中第一个字符的地址。
4.4 gets()

和fgetc类似,fgets(stdin)有一个标准输入版gets(s),但是gets(s)没有指明最大读取数,所以会不停地往s中存储内容,存在缓冲区溢出的风险,不推荐使用,且在C11标准中已经废除。

示例

在这里插入图片描述

解法

使用getchar()不断读取字符直到遇到换行符

#include<stdio.h>

int main(){
	int c,q = 1;
	while((c = getchar()) != EOF){
		if(c == '"') {
			printf("%s", q ? "``" : c); 
			q = !q;
		}
		else printf("%c",c);
	}
	return 0;
}
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值