C ++上的简单转换转换

时间:2015-12-07 22:15:38

标签: c++ casting

我正在为大学做练习,我必须比较一个包含标题<string>的字符串和一个字符。

我有一个文本文件,其中包含来自人口普查的几行数据,例如

  

Alabama AL 4849377
Alaska AK 736732
Arizona AZ 6731484

我想用字符串变量读取每一行的状态名称,但比较是我要求的唯一内容,因为我有错误。

我有这段代码:

    struct Census{
    string name;
    int population, code;
};

struct States{
    Census state;
};

typedef States Vector[US_STATES];

void loadCensus(ifstream & census, Vector stats){
    int i=0;
    string readData;
    string line;
    while (getline(census, line)) {
        stringstream linestream(line);
        while (linestream >> readData) {
            if (linestream >> stats[i].state.name >>
                stats[i].state.code >>
                stats[i].state.population)
            {
                std::cerr << "Bad input on line " << i << ": " << line << std::endl;
            }
            stats[i].state.name=readData;
            stats[i].state.code=readData;
            stats[i].state.population=readData;
            i++;
        }
    }
}

如何将readData转换为整数以分配stats [i] .state.population = readData? 我在第7行的第line行&gt;&gt;中收到错误READDATA。

2 个答案:

答案 0 :(得分:1)

您想要使用getline()函数。  我认为它是ifstream的成员函数,或者将非readData与字符串进行比较(&#34; \ n&#34;) - 双引号。或者将读取的数据放入一个字符串中并检查刺痛是否包含&#39; \ n&#39;。

答案 1 :(得分:0)

census >> readData将从输入中读取下一个单词(任何一组非空白字符)。为了做到这一点,它将丢弃其寻找下一个单词的所有空格。 '\n'是空格,所以你永远不会用>>运算符读取它而不玩你可能不想玩的游戏。

而不是>>,请使用std::getline读取一行,然后使用std::stringstream将该行划分为单词。

std::string line;
while (std::getline(census, line)) {
    std::stringgstream linestream(line);
    while (linestream >> readData) {
        statistics.state[i]=readData;
        i++;
    }
}

但是...

我不相信statistics.state[i]=readData;完全符合您的要求。你可能想要更像的东西:

std::string line;
while (std::getline(census, line)) {
    std::stringstream linestream(line);
    if (!(linestream >> statistics.state[i].name >>
                      statistics.state[i].abbreviation >> 
                      statistics.state[i].population))
    {
        std::cerr << "Bad input on line " << i << ": " << line << std::endl;
    }
    i++;
}

在此state中成为对象的数组或向量,可能看起来像

struct statestats
{
    std::string name;
    std::string abbreviation;
    int population;
};

逐行分解

std::stringstream linestream(line);

制作字符串流。字符串流是类似cin和cout或fstream的流,但它包含一个字符串。主要用途是使用与在另一个流上使用的语法相同的语法来缓冲和构建字符串。在这种情况下,我们使用它将行分成单词。

if (linestream >> statistics.state[i].name >>
                  statistics.state[i].abbreviation >> 
                  statistics.state[i].population)

需要在几个部分中处理几个部分。总而言之,它是

的缩写
if (linestream >> statistics.state[i].name && 
    linestream >> statistics.state[i].abbreviation &&
    linestream >> statistics.state[i].population)

每个阶段从线流读取变量。

接下来,>>运算符返回正在读取的流,这在示例中以两种方式使用。第一个允许链接。一个>>的输出用作下一个的输入,所以如果你看一下&gt;&gt;就像你想要一个函数(and it is a function. See Stream extraction and insertion for more)一样,你可以认为它看起来像这样:

linestream.read(statistics.state[i].name).read(statistics.state[i].abbreviation).read(statistics.state[i].population)

>>语法使其更容易。

从返回流中获得的下一个好处是可以测试流以查看流是否仍然良好。它有一个boolean operator,如果流处于良好状态并且可以使用,它将返回true。

if(linestream)
{
    good
}
else
{
    bad
}
如果流已打开,未到达流的末尾,并且没有读取或写入数据的麻烦,

将输入良好状态。

回到我们的例子

if (linestream >> statistics.state[i].name >>
                  statistics.state[i].abbreviation >> 
                  statistics.state[i].population)

如果流成功读取流中的所有三个值,则将输入if语句的主体。这不是我们想要的。糟糕!我已经纠正了上面的代码。

if (!(linestream >> statistics.state[i].name >>
                    statistics.state[i].abbreviation >> 
                    statistics.state[i].population))

将进入if if的主体,至少有一个值因任何原因未被读取并打印出错误消息。通常当出现错误时,您需要clear the error才能继续,但在这种情况下,我们会使用整个流并即将丢弃它。

假设没有发生错误,已经读取了该行的所有数据,并且不需要

stats[i].state.name=readData;
stats[i].state.code=readData;
stats[i].state.population=readData;