2011-11-04 148 views
0
//sLine is the string 
for(int l = 0; l < sLine.length(); l++) 
{ 
    string sNumber; 
    if(sLine[l] == '-') 
    { 
     sNumber.push_back(sLine[l]); 
     sNumber.push_back(sLine[l + 1]); 
     l++; 
    } 
    else if(sLine[l] != '\t') 
    { 
     sNumber.push_back(sLine[l]); 
    } 
    const char* testing = sNumber.c_str(); 
    int num = atoi(testing); 
    cout << num; 
} 

我有这个for-loop,它检查字符串的每个字符并将此字符串中的每个数字转换为int。但由于某种原因,atoi函数做了两次,所以当我关闭它时,它会出于某种原因显示它两次......为什么?C++将字符串转换为int

例如: INPUT 3 3 -3 9 5
-8 -2 9 7 1
-7 8 4 4 -8
-9 -9 -1 -4 -8

OUTPUT 3030-309050 -80-20907010
-70804040-80
-90-90-10-40-80

+3

'sNumber.push_back(sLine [l + 1]);'可以超出字符串结束。 – Vlad

+0

@Vlad但我已经把那里,因为负数... – Danny

+0

它执行整个循环两次。 –

回答

10

它显示所有nonrecognized字符的零,因为atoi回报0给出一个非数字字符串时

但是,你想要做什么,是令人震惊的简单:

std::stringstream ss(sLine); 
int num; 
while(ss >> num) { 
    cout << num; 
} 
0

移动这样的:

const char* testing = sNumber.c_str(); 
int num = atoi(testing); 
cout << num; 

低于您粘贴的代码中的最后一个},即超出for-loop。目前,您在sLine中为每个字符分别打印输出,因为它在循环的每次迭代中都执行。 (在sLine的最后一个字符可能是一个换行符所以,即使你认为你只写了一个数字可能出现这种情况。)

编辑:亦动上述 for循环的sNumber声明。

您可能还希望将if (sLine[l] == '-')更改为if (sLine[l] == '-' && (l + 1) < sLine.length()),因此如果连字符是最后一个字符,则不会访问超出字符串的末尾。

您可能还想将变量l重命名为看起来不像1的东西。 =)

您可能还需要重新考虑,如果这是在所有做到这一点(通常,如果一个简单的事情变得复杂,这种正确的方式,那么你就错了)。 (!就像一个空格)

+0

sNumber会超出范围 –

+0

注意和编辑,谢谢。 – Arkku

0

您为非数字字符输出额外0。问题是atoi在无法转换输入时返回0,因此您的空格被打印为零。

0

这似乎是一个痛苦的方式来重新创建轮子。你最好用stringstream来解析这个。

std::stringstream strm(sLine); 
int num; 
while(strm >> num) 
{ 
    std::cout << num << std::endl; 
} 
+3

请不要鼓励使用'eof()'或'fail()'作为循环条件。这样做几乎总是会导致错误的代码。而不是'while(strm >> num){...}'。为了演示'eof()'的邪恶力量:http://ideone.com/ZKa67 –

+0

@Rob感谢您的演示。将编辑答案。 – Jon