使用stringstream将字符串转换为int

时间:2017-04-29 23:54:38

标签: c++ string int

这是我的功能

void global::readData(lifeform &p)
{
std::ifstream ifs("data.txt");
int i=0,i_str=0;
std::string str,str2;
std::getline(ifs,str);
std::stringstream ss(str);

if(i<31) {
    std::getline(ss,str2,',');
    std::istringstream toint(str2);
    toint >> i_str; 
    if(i_str ==1) {   //here i_str can get 1
        p.newgame=1;
        while(i<31) {
            std::getline(ss,str2,',');

            toint >> i_str; 
            if(i==0) {

                p.setName(str2);       //this also works

            }
            if(i==1) {

                p.setMaxHp(i_str);        //doesnt work

            }

            if(i==2) {

                p.setQName("main",str2);        //works

            }
             i++;
             //....
     }
   }

这是data.txt

  

1,furkan,100,没有任务,

我试着把data.txt上的内容写到str.there到目前为止没有问题。之后我想将字符串转换为int它在第一次转换中工作但不是其余的

我将1更改为0以查看它是否有效并且它可以正常工作,但其余 i_str 无法正常工作

2 个答案:

答案 0 :(得分:0)

1)std::istringstream获得他自己的str2的副本。它不会观察此变量的变化。

2)你应该怎么做:

char c;
ss>>i_str//read int value from stream
>>c;//and throw away separator

这里你不需要getline。

答案 1 :(得分:0)

警告:这个答案对于手边的具体工作来说有点过分。它使用了一些相当通用的实用程序,使工作变得简单,但如果这是你唯一使用它的时间/地点,可能值得写(但事实并非如此)一旦你拥有它们,一般非常有用)。我将它们保存在&#34; input_utils.h&#34;中,我几乎可以很容易地使用它们。

第一个是常量字符串的输入运算符。这可能听起来毫无意义(如果它不变,你显然无法读入它)。它的作用是从流中读取一些固定输入,并验证流中的内容是否符合您的预期。代码如下所示:

std::istream &operator>>(std::istream &is, char const *label) {
    if (is.flags() & std::ios::skipws)
        while (std::isspace((unsigned char)is.peek()))
            is.ignore(1);

    while (is.peek() == *label) {
        is.ignore(1);
        ++label;
    }
    if (*label) 
        is.setstate(std::ios::failbit);

    return is;
}

这使我们可以非常轻松地阅读(大部分)输入中的逗号 - 验证它们是否存在,但忽略它们。所以,要读取以逗号分隔的三个数字,我们会这样做:

input_stream >> number1 >> "," >> number2 >> "," >> number3;

至少在我看来,这个含义看起来非常简单,直接而且显而易见(而且对手头工作的适用性似乎也同样明显)。

第二个具有明确而明显的意图,但实施的重要性不如我想要的那么简单(但我不知道如何让它更简单并且仍然可以完成工作)。它的代码如下:

class line_proxy {
    std::string &s;
    char delim;
public:
    line_proxy(std::string &s, char delim) : s(s), delim(delim) {}

    friend std::istream &operator>>(std::istream &is, line_proxy const &p) {
        std::getline(is, p.s, p.delim);
        return is;
    }
};

line_proxy line(std::string &in, char delim = '\n') {
    return line_proxy(in, delim);
}

我们这样使用它:

std::string s;

input_stream >> line(s); // equivalent to `std::getline(input_stream, s);`

同样,即使实现有点复杂,使用似乎也很明显(至少对我而言)。

一旦我们拥有了这些,你的工作就会变得微不足道。我最初看起来有点困难的一部分就是在lifeform类的流提取运算符中实现读取:

#include "input_utils.h"

struct lifeform {
    int index;
    std::string name;
    int level;
    std::string mission;

    friend std::istream &operator>>(std::istream &is, lifeform &f) { 
        return is >> f.index 
                  >> "," 
                  >> line(f.name, ',') 
                  >> f.level 
                  >> "," 
                  >> line(f.mission, ',');
    }

我们可能希望能够写出一个lifeform:

friend std::ostream &operator<<(std::ostream &os, lifeform const&f) {
    return os << "Index: " << f.index 
              << ", name: " << f.name 
              << ", level: " << f.level 
              << ", mission: " << f.mission;
}

...还有一些代码来测试它们并看到它们正常工作:

int main() {
    std::istringstream input("1,furkan,100,No mission,");

    lifeform f;
    input >> f;
    std::cout << f;
}