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

文章目录

        • 1.C 字符串
          • 1.1 输入和输出C字符串
          • 1.2 C字符串函数
        • 2.String
          • 2.1 string的输入和输出
          • 2.2 string的常用函数
        • 3.cin和getline()连用陷阱
        • 4.常用的C字符串输入输出
          • 4.1 getchar()
          • 4.2 int fgetc(FILE* stream)
          • 4.3 char *fgets(char * buf, int size, FILE *stream);
          • 4.4 gets()

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字符串函数

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

函数 描述
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++中的字符串型,包含在头文件中。

2.1 string的输入和输出

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

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

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

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

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

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

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

测试程序:

#include 
#include 

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
#include

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
#include

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标准中已经废除。

示例

C++基础之C字符串和String_第1张图片

解法

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

#include

int main(){
	int c,q = 1;
	while((c = getchar()) != EOF){
		if(c == '"') {
			printf("%s", q ? "``" : c); 
			q = !q;
		}
		else printf("%c",c);
	}
	return 0;
}

你可能感兴趣的:(#,C++基础知识)