C++中 char* 、string、 char、char[]在各种情况下的输入与输出

之前在自己练手写代码的时候总是会在字符串,字符这一块卡住,今天写下这篇文章给自己长长记性!

其实在代码过程中会遇到很多很玄学的问题。刚刚在尝试的时候找到了之前写的测试字符串的程序,放到另外一个工程里跑就没有问题,在原来的工程文件里跑就报错:(期间vs2019 升级了)如果有知道原因的大神还请帮忙解答一下疑惑。

在开始记录之前,我用的是vs2019的16.4.2,之前用的2019的某个版本以下这段代码是会乱码的

(是的,这么简单的代码都会有问题)

一般出现乱码都是因为字符编码出现问题,中国汉字的编码一般都是GBK开头的,而且中文属于宽字符(两个字节大小),一般abc和数字都是窄字符(一个字节大小),所以就有了wstring和wchar(感觉是专门为中文设计的),有关的资料可以去看看其他博客。我的环境之前会乱码,现在不会了。

接下来正式开始(然后再用代码加深记忆):

char:字符型基本类型,大小为1字节

string:是标准库中的一个类,既然是类就有很多函数可以通过点运算符来调用,比如常用的s.size()(返回串长) s.empty()(判断是否为空串)等等,还可以像数组一样索引他们,还可以用“+”来连接两个串。

#include<iostream>
using namespace std;

int main() {
	char c = 'a'; //注意用单引号
	char c1 = '诶';  //如前面说的,中文字符有两个字节,而char只有一个字节,所以这里c1输不出
	cout << c<<endl;  
	cout << c1 << endl;//输出空,c1作为char不能接收一个中文字符
	string a1 = "是的";
	cout << a1 << endl;
	string a2 = "不是的";
	cout << a2[2] << endl; //输出空或者其他符号,并不会输出‘是’
	cout << a2[2] << a2[3] << endl;//输出‘是’
	cout << a1 + a2 << endl;//可以用加号把两个中文字符串连接
	string c3 = "123";
	string c4 = "456";
	cout << c3[2] << endl;//对于窄字符是可以直接像数组一样索引的
	cout << c3 + c4 << endl;
	cout << c3 + a1 << endl;//加号可以把两个串连接起来,不论中英文
} 

输出:

a

是的

是
是的不是的
3
123456
123是的

注意以上注释和空白输出。

char*和char[]:

当用户自己管理字符串的时候往往有两种方法:(不使用string时)

1.字符数组char[]:就是一个数组,但是存放的类型都是字符,如果是中文字符也可以,但是每个中文字符占用两个位置。

这里三个字符但是长度显示是7,这是因为每个中文字符占用两个位置,另外为了表示一个字符串的结束位置,最后一位是‘\0’。在程序处理中,检测到‘\0’就认为一个字符结束了。

2.字符指针管理串:也就是char* ,在实际应用中,字符串的长度变化很大,将字符串作为串地址,为管理字符串提供方便。

在直接为char*赋值时候可以采取如下形式:

const char* s = "你瞅啥";

系统上实际完成两步操作:首先申请堆空间,然后填入串值。至于这里为什么要用const,看后面代码的注释。

这里的代码尝试了常用的输入输出情况:(留意注释)

#include<iostream>
using namespace std;

int main() {
	const char* s = "你瞅啥";//为什么要用const:含义是先新建一个字符串,内容是“你瞅啥” 然后str1是一个头指针,指向这个串. 
	                         //但是这个新建串是作为const存在的,并不是一个可以编辑的变量,因此,一旦你想更改其中的值,程序就会挂掉.
	const char* s1 = "omg"; //去掉const会报错
	char s2[5] = "我c";//加上花括号也是可以的

	cout << s << endl; //直接将串全部输出
	cout <<*(s)<< *(s + 1) << endl;//类比string,由于这里是中文字符,所以这种操作是会输出第一个中文字符的
	cout << *(s1 + 1) << endl;//这里s1是英文字符,也就是说直接读出
	cout << s2 << endl;//也是直接输出s2
	cout << s2[2] << endl;//输出单个字符

	char* in=new char[20]; //在使用char* 但是未初始化的时候是需要先声明空间大小的,否则报错
	cout << "请输入in:";
	cin >> in;
	cout << in << endl;
	char in1[20];
	cout << "请输入in1:";
	cin >> in1;
	cout << in1 << endl;
	string str;
	cout << "请输入str:";  //这里这三种输入都直接输入就好,但是不能包含空格
	cin >> str;
	cout << str << endl;

	char* strc = &str[0]; //根据char*的本质,它是指向字符首个地址的,所以,
	//只要把str第一个字符的地址给char *,就可以完成整个字符串的拷贝。但是他只是指针,strc并不能真正保留str的初始内容
	//后面代码中只要再次修改str,strc也会随之改变
        cout << "请输入新的str:";
	cin >> str;
	cout << strc << endl;
}
你瞅啥
你
m
我c
c
请输入in:in
in
请输入in1:in1中文也可
in1中文也可
请输入str:666嘿嘿
666嘿嘿
请输入新的str:一起改变
一起改变

感觉总的来说输入输出都比较直观易懂,但是我总记得我之前给字符串赋值或者输出的时候的时候还要用到for循环。。。

但是我们有时候便于管理还是要用到char* name[],就是指针数组,放着很多个字符串在里头。

#include<iostream>
using namespace std;

int main() {
	const char* str[3] = {"奥 利 给","这就是你分手的借口","干啥嘞"};
	//cout << "请给str赋值:";
	
	//cout << "赋值结束" << endl;
	cout << str<<endl; //输出地址
	cout << str[0]<<endl;//输出字符串,因为有中括号,这里表示数组内的元素
	cout << &(str[0])<<endl;
        char test[] = "wtf?";
        char* sp = test;
	cout << sp << endl;

}

 输出:

007DFD20
奥 利 给
007DFD20
007DFD24
wtf?

验证了一句话: 数组名字代表着这个数组的首地址,也是第一个元素的地址

 

在实际运用中,cstring这个库里面有一些我们常用的函数比如strlen(char* or char[])返回串长度,strcpy_s(des,src)复制串,但是这些就不在这次的讨论范围了。

综上,建议多用String。

(比较基础的东西,如果有错误还请指出)

 

  • 22
    点赞
  • 90
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
在这份代码,存在一些问题: 1. 在ReplaceString函数,result指针没有进行动态内存分配,没有为其分配足够的内存空间,会导致程序崩溃。 2. 在使用strcat函数将字符拼接到result指针时,应该传入字符指针而不是字符。 3. 在最后将结束符'\0'拼接到result指针时,应该使用字符串形式的'\0',而不是字符形式。 针对以上问题,可以对代码进行改进。改进后的代码如下: ```c++ #include <iostream> #include <cstring> using namespace std; char* ReplaceString(char* str, char* s1, char* s2); int main() { char str[100], s1[10], s2[10]; cin >> str >> s1 >> s2; char* result = ReplaceString(str, s1, s2); cout << result << endl; delete[] result; // 释放动态分配的内存空间 return 0; } char* ReplaceString(char* str, char* s1, char* s2) { int a = strlen(s1); int b = strlen(s2); int c = strlen(str); char* result = new char[c * b + 1]; // 动态分配足够的内存空间 char* p = str; result[0] = '\0'; while (*p != '\0') { if (strncmp(p, s1, a) == 0) { strcat(result, s2); p += a; } else { char temp[2] = {*p, '\0'}; strcat(result, temp); p++; } } strcat(result, "\0"); // 使用字符串形式的'\0' return result; } ``` 在这里,首先为result指针分配了足够的内存空间,避免了程序崩溃问题。然后,在使用strcat函数拼接字符时,传入了字符指针,避免了编译错误。最后,在拼接结束符'\0'时,使用了字符串形式的'\0',确保了新字符串的正确性。同时,在main函数,通过delete[]释放了动态分配的内存空间,避免了内存泄漏问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值