首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >根据类型对字符串流进行标记

根据类型对字符串流进行标记
EN

Stack Overflow用户
提问于 2012-10-07 02:59:18
回答 6查看 1.4K关注 0票数 1

我有一个包含整数和特殊含义字符'#‘的输入流。看起来是这样的:... 12 18 16 # 22 24 26 15 # 17 # 32 35 33 ...标记之间用空格隔开。“#”的位置没有模式。

我试图像这样对输入流进行标记:

代码语言:javascript
运行
复制
int value;
std::ifstream input("data");
if (input.good()) {
  string line;
  while(getline(data, line) != EOF) {
    if (!line.empty()) {
      sstream ss(line);
      while (ss >> value) {
        //process value ...

      }
    }
  }
}

此代码的问题是,当遇到第一个'#‘时,处理会停止。

我能想到的唯一解决方案是将每个单独的标记提取为一个字符串(而不是'#'),并使用atoi()函数将该字符串转换为整数。然而,它的效率非常低,因为大多数标记都是整数。在令牌上调用atoi()会带来很大的开销。

有没有一种方法可以根据令牌的类型来解析单个令牌?也就是说,对于整数,将其解析为整数,而对于'#',则跳过它。谢谢!

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2012-10-07 03:06:51

一种可能是显式地跳过空格(ss >> std::ws),然后使用ss.peek()来查看后面是否有#。如果是,则使用ss.get()读取并继续,否则使用ss >> value读取该值。

如果#的位置无关紧要,您还可以在使用'#'初始化stringstream之前从行中删除所有它。

票数 2
EN

Stack Overflow用户

发布于 2012-10-07 05:07:32

通常不值得对good()进行测试

代码语言:javascript
运行
复制
if (input.good()) {

除非您的下一个操作是生成错误消息或异常。如果它不好,那么所有进一步的操作都将失败。

不要对EOF进行测试。

while(getline(data,line) != EOF) {

std::getline()的结果不是整数。它是对输入流的引用。输入流可以转换为布尔型对象,可以在布尔型上下文(如whileif等)中使用。所以你想做的是:

代码语言:javascript
运行
复制
while(getline(data, line)) {

我不确定我会不会读一行。你可以只读一个单词(因为输入是空格分隔的)。在字符串上使用>>运算符

代码语言:javascript
运行
复制
std::string word;
while(data >> word) {  // reads one space separated word

现在您可以测试单词,看看它是否是您的特殊字符:

代码语言:javascript
运行
复制
if (word[0] == "#")

如果不是,则将该单词转换为数字。

这就是我要做的:

代码语言:javascript
运行
复制
// define a class that will read either value from a stream
class MyValue
{
  public:
    bool isSpec() const {return isSpecial;}
    int  value()  const {return intValue;}

    friend std::istream& operator>>(std::istream& stream, MyValue& data)
    {
        std::string item;
        stream >> item;
        if (item[0] == '#') {
            data.isSpecial = true;
        } else
        {   data.isSpecial = false;
            data.intValue  = atoi(&item[0]);
        }
        return stream;
    }
  private:
    bool isSpecial;
    int  intValue;
};

// Now your loop becomes:
MyValue  val;
while(file >> val)
{
    if (val.isSpec())  { /* Special processing */ }
    else               { /* We have an integer */ }
}
票数 2
EN

Stack Overflow用户

发布于 2012-10-07 03:09:27

也许你可以把所有的值都读成std::string,然后检查它是不是"#“(如果不是--转换成int)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12762865

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档