2013-02-01 33 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',我得到你从哪里来 - 我也是一个性能强劲的极客,唉,这是我们在工作场所的要求... –

相关问题