Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C Windows中的ReadFile()_C_Windows_Winapi - Fatal编程技术网

C Windows中的ReadFile()

C Windows中的ReadFile(),c,windows,winapi,C,Windows,Winapi,我试图使用Windows函数ReadFile()读取文件,但打印消息时会打印太多字符 不管我是从ANSII文件还是UNICODE文件读取,我都没有得到正确的字符 文件中的文本是:“这是一个文本文件” ANSII文件的屏幕截图: UNICODE文件的屏幕截图: 我做错了什么 #define BUFSIZE 4000 int _tmain(int argc, TCHAR *argv[]) { HANDLE hIn; TCHAR buffer[BUFSIZE]; DW

我试图使用Windows函数
ReadFile()
读取文件,但打印消息时会打印太多字符

不管我是从ANSII文件还是UNICODE文件读取,我都没有得到正确的字符

文件中的文本是:“这是一个文本文件”

ANSII文件的屏幕截图:

UNICODE文件的屏幕截图:

我做错了什么

#define BUFSIZE 4000


int _tmain(int argc, TCHAR *argv[])
{
    HANDLE  hIn;
    TCHAR buffer[BUFSIZE];
    DWORD nIn = 0;

    //create file
    hIn = CreateFile(argv[1],
        GENERIC_READ,
        FILE_SHARE_READ,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL);
    //check the handle
    if (hIn == INVALID_HANDLE_VALUE)
    {
        printf("\nOpen file error\n");
    }
    //read from file
    if (FALSE == ReadFile(hIn, buffer, BUFSIZE - 1, &nIn, NULL))
    {
        printf("Terminal failure: Unable to read from file.\n GetLastError=%08x\n", GetLastError());
        CloseHandle(hIn);
        return 0;
    }

    if (nIn > 0 && nIn <= BUFSIZE - 1)
    {
        buffer[nIn] = TEXT('\0'); // NULL character
        _tprintf(TEXT("Data read from %s (%d bytes): \n"), argv[1], nIn);
    }
    else if (nIn == 0)
    {
        _tprintf(TEXT("No data read from file %s\n"), argv[1]);
    }
    else
    {
        printf("\n ** Unexpected value for nIn ** \n");
    }
    printf("1:%s\n", buffer);
    _tprintf(TEXT("\n2:%s"), buffer);

    return 0;
}
#定义BUFSIZE 4000
int_tmain(int argc,TCHAR*argv[])
{
处理hIn;
TCHAR缓冲区[BUFSIZE];
DWORD-nIn=0;
//创建文件
hIn=CreateFile(argv[1],
泛读,
文件共享读取,
无效的
开放式,
文件\u属性\u正常,
无效);
//检查把手
if(hIn==无效的句柄值)
{
printf(“\n打开文件错误\n”);
}
//从文件中读取
if(FALSE==ReadFile(hIn,buffer,BUFSIZE-1,&nIn,NULL))
{
printf(“终端故障:无法读取文件。\n GetLastError=%08x\n”,GetLastError());
闭柄(hIn);
返回0;
}

如果(nIn>0&&nInWindows API函数
ReadFile()
读取字节,则为
无符号字符
,而不是Windows UNICODE大小的
TCHAR
,在现代Windows中,它是两个字节,而不是Windows 95中的一个字节,等等。因此,您需要进行以下修改

另请参见,其中包含有关Windows的不同编译目标和所用字符编码的其他信息

首先,缓冲区应该是
字节
类型,而不是
TCHAR

其次,您需要确保它是零字段,以便按照
字节缓冲区[BUFSIZE]={0};
初始化缓冲区

由于Windows UNICODE是UTF-16或每个字符两个字节,因此您需要确保UNICODE文本字符串的字符串结尾字符是二进制零的两个字节,并且您需要在缓冲区长度中考虑到这一点。放置字符串结尾时,您需要确保它是零的两个字节,而不仅仅是一个字节

您应该读取
BUFSIZE-2
字节,以确保在读取的是UNICODE字符串的情况下读取偶数个字节。并且您的缓冲区大小也应该是2的倍数

如果字符串是您读入的ANSI字符串,那么当显示为UNICODE时,它可能看起来像垃圾,因为每个UNICODE字符将由两个ANSI字符组成


因此,要使字符串相同,您需要在两个字符编码之间进行转换。请参阅这篇关于在文本文件中使用以指示文件中使用的字符编码类型的文章。

为什么要使用TCHAR?您是否在Win98上运行?不,但要制作一个通用程序,用于简单字符或宽字符。这样做是错误的使用TCHAR。要明确。TCHAR只会让你感到困惑,尤其是因为你还没有真正清楚地理解文本编码。额外的间接性只会让你更加困惑。噢。它实际上不必是零填充的,只需要是零终止的。你的方法行得通,但我过早的优化冲动让我感到刺痛。这会很好当
ReadFile
返回时,在获得实际缓冲区长度后,在缓冲区的末尾添加一个NUL字符就足够了。此外,我知道您在这里试图保持简单,事实是非常复杂和令人沮丧的,但基本上不可能确定文件使用什么字符编码。有一些uristics,但它们不可靠。您需要通过元数据或用户告知。@CodyGray因此我知道它不需要零填充,但另一方面,从已知状态开始有助于调试和查看调试器中的数据结构。在第一次读取后,它不再是零填充。我知道尝试确定c通过检查字节流进行字符编码基本上是不可能的。这就是http协议中存在
内容编码:
内容类型:
的原因。但是,因为这是他的文件,所以他可以使用字节顺序标记、文件扩展名或任何其他他想要使用的方法。“我知道,通过检查字节流来确定字符编码基本上是不可能的。这就是http协议中存在
内容编码:
内容类型:
的原因。“-嗯,不。这就是BOM存在的原因。如果没有BOM,您可以对缓冲区运行一些试探法,例如调用。此外,没有称为“ANSII”的编码,
TCHAR
不是Unicode代码单元(
wchar\t
is).@IInspectable bom仅适用于UTF编码,而不适用于ANSI编码。ANSI编码比UTF编码多得多。被明确告知文件编码比猜测要好。而
istextanticode()
就是猜测(并且已知有时猜错)在Unicode编译中, TChar 是“代码> WCARYTT
。@ ReMyLeBeAu:“每一条鱼都是金鱼(只要你只考虑金鱼)。”——如果你遵循这一学派,那么,是的,每个<代码> TCHAR 是<代码> W查尔特特< /Code >。