2010-10-12 125 views
2

C++中是否有方法從文本文件中刪除/修剪尾隨的新行?C++從文本文件中刪除尾隨的新行

例如

content content 
content content 
content content 
<- this line in the text file is empty and needs to go -> 
+0

是的,但我建議使用更高級別的語言。也許python會讓這個變得如此簡單。有多少文件需要完成這些? – JoshD 2010-10-12 01:56:55

+2

您確定該行實際存在並且不是您編輯器的工件。如果包含內容的最後一行以'\ n'結尾,則編輯器可能會顯示空白的最後一行,即使該行包含零數據。 – 2010-10-12 02:27:42

+0

我甚至沒有想過使用'\ n'。我正在使用endl。 – NateTheGreatt 2010-10-12 02:34:53

回答

2

當然!做到這一點的方法之一將是read the file to a std::string

#include <fstream> 
#include <string> 

// Add this code inside your main() function 
std::ifstream ifs("filename.txt");  
std::string str((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>()); 

,然後使用任何這裏描述的技術:

C++ Remove new line from multiline string

,那麼你可能會覆蓋新結果文件。當然,這種方法在處理非常大的文件(比如說2GB)時是不實際的,但根據您原來的問題,這樣的事情不是一個限制。

thread也有很大的材料檢測新行。

+0

這非常有幫助。謝謝! – NateTheGreatt 2010-10-12 20:33:23

0

您需要閱讀所有的文件中的內容,並以這樣的方式,沒有空行不存在,或者你想要的方式重新編寫內容。

+0

沒錯,那就是我的想法。我會怎麼做呢? – NateTheGreatt 2010-10-12 02:00:53

+0

我不能告訴你,直到我知道確切的文件格式。在C++ fstream上閱讀:http://www.cplusplus.com/reference/iostream/fstream/ – Donotalo 2010-10-12 02:04:27

+0

文件格式與上述內容完全相同,只是更多內容的行數更多 – NateTheGreatt 2010-10-12 02:24:56

2
ifstream fin("input.txt"); 
vector<string> vs; 
string s; 
while(getline(fin,s)) 
    vs.push_back(s); 
fin.close(); 

ofstream fout("input.txt"); 
for(vector<string>::iterator it = vs.begin(); it != vs.end(); ++it) 
{ 
    if(it != vs.begin()) 
     fout << '\n'; 
    fout << *it; 
} 
0

您可以創建一個簡單的過濾器,如適用於:

remove_empty_last_line <input.txt> output.txt 

或者,您也可以創建自己的文件輸入流翼:

#include <fstream> 

std::ifstream myin(filename); 

然後,代碼將類似於(未經測試)...

char c, d, e; 

if (cin.get(c)) 
    if (cin.get(d)) 
    { 
     while (cin.get(e)) 
     { 
      cout << d; 
      c = d; 
      d = e; 
     } 
     if (c != '\n' || d != '\n') 
      cout << d; 
    } 
    else 
     cout << c; 

(Subst如果需要,請將cin改爲cin,然後myin.close())。不需要使用std :: strings來實現這麼簡單的事情:它們只是放慢了一切。 C(以及C++)的強大優勢之一是能夠一次有效地處理數據。

0

最有效的方法是查找文件末尾並向後移動文件結束指針。不幸的是,這不是可移植的,因爲在C或C++標準庫中沒有設置文件結束指針的標準方法。您需要使用特定於平臺的功能,例如Windows上的SetEndOfFile或POSIX上的ftruncate。例如:

void RemoveFinalNewline(const char *filename) 
{ 
#if defined(_WIN32) 
    HANDLE hFile = CreateFile(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 
    if(hFile == INVALID_HANDLE_VALUE) 
     ; // handle error 

    LARGE_INTEGER fileSize; 
    if(GetFileSizeEx(hFile, &fileSize) == 0) 
     ; // handle error 
    if(fileSize.QuadPart < 2) 
     ; // this case is left as an exercise to the reader 

    LARGE_INTEGER newFilePtr; 
    newFilePtr.QuadPart = -2; 
    if(SetFilePointerEx(hFile, &newFilePtr, NULL, FILE_END) == 0) 
     ; // handle error 

    char lastTwoBytes[2]; 
    if(ReadFile(hFile, lastTwoBytes, 2, NULL, NULL) == 0) 
     ; // handle error 

    if(lastTwoBytes[1] == '\n') 
    { 
     fileSize.QuadPart--; 
     if(lastTwoBytes[0] == '\r') 
      fileSize.QuadPart--; 
     if(SetFilePointerEx(hFile, &fileSize, NULL, FILE_BEGIN) == 0) 
      ; // handle error 
     if(SetEndOfFile(hFile) == 0) 
      ; // handle error 
     // Success! 
    } 
    // else the file didn't end in a newline 

    CloseHandle(hFile); // and we're done 
#else // POSIX case; the non-Windows, non-POSIX case is left as an exercise 
    int fd = open(filename, O_RDWR); 
    if(fd == -1) 
     ; // handle error 

    off_t fileSizeMinus1 = lseek(fd, -1, SEEK_END); 
    if(fileSizeMinus1 == (off_t)-1) 
     ; // handle error 

    // We're assuming that a newline is a bare LF '\n' here. The CRLF case 
    // is left as an exercise (hint: see the Windows case above) 
    char lastChar; 
    if(read(fd, &lastChar, 1) != 1) 
     ; // handle error 

    if(lastChar == '\n') 
    { 
     if(ftruncate(fd, fileSizeMinus1) == -1) 
      ; // handle error 
     // else success! 
    } 
    // else the file does not end in a newline 

    close(fd); // and we're done 
#endif 
}