给vector取下标时出现的神奇问题
就是下面的程序,首先用户随意输入任意数目的字符串,当要结束的时候,就按Ctrl+Z.然后这些字符串就被储存在vector svec里面了。然后用户随意输入一个数index,那么程序将输出svec中第index个元素(当然,如果越界的话,就取模)。可是神奇的是,当我输入
a b c d e f g h
^z
后,再输入-1,却给我显示的是svec中第3个元素。我还发现这一现象与svec的元素数目无关。这究竟是怎么回事呢?如何解决呢?
vector 下标
//
#include <iostream>
#include <vector>
#include <string>
using std::string;
using std::vector;
using std::cin;
using std::cout;
using std::endl;
void keep_window_open();
int main()
{
vector<string> svec;
string s;
cout<<"\nNow please input any number of strings with no whitespace in the center."
<<"\nTo terminate, input Ctrl+z:\n"
<<endl;
while(cin>>s)
{
svec.push_back(s);
}
cin.clear();
vector<int>::size_type n=svec.size();
cout<<"\nActually, there are "<<n<<" elements in the vector svec now.\n";
if(n>0)
{
vector<int>::size_type index;
cout<<"\nNow please input any integer between 1 and "<<n
<<".\nYes, as you may have guessed, I will show you the corresponding element of vector svec.\n"
<<endl;
cin>>index;
while(index<=0)
{
cout<<"\nMake sure to input a positive integer, OK? Try again:\n";
cin>>index;
}
index=index%n;
if(index==0) index=index+n;
cout<<"\nSo the "<<index<<"th element of vector svec is "
<<svec[index-1]<<endl;
}
keep_window_open();
}
void keep_window_open()
{
cout << "\nPress any key to exit:";
getchar();
}
[解决办法]
一般size_type都是无符号数。
http://www.cplusplus.com/reference/vector/vector/
[解决办法]
index 是 size_type 类型 是 unsigned 的
-1 转化为 unsigned 是一个很大的正数
再 svec[index-1] 的话 就越界了
你可以访问前 先判断是否越界
[解决办法]
摒弃cin,使用scanf并判断其返回值。
[解决办法]
index是size_t类型,永远不会小于0,你输入的-1实际上变成了4294967295
[解决办法]
cin输入的时候是按照变量的类型来将不同输入(应该都是字符串)转换成不同的内存表示的。输入的时候会将-1转换成所有位全都是1的变量(-1和所有位全是1的二进制表示是一样的,关键是你在操作这个数据的时候将这个内存中的数据看成有符号的还是无符号的,相同的二进制表示,使用不同的操作是可能会得到不同的结果的。在高级语言中,你不需要考虑这么多,定义了类型之后也就确定了应用在这个数据上的操作),但是长度是不同的,size_type的长度应该是未定义的,可以由C++实现来决定。
然后就是你的使用,C和C++中在对数据进行操作的时候也是要看变量的类型的。因为index是无符号数,所以<=比较的其实是无符号数,也就是所有位全都是1的数。
有点乱,如果你懂汇编的话这个问题应该很容易理解。
[解决办法]
unsigned类型,输入负数会自动转换为正数!
[解决办法]
cin能
#include <stdio.h>
char s[]="123 ab 4";
char *p;
int v,n,k;
void main() {
p=s;
while (1) {
k=sscanf(p,"%d%n",&v,&n);
printf("k,v,n=%d,%d,%d\n",k,v,n);
if (1==k) {
p+=n;
} else if (0==k) {
printf("skip char[%c]\n",p[0]);
p++;
} else {//EOF==k
break;
}
}
printf("End.\n");
}
//k,v,n=1,123,3
//k,v,n=0,123,3
//skip char[ ]
//k,v,n=0,123,3
//skip char[a]
//k,v,n=0,123,3
//skip char[b]
//k,v,n=1,4,2
//k,v,n=-1,4,2
//End.
或者
#include <stdio.h>
FILE *f;
int n,r,g;
int main() {
f=fopen("in.txt","r");
if (NULL==f) {
printf("Can not open file in.txt!\n");
return 1;
}
n=0;
while (1) {
g=0;
r=fscanf(f,"abcde%n",&g);
if (5==g) n++;
else if (0==r) fgetc(f);
else break;
}
fclose(f);
printf("%d time(s) \"abcde\" in file in.txt.\n",n);
return 0;
}
么?