代码之家  ›  专栏  ›  技术社区  ›  Abid Ali

读取文件win32 api

  •  2
  • Abid Ali  · 技术社区  · 15 年前

    我想读一个文件……但是…当我调试我的程序时,它会运行,但会弹出一个窗口,显示系统编程已经停止工作,在控制台中,它会被写入,按Enter键关闭程序。我的代码是:

    // System Programming.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    #include "iostream"
    using namespace std;
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        HANDLE hin;
        HANDLE hout;
        TCHAR buff[20]= {'q','2','3'};
        TCHAR buff2[20]={'a','v'};
        hin = CreateFile(_T("Abid.txt"),GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
        if(hin == INVALID_HANDLE_VALUE)
        {
            cout<<"error";
        }
    
        WriteFile(hin,buff,40,0,NULL);
        CloseHandle(hin);
    
        hout = CreateFile(_T("Abid.txt"),GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
    
        if(hout == INVALID_HANDLE_VALUE)
        {
            cout<<"error";
        }
    
        ReadFile(hout,buff2,40,0,NULL);
        CloseHandle(hout);
        return 0;
    }
    
    4 回复  |  直到 15 年前
        1
  •  12
  •   Abyx    15 年前

    根据msdn,只有当lpoverlapped参数不为空时,lpNumberOfBytesWritten参数才能为空。所以电话应该是

    DWORD nWritten;
    WriteFile(hin, buff, 40, &nWritten, NULL);
    

    DWORD nRead;
    ReadFile(hout, buff2, 40, &nRead, NULL);
    

    此外,重命名 豪特 .

        2
  •  5
  •   Cheers and hth. - Alf    15 年前

    其他人已经回答了你的问题。这是关于代码的。

    // Your code:
    // System Programming.cpp : Defines the entry point for the console application.
    //
    

    删除那个评论就行了。这不是真的。-) 入口点 因为您的程序是机器代码开始执行的地方,并且使用Microsoft工具链,它由 /entry 链接器选项。

    请注意,Microsoft的文档通常会混淆入口点,例如,它总是以某种方式记录了入口点的错误签名。

    这是最臭名昭著的微软文档错误之一,而且,考虑到它以各种形式持续了15年,我认为它说了些什么(但不确定具体是什么)。

    // Your code:
    #include "stdafx.h"
    

    您不需要这个自动生成的头。代替使用 <windows.h> . 最简单的方法包括 <Windows .h & gt; 对于你的计划

    #undef  UNICODE
    #define UNICODE
    #include <windows.h>
    

    对于C++,一般你还想确保 STRICT NOMINMAX 在包括之前定义 <Windows .h & gt; . 至少用现代工具 严格的 是默认定义的,但要确保它不受伤害。没有它一些声明 不会编译 使用C++编译器,至少不需要重新解释转换,例如对话过程。

    // Your code:
    #include "iostream"
    using namespace std;
    

    差不多了。

    这样做:

    #include <iostream>
    using namespace std;
    

    不同之处在于编译器在哪里搜索头。使用引用的名称,它首先在一些额外的地方搜索(这就是标准所说的)。对于大多数编译器,这些附加位置包括include文件的目录。

    // Your code:
    int _tmain(int argc, _TCHAR* argv[])
    

    哦不!不要这样做。它是一个Microsoft“功能”,有助于支持Windows 9.x。只有当您使用动态链接的MFC,并且目标是Windows 9.x时,它才相关;如果图片中没有MFC,则只使用Microsoft Unicode层。

    您是否真的将Windows9.x作为使用动态链接MFC的应用程序的目标?

    相反,做…

    int main()
    

    …哪个是标准的,或者使用Microsoft语言扩展…

    int wMain( int argc, wchar_t* argv[] )
    

    …如果您想以“简单”的方式处理命令行参数。

    // Your code:
    {
        HANDLE hin;
        HANDLE hout;
        TCHAR buff[20]= {'q','2','3'};
        TCHAR buff2[20]={'a','v'};
    

    这个 TCHAR 在Windows9.x支持工具中,这些东西只是更多的MFC。

    除了完全不必要(大概,你不是真的针对Windows9.x,是吗?)它隐藏了你的意图,伤害了你的眼睛。

    你是说…

    char buff[20] = {'q', '2', '3'};
    

    …也许?

    // Your code:
        hin = CreateFile(_T("Abid.txt"),GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
        if(hin == INVALID_HANDLE_VALUE)
        {
            cout<<"error";
        }
    

    正如其他人提到的, OPEN_EXISTING 创建文件时不符合逻辑,计数指针参数的用法不能为0。

    使用时 <Windows .h & gt; UNICODE 文件名参数应指定为 L"Abid.txt" .

    干杯!

        3
  •  1
  •   Michael Burr    15 年前

    问题是,您正在为 lpNumberOfBytesWritten / lpNumberOfBytesread 参数。虽然这是一个可选参数,但有一个条件:

    只有当lpoverlapped参数不为空时,此参数才能为空。

    此外,您的缓冲区大小可能有误:

    WriteFile(hin,buff,40,0,NULL);  // says that buff has 40 bytes
    
    ReadFile(hout,buff2,40,0,NULL); // says that buff2 has 40 bytes
    

    但是如果您是为ansi而不是unicode编译的,那么它们的大小将只有20个字节。

    你应该使用 sizeof(buff) sizeof(buff2) 相反。

        4
  •  0
  •   Steve Townsend    15 年前

    假设初始代码试图将文件创建为新文件,则不能使用 OPEN_EXISTING ,你必须使用 OPEN_ALWAYS (或其他一些创造性的变体)。

    这个 存在的开放性 回读的用法可以。

    btw一旦修复 WriteFile 调用会导致访问冲突,因为您正在尝试写入数组包含的更多字节。