2017-02-01 67 views
1

我工作一个文件,在这个文件内容:“hello_READHERE_guys”。如何只读取“READHERE”位置?C++ ifstream读取偏移范围

我尝试这种代码和失败:

std::ifstream is("test.txt"); 

if (is.good()) 
{ 
    is.seekg(5, ios::end); // step from end "_guys" 
    is.seekg(6, ios::beg); // step from start "hello_" 

    std::string data; 

    while (is >> data) {} 

    std::cout << data << std::endl; // output "READHERE_guys" fail. 
} 
+0

您应该阅读'seekg'的文档。它没有定义“范围”,它只是移动读取位置。 – molbdnilo

+0

我缓解了文档,并试图不工作。请帮帮我。 –

+0

Windows api ReadFile函数给nNumberOfBytesToRead。 ifstream我该怎么办? –

回答

2
The seekg function

不仅设置下一个字符的位置被从输入流萃取。它不能设置“限制”停止。因此,以下行:

is.seekg(5, ios::end); // step from end "_guys" 

错误。使用seekg与ios::end不会设置限制。

但是,您的其他用途是正确的。如果您只想读取特定的数据块,并且如果您确切知道此数据块的大小(字符串“READHERE”的精确大小),则可以使用istream::read函数来读取它:

std::ifstream is("test.txt"); 

if (is.good()) 
{ 
    is.seekg(5, ios::end); // step from end "_guys" 


    std::string data(sizeof("READHERE"), '\0'); // Initialize a string of the appropriate length. 

    is.read(&data[0], sizeof("READHERE")); // Read the word and store it into the string. 

    std::cout << data << std::endl; // output "READHERE". 
} 
+0

为什么不调整'data'并直接读入它?不需要通过'缓冲区'和类似C的函数往返。实际上你根本不使用数据。 –

+0

@LightnessRacesinOrbit您说得对,我以前的解决方案太C风格。我用'std :: string'替换了它。 – Aracthor

1

当您第一次打电话给seekg时,它会在指定位置的文件中设置一个“光标”。然后第二次调用seekg后,它会在另一个位置(现在'head_'后面)设置'curson',但它不关心之前的调用,因此它不会像您所想的那样读取。

一个解决方案是为folows:

std::string data; 
is.ignore(std::numeric_limits<std::streamsize>::max(), '_'); 
std::getline(is, data, '_'); 

std::ifstream::ignore用于跳过一切直到和包括 '_' 第一次出现。现在std::getline从该文件中读取所有内容(在跳过部分之后),直到它遇到作为第三个参数('_')提供的字符分隔符,以便它完全读取您想要的内容。