sscanf:从具有未知出现次数的模式中检索int

时间:2012-09-10 12:53:02

标签: c++ scanf

我用fstream读取了一个ascii文件。一行包含至少两个以下patern(最多128个)的重复:

 %d %llu %d %d %llu %d %d %llu

对于每一行,我需要行

中每个模式的第三个%d的最大值

我找不到使用sscanf正确执行此操作的方法。

myFstreams->getline (buffer, MAX_BUFF-1);
while( ... ){
    sscanf (buffer," %*d %*llu %*d %d %*llu %*d %*d %*llu",&number);
    if(number>max) max=number;
    //modify buffer ???
}

任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:5)

您的方法看起来不错,感谢您使用%*来抑制分配。

您需要添加代码来检查sscanf()的返回值,并循环直到失败(即它不返回1)。在循环中,通过将每个转换值与您目前看到的最大值进行比较来保持最大值。

更新:我意识到我没有在同一行方面考虑重复模式。 D'哦。我认为一种解决方案是在模式的末尾使用%n说明符。这将写入(通过和int *参数)处理的字符数,从而允许您在行中前进,以便下一次调用sscanf()

答案 1 :(得分:1)

某种类型的东西:(代码未经测试)

#include <limits>
#include <sstream>
...

std::string line;
while(std::getline(input_stream,line))//delimit by /n
{
    auto line_ss = std::stringstream(line);
    std::string token;
    int number = std::numeric_limits<int>::min();
    int k=0;
    while(std::getline(line_ss,token,' '))//delimit by space
    {
        if(k == 3) // 3rd number
        {
            int i3;
            std::stringstream(token) >> i3; 
            number = std::max(number,i3)
        }

        k = k == 7 ? 0: k+1; //8 numbers in the set
    }
}

答案 2 :(得分:1)

scanf而不是printf使用了一种“秘密”类型,这就是为什么它经常被遗忘:%n

while( ... )
{
    //%n gives number of bytes read so far
    int bytesRead =0;
    sscanf (buffer," %*d %*llu %*d %d %*llu %*d %*d %*llu%n",&number, &bytesRead);
    if(number>max)
        max=number;
    buffer +=bytesRead;//be cautious here if using UTF-8 or other MCBS
}