2012-09-05 63 views
0
void maintainFileName() 
{ 
    std :: ifstream myfile; 
    myfile.open ("zoomLevels.txt"); 

    if (myfile.is_open()) 
    { 
     // Move to end of the file, 
     myfile.seekg (0, std::ios::end); 

     // and then six characters back to pick up the last file number. 
     myfile.seekg (6, std::ios::beg); 

     int len = 1; 
     char *t = new char[len]; 

     myfile.read(t, len); 
     qDebug() << "\nt: " << *t << "\n"; 
    } 
    else 
    { 
     qDebug() << "\nsorry"; 
    } 
} 

該文件包含此:如何從文件末尾讀取第6個字符 - ifstream?

78.8115,29.582,1,01.rda 
78.8115,29.582,2,02.rda 
76.3671,30.2201,1,11.rda 
76.3671,30.2201,2,12.rda 
78.1908,30.3007,1,01.rda 
78.1908,30.3007,2,02.rda 
77.3284,29.1415,1,01.rda 
77.3284,29.1415,2,02.rda 
77.3064,29.1655,1,01.rda 
77.3064,29.1655,2,02.rda 

由該函數返回的值是5,而從最終的第六個字符是0
我哪裏錯了?

+0

你得到了'dir'參數錯誤的含義。這不是一個方向!你可能不是第一個被抓到的人:這完全是一種誤導:它實際上是一個位置! –

+0

@ J.N。看到這個:http://www.cplusplus.com/reference/iostream/istream/seekg/它寫在那裏:'尋找方向'。 :) –

+0

相當於鏈接:「**正在尋找方向**它是一個ios_base :: seekdir類型的對象,它指定了應用偏移參數off的位置的絕對位置**。方向/絕對位置。難怪人們會感到困惑。 – jrok

回答

6

尋找到任意位置在文本文件未定義的行爲。 實際上,它可能在各種聯合國工作,但沒有其他地方 。如果以二進制模式打開文件,則該搜索是合法的。 形式上,如果以二進制模式打開文件,最後可能會得到額外的字節數,但實際上,這在今天不成問題。但是,如果您在二進制模式下打開它,則可能會在數據中看到其他內容,而不是 '\n';例如,在Windows下,您將看到兩個 字符序列0x0D, 0x0A

當然,在你的代碼中,你從開始尋找,而不是從 到最後。這也是未定義的行爲,但大多數情況下,只要您在第一行尋求,就會運行 。

最後,您所寫的數據中最後的第六個字符是 '2',而不是'0'。但是,當然,在除Unix以外的其他系統上,您可以輕鬆地看到其他某些內容(或出現錯誤):在Windows下可能是 '.',或者在某些大型機OS下出現錯誤(或可能是'' ')。

+0

你說的很對,我在Linux上,現在我用二進制模式打開文件,顯示正確的結果當然,最後的第一個字符是EOF,所以我的計算是錯誤的。感謝您的幫助。 –

+0

@AnishaKaul:沒有「EOF字符」。這是C程序員中最普遍和最根本的誤解之一 –

+0

但是當我寫'myfile.seekg -7,std :: ios :: end);'它確實顯示'0',但是,如果你實際計算了這些值,'0'就在結束的第六位! –

4
myfile.seekg (6, std::ios::beg); 

在這裏你正在 6個字符開始時,沒有向開始時。只需使用

myfile.seekg (-6, std::ios::end); 
+0

-6現在顯示'2',結果應該是'0'。 :( –

+3

它仍然是未定義的行爲 –

1

首先尋求跳到結束,第二個跳到開始+ 6

用途:

myfile.seekg(-6, std::ios::end); 
+3

未定義的行爲 –

1

您可以嘗試通過文件末尾的tellg()來確定文件的完整大小,並減去數字,將其大於0再驗證一次,然後重新找回。 如果你試試這個,你也應該確保文件以二進制模式打開(我記得,有可能是一個缺陷)

myfile.seekg (0, ios::end); 
// You have to ensure, myfile.tellg() > 6 
myfile.seekg (myfile.tellg() - 6, ios:beg); 

編輯:

seekg需要類型的std :: streamoff作爲抵消。標準(ISO/IEC 14882:2003)在這裏討論了許多關於這個「問題」的非常有趣的事情。

在第27.2節中。前向聲明,streampos是fpos類的。

如果我們走得更遠,我們可以在第27.4.3節找到fpos的需求表。2,在那裏我們可以得到閉包到streamoff類型,這裏明確的要求是:q = p + o,所以fpos類必須定義一個運算符+(偏移量)。由於fpos對象還要定義一個返回類型爲OFF_T的O(p),該類型是一個內部類型,但也有一個語句,std :: streamoff類型爲OFF_T,我們有一個閉環到標準內的定義爲此操作。

所以這個操作應該是明確的。

歡迎提出其他意見。

+2

未定義的行爲。這個標準對於在streampos中增加或減少一個值可能意味着什麼很模糊。 (這個標準實際上對'streampos'的行爲提出了不可能的要求。) –

+0

我已經編輯過,爲什麼在標準內部有很好的定義,歡迎其他意見討論。 – Sven

+0

該標準說明明文尋找文本文件,而不是 由'tell'返回的位置是未定義的行爲。你不需要關於它的原因 。當然,實際上,在 'streampos'上的算術不適用於以文本模式打開的文件,除非在 Unix下。 –

0

首先,轉到文件末尾:is.seekg (0, ios::end);,然後保存位置:file_end_position = is.tellg();。現在跳轉到該位置:is.seekg (file_end_position-6, ios::end);,並從閱讀正文之後的第6個字符:is.read (buf,1);

#include <iostream> 
#include <fstream> 
using namespace std; 

int main() { 
    int file_end_position; 

    ifstream is; 
    is.open ("test.txt", ios::binary); 

    // get size of file: 
    is.seekg (0, ios::end); 
    file_end_position = is.tellg(); 
    is.seekg (0, ios::beg); 


    //go to the end of the file -6 
    is.seekg (file_end_position-6, ios::end); 

    char buf[1]; 

    // read the 6th character from the end of the file 
    is.read (buf,1); 
    is.close(); 



    delete[] buffer; 
    return 0; 
}