【问题标题】:Advance File Pointer to skip over number in a file高级文件指针跳过文件中的数字
【发布时间】:2011-09-14 02:25:53
【问题描述】:

我想知道是否可以在文本文件中跳转位置。 假设我有这个文件。

12
8764
2147483648
2
-1

每当我尝试读取第三个数字时,它都不会读取,因为它大于 32 位 int 的最大数字。因此,每当我达到第三个数字时,它就会一遍又一遍地读取第二个数字。如何跳转到第 4 个数字?

【问题讨论】:

  • 可以选择使用更长的整数吗?

标签: c++ file file-pointer


【解决方案1】:

使用 std::getline 代替运算符>>(std::istream, int)

std::istream infile(stuff);
std::string line;
while(std::getline(infile, line)) {
    int result;
    result = atoi(line.c_str());
    if (result)
        std::cout << result;
}

您遇到这种行为的原因是,当 std::istream 尝试(但失败)读取整数时,它会设置一个“badbit”标志,这意味着出现问题。只要那个 badbit 标志保持设置,它就不会做任何事情。所以它实际上并没有重新阅读该行,它什么都不做,只留下曾经存在的价值。如果您想与已有的内容保持一致,可能如下所示。上面的代码更简单,更不容易出错。

std::istream infile(stuff);
int result;
infile >> result; //read first line
while (infile.eof() == false) { //until end of file
    if (infile.good()) { //make sure we actually read something
        std::cout << result;
    } else 
        infile.clear(); //if not, reset the flag, which should hopefully 
                        // skip the problem.  NOTE: if the number is REALLY
                        // big, you may read in the second half of the 
                        // number as the next line!
    infile >> result; //read next line
}

【讨论】:

  • atoi 什么时候对std::string 有过载??
  • 这样做的“C++ 方式”是 stringstream,这有点令人恼火,它有复制整个字符串的开销,然后可能只是在里面调用 atoi。
  • 事实上,如果有一个类似矢量的容器可以使用外部缓冲区来处理 C-API,那就太好了。我想我在某个地方有一半。
  • 你的意思是,std::vector&lt;char&gt;?这是一个非常通用的样本...您也可以轻松地将其转换为 std::string
【解决方案2】:

您可以先读取该行,然后如果可以,将该行转换为整数。这是您的文件的示例:

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>

int main()
{
    std::ifstream in("file");
    std::string line;
    while (std::getline(in, line)) {
        int  value;
        std::istringstream iss(line);
        if (!(iss >> value)) {
            std::istringstream iss(line);
            unsigned int uvalue;
            if (iss >> uvalue)
                std::cout << uvalue << std::endl;
            else
                std::cout << "Unable to get an integer from this" << std::endl;
        }
        else
            std::cout << value << std::endl;
    }
}

【讨论】:

  • 我考虑过 istringstream(因为它“更正确”),但我决定,因为他似乎只有数字,所以使用 atoi 更快更简洁。如果他有更多的数字,那么这是更好的答案。此外,他似乎只关心带符号的 32 位范围内的值,因此可以删除内部的 iss
【解决方案3】:

作为使用std::getline() 的替代方法,您可以致电std::ios::clear()。考虑一下你的previous question的这段摘录

    fin >> InputNum;

您可以用以下代码替换该代码:

    fin >> InputNum;
    if(!fin)
        fin.clear();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-06
    • 2014-05-25
    • 1970-01-01
    • 1970-01-01
    • 2018-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多