2013-02-01 34 views
2

我想在Win32中獲得簡單的文件IO。到目前爲止,寫入工作正常,但讀取不成功:雖然它成功讀取內容,但額外的「垃圾」被附加到字符串。我到目前爲止的代碼如下。該程序已定義UNICODE在Win32中,如何將文本文件成功讀入內存?

對於寫作:

DWORD dwTextSize = GetWindowTextLength(hWndTextBox); 
WCHAR *lpszText = new WCHAR[dwTextSize]; 
GetWindowText(hWndTextBox, lpszText, dwTextSize + 1); 
hTextFile = CreateFile(lpszTextFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 
DWORD dwBytesWritten; 
WriteFile(hTextFile, lpszText, 2 * dwTextSize, &dwBytesWritten, NULL); // x2 for 2 bytes per Unicode character 
CloseHandle(hTextFile); 
DeleteObject(hTextFile); 

在這個例子中,Hello, World!成功保存爲Hello, World!

對於閱讀:

lpszTextFileName = L"text.txt";  // LPCTSTR Variable 
hTextFile = CreateFile(lpszTextFileName, GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 
DWORD dwFileSize = GetFileSize(hTextFile, &dwFileSize); 
DWORD dwBytesRead; 
WCHAR *lpszText = new WCHAR[dwFileSize/2]; 
ReadFile(hTextFile, lpszText, dwFileSize, &dwBytesRead, NULL); 
CloseHandle(hTextFile); 

字符串然後用於設置編輯控件的文本:

SendMessage(hWndTextBox, WM_SETTEXT, NULL, (LPARAM)lpszText); // SetWindowText() also possible 

Hello, World!在讀回時,它讀取回作爲Hello, World!﷽﷽ꮫꮫꮫꮫﻮ或視覺上的變化,但基本上「垃圾」!

我可能錯過了一些相當明顯的東西,但我看不到它在哪!有沒有解決這個問題的辦法,如果是的話,那是什麼?

+2

在將它發送到SendMessage()之前,終止該字符串(並確保爲該終止符分配空間)。 (如果不是很明顯,那麼在完成時刪除緩衝區)。此外,將GetWindowText(hWndTextBox,lpszText,dwTextSize + 1)'放入前一行分配爲'dwTextSize'的緩衝區可能不是一個明智的想法。 – WhozCraig

+0

如何在Win32中終止一個字符串?它是否就像'lpszText [sizeof(lpszText) - 1] =(WCHAR)0; //或'\ 0''? – BWHazel

+0

這將設置您的字符串中的第3個(或第7個,如果編譯64位)wchar爲0,這不是您想要的。 'sizeof(pointer-type-var)'與sizeof(array-type-var)'不一樣。查看下面的帖子,瞭解如何終止你的字符串。 – WhozCraig

回答

4

好吧,我開始了這個評論,但它失去了控制。

用於編寫

此:

WCHAR *lpszText = new WCHAR[dwTextSize]; 

應該是:

WCHAR *lpszText = new WCHAR[dwTextSize+1]; 

此:

DeleteObject(hTextFile); 

不應該根本沒有。擺脫它。

我假設你delete [] lpszText;當你完成它的某個地方。如果沒有,那就這樣做。


用於讀取

的第二個參數GetFileSize()不應該是相同的變量作爲返回值。對於大文件大小,它是64位值的高32位。如果你知道你的文件大小超過4GB時,你可以讓它空,所以更改此:

DWORD dwFileSize = GetFileSize(hTextFile, &dwFileSize); 

這樣:

DWORD dwFileSize = GetFileSize(hTextFile, NULL); 

你必須考慮你的文件的空終止緩衝區,所以這樣的:

WCHAR *lpszText = new WCHAR[dwFileSize/2]; 

應該改成這樣:

WCHAR *lpszText = new WCHAR[dwFileSize/2 + 1]; 
lpszText[dwFileSize/2] = 0; 

其餘的應該像你希望的那樣工作。沒有錯誤檢查,這不好,但我看到更糟。和以前一樣,當你完成它的時候,我假設你在某個地方delete [] lpszText;。如果沒有,那就這樣做。

+0

優秀的職位。 8行代碼有這麼多錯誤/問題令人驚訝......我不知道我會個人使用'lpszText [dwFileSize/2] = 0';我更喜歡直接將memset緩存到全部的零,但這是一種風格。 –

+0

@NikBougalis其中大部分對於Windows和C/C++新手都很常見。唯一一個讓我走「跆拳道」是'DeleteObject()'。主知道*來自哪裏。關於'memset',它是一個性能方面的事情。沒有必要用一大堆零填充內存,僅僅在其中一個覆蓋後立即覆蓋。來自平臺,這樣做可能會變得昂貴。但是,無論什麼作品,讓你在晚上睡覺= P – WhozCraig

+0

是的,DeleteObject是奇特的。至於'memset',我得到你從哪裏來 - 我也是一個性能強勁的極客,唉,這是我們在工作場所的要求... –

相關問題