scanf 和 cin 对string 的输入 和坑点

版权声明:如果是原创仅供参考,转请标明出处。 https://blog.csdn.net/oShuaiFeng/article/details/80712211

写这个源于 一道题 《1028 人口普查(20)(20 分)》

前言:在网络上 我常常会看见有人说 cin>>的效率慢 不如 scanf 。经过测试 的确是这样子。既然cin>>输入慢 为什么还要用呢?抛开很多很多的问题比如:

1.cin>>可以对类似string 类型进行直接输入。

2.cin>>可以自动转换类型,不需要像scanf写的那么麻烦。

3.等等

// 实验之前 先说下一些已知的结论 因为考虑到 可能有些人不愿意看我实验的内容,可能是因为我太水了吧。--哭~

1.  string使用 scanf进行输入是这样输入的:

	string s;
	scanf("%s",&s[0]);
直接
scanf("%s",s); //无法完成赋值 赋值结束后字符串 s 为空

2.使用scanf给 string 直接结构体赋值后 无法传递给 下一 string的变量。

struct sn {
	string t;
}K,P;

void solve() {

	string s;
	scanf("%s",&K.t[0]);
	P = K;
	s = K.t;
}

答案是:当K.t被正常赋值以后P.t 为空 s也为 空


造成这个原因的是 没有加上 resize(num);这个函数 num是正整数 表示初始化string多少空间。 

    接下来不想讲太多 我还要留一些下面讲 , 不想看的 可以关掉页面了。== (今天怎么啦?)(不说。。~)

//


那么问题来了 我如何使用 scanf()对string进行输入呢?又有什么不同的地方,适不适用 gets ?

这次主要做一个实验:


实验工具: VS2017 , codeblock 17,VC++6.0 不一定全部用上。因为我记得 2017里是没办法使用 gets的 ,它提供了一个叫做gets_s的安全函数 一会也会进行测试。


一般情况之下 我们对 string 类型的变量赋值的时候会使用 cin>> 赋值 两个string值之间可以 使用等于号进行赋值,这个是我们的常识:

比如:

string s,t;
cin>>s;
t = s;

那么 string 类型的数据 在输入后其实也可以像 char 类型的数组一样是一个连续的空间 那么就是因为这个特性 才能用scanf进行输入。那么输入的方法是:对空间的第一个元素所在的地址进行输入。那么我们早就知道对char 数组 或是 char* 空间数组的赋值方法是

char s1[900];
scanf("%s",s1);
scanf_s("%s",s1,sizeof(s1)); // 新版编译器  OJ 不支持
gets(s1);
gets_s(s1,sizeof(s1)); // 新版编译器        OJ 不支持

那么我们推出 使用 scanf对 string 进行输入的方法:

string s;
s.resize(10000);
scanf("%s", &s[0]);

有些人会说 s.resize(10000);这条语句我不加 也可以赋值成功啊~ 他们给我看的是这样的情况(输入NTSD)


赋值成功!! 但是 这是很危险的 我们使用更长的字符串的时候就会赋值失败 比如:


但是我们 启用 resize 的话情况就会不一样。如图:


这样才是正规的写法,但是我们今天不仅研究这个。我们来看看赋值的操作吧。

 直接使用等号赋值的是成功的!!!那今天的实验到此为止么?不是 因为赋值成功还有特例 让它赋值不成功

我们来看 那个最特殊的 特例 让这种方法彻底失败。当然也是犯了一个错误所导致的 resize(num); 

这个最特殊的特例就是 --- 结构体的整体赋值下。或是 结构体中的string赋值给局部(全局)变量下。


如果不加 resize(num);就会出现赋值失败的问题。 


加上就会好了:

RT



由于 VS2017上没有 gets 那么我们使用 vc++6.0来看一下吧!gets也是能正常的赋值的。


然后我使用子函数 在VS2017上模拟了一下 gets 

int gets(char *s) {

	for (char t, *p = s; t = getchar(), s!=NULL&&t != '\n'; p++, *p = 0)
		*p = t;
	return s != NULL ? strlen(s) : 0;
}

也能成功赋值。我觉得这个也是一个替代方案吧 毕竟摆着 cin>>不用 用这个还是很多坑点的啊!!~~

本来想上一下反汇编的~~~但是我也不精反汇编 怕说错被笑 哈哈~~


好好学习,天天向上,加油哦~


猜你喜欢

转载自blog.csdn.net/oShuaiFeng/article/details/80712211