2012-04-28 66 views
3

下面是代碼:ENDL不與wstring的(Unicode)的工作

std::ofstream f("file1.txt"); 
    f<<"123"<<std::endl<<"456";   //(*1) 

    /*std::stringstream ordinary_strstream; This works too 
    ordinary_strstream<<"123"<<'\n'<<"456"; 
    f<<ordinary_strstream.str();*/ 

    std::wstringstream s; 
    s<<L"123"<<std::endl<<L"456";   //(*2) 
    s<<L"123"<<L"\n"<<L"456";    //(*3) 
    s<<"123"<<WCHAR(13)<<WCHAR(10)<<"456";//(*4) 

    HANDLE h =CreateFileW(L"file2.txt", GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 
    NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 

    ULONG l; 
    WriteFile(h, s.str().c_str(), s.str().length() * 2, &l, NULL); 

在(* 1)的情況下有一個新行,在(* 2)和(* 3)我看到在file2.txt中沒有換行符。在(* 3)中有一個換行符。我使用notepad.exe進行瀏覽。十六進制編輯器沒有顯示0x0D字節,只有0x0A

我應該如何正確把unline文本文件中的換行符?謝謝。

+2

'2'應該是'sizeof(wchar_t)',不是嗎? – Fanael 2012-04-28 12:46:38

+1

''2''只是用於縮略,在原始代碼中當然有std :: wstring :: value_type。 – fogbit 2012-04-28 12:49:27

+1

小心你的術語。 Unicode是代碼點的規範。從技術上講,您在文件中存儲的是Unicode的編碼。如果你使用Windows和wchar_t,這可能是UTF-16 – 2012-04-28 13:34:20

回答

9

這是預期的:std::endl寫一個L'\n'到一個寬char字符串(並刷新它,但它不相關),從來沒有L"\r\n"。在編寫文字L"\n"時更爲明顯。 WriteFile不會執行任何種類的換行替換,也不會執行wstringstream(請注意,文本流在文本模式下打開時執行換行替換,這就是爲什麼您在(*1)中獲得正確的換行符)。因此,在文件中將不會有回車符。如果你想要他們,明確地寫下來。

+2

@downvoter:謹慎解釋? – Fanael 2012-04-28 12:47:47

+1

你的意思是它只需要「\ n」(0x0A)的第一部分,爲了形成寬字符而加零,把字符放在''wstringstream''中並拋出第二部分(0x0D)?我理解對嗎? – fogbit 2012-04-28 12:57:09

+1

@fogbit:不,沒有東西被扔掉。您已經編寫了代碼,以便它寫入'L'\ n',所以'wstringstream'將一個'L'\ n'寫入其內部字符串。沒有更多,沒有更多。它不知道你真的是指'L'\ r \ n「',所以如果你想要的話,就說出來。 – Fanael 2012-04-28 13:00:22

2

Stringstreams不進行換行。 std::endl\n(char或wchar,取決於上下文)完全相同。

CreateFile不做換行轉換;它是嚴格二元的。

因此,當您使用stringstream創建一個字符串並將其寫入文件CreateFile時,endl將只是一個換行符(0x0A)字符。

記事本不能很好地處理文件的行結尾只是換行符而不是CR + LF。

+0

但是普通的stringstream做到了。我更新了代碼,如果你想要的話,嘗試一下。 – fogbit 2012-04-28 13:07:19

+0

這是您正在寫入的'fstream',而不是字符串流,可以進行轉換。 – 2012-04-28 15:26:41