2017-02-01 88 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從該文件中讀取所有內容(在跳過部分之後),直到它遇到作爲第三個參數('_')提供的字符分隔符,以便它完全讀取您想要的內容。