一.
之前在刚刚学过结构体之后,初次编程遇到了char型变量无法(整体)输入的问题。
最初的尝试是直接定义字符指针,然后用cin直接输进去,真是异想天开。
问度娘之后得知,首先,如果想要在控制台里由I/O流读取字符串的话,用来装它的容器得是个字符数组,(把你的指针扔到一边去。。)其次,cin是不够的。需要使用库函数 gets() 。
本函数可以无限读取,不会判断上限,所以程序员应该确保buffer的空间足够大,以便在执行读操作时不发生溢出。如果溢出,多出来的字符将被写入到堆栈中,这就覆盖了堆栈原先的内容,破坏一个或多个不相关变量的值。这个事实导致gets函数只适用于玩具程序,为了避免这种情况,我们可以用fgets(stdin) (fgets实际上可以读取标准输入(即大多数情况下的键盘输入),具体参阅fgets词条)来替换gets()。在V7的手册(1979年)中说明:为了向后兼容,gets删除换行符,gets并不将换行符存入缓冲区。
由于可以无限读取,所以在2011年12月,ANSI 采纳了 ISO/IEC 9899:2011 标准,标准中删除了 gets()函数,使用一个新的更安全的函数gets_s()替代
出处:http://blog.csdn.net/wordwarwordwar/article/details/52579503
#include<iostream>
using namespace std;
int main()
{
char c;
while(1)
{
cin>>c;
cout<<c<<endl;
} //此时无论输入一个多长的字符,都可以原样输出。(大概在一个个读完输读完输了)
}
#include <iostream>
#include <cstdio> //gets()函数头文件:cstdio
using namespace std;
int main()
{
char str[100];
gets(str);
cout<<str<<endl;
return 0;
}
二。在试图使用类型数组自己搭一个数据库(忽略我这恬不知耻的叫法。。)时,使用了gets()函数,运行结果惨烈,向学长请教,得出以下结论:
源代码:
{
struct individual
{
char name[100];
int number;
int score;
};
individual class1[8];
int i=0;
while(i<8)
{
cout<<"name:"<<endl;
gets(class1[i].name);
cout<<"number:"<<endl;
cin>>class1[i].number;
cout<<"score"<<endl;
cin>>class1[i].score;
i++;
出来的效果是:第一个还好,之后就完全崩掉,name和number一起蹦出来,蹦的让人头秃。。
出现此种情况的原因是:
cin最后的换行留在缓冲区中,被gets接收走了,然后识别为空字符串。
cin貌似对开头的换行有忽略效果,不过不确定是否还留在缓冲区中。
比方说cin以后直接输入多个换行,都不会结束,而是要输点别的东西再换行才会结束。
而gets不一样,给他一个换行马上就结束。
解决办法是:完全可以不用gets(),用cin就好。。
cout<<"name:"<<endl;
cin>>class1[i].name; //直接对数组名(地址(数组指针(为啥要写这么多括弧?加深印象。。)))进行输入。
这样的实现方式没有印象,翻书,果真未曾提到,于是又回头试验对char型数组的输入方法。
结论如下:
#include<iostream>
using namespace std;
int main()
{
char s[100]={"asdqwrfadsf"}; //对这个数组的这样赋值只能在这个一开始的时候,之后就不行了。
cout<<s;
cin>>s;
cout<<s;
//s="asdkajsfdf"; //incompatible types in assignment of 'const char [11]' to 'char [100]'
//s={"asdkajsfdf"};//assigning to an array from an initializer list
s[100]={"asdkajsfdf"};//invalid conversion from 'const char*' to 'char' [-fpermissive]
}
也就是说,如果想在程序运行之后由键盘输入一个字符串,可以通过定义字符数组之后,直接写成:
cin>>数组地址;
来实现。