c - 使用 _tprintf 错误地打印出二进制文件

标签 c windows winapi binaryfiles tchar

我必须读取二进制文件,但输出错误。我从一个 txt 文件开始,其中包含:

1 100000 Romano Antonio 1250
2 150000 Fabrizi Aldo 2245
3 200000 Verdi Giacomo 11115
4 250000 Rossi Luigi 13630

我通过程序生成相对的二进制文件:

#include <windows.h>
#include <tchar.h>
#include <stdio.h>

#define BUF_SIZE 1000

/*
 *  Problem1: use tchar.h and _tmain instead of
 *  int main (int argc, LPTSTR argv [])
 *  Sometimes it is needeed to see argv correctly
 */
int _tmain (int argc, LPTSTR argv [])
{
  HANDLE hIn, hOut;
  DWORD nIn, nOut;
  CHAR buffer [BUF_SIZE];

  if (argc != 3) {
    fprintf (stderr, "Usage: cp file1 file2\n");
    return 1;
  }

  hIn = CreateFile (argv[1], GENERIC_READ, FILE_SHARE_READ, NULL,
    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); /*Here hIn is created with read access*/
  if (hIn == INVALID_HANDLE_VALUE) {
    fprintf (stderr,
      "Cannot open input file. Error: %x\n", GetLastError ());
    return 2;
  }

  hOut = CreateFile (argv[2], GENERIC_WRITE, 0, NULL,
    CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  if (hOut == INVALID_HANDLE_VALUE) {
    fprintf (stderr,
      "Cannot open output file. Error: %x\n", GetLastError ());
    CloseHandle(hIn);
    return 3;
  }

  while (ReadFile (hIn, buffer, BUF_SIZE, &nIn, NULL) && nIn > 0) {
/*hIn is the handle to the read file, buffer is a pointer to the buffer that receives the data read 
from the file, BUF_SIZE is the maximum number of bytes to be read, &nIn is 
the pointer to the variable that receives the n° of bytes read*/
    /*
     *  Problem 2:
     *  During the last cycle less than BUF_SIZE characters may
     *  be read from file
     *  WriteFile (hOut, buffer, BUF_SIZE, &nOut, NULL);
     *  so write just the number of characters read
     */
    WriteFile (hOut, buffer, nIn, &nOut, NULL); /*I write in file related hOut, the content of read file hIn is in buffer, 
nIn is the n° of bytes to write, &nOut is a pointer to the variable that receives the number of bytes written*/
    if (nIn != nOut) {
      fprintf (stderr, "Fatal write error: %x\n", GetLastError ());
      CloseHandle(hIn); CloseHandle(hOut);
      return 4;
    }
  }

  CloseHandle (hIn);
  CloseHandle (hOut);
  return 0;
}

现在我认为它给了我一个二进制文件。然后,我必须读取这个二进制文件并将数据放入结构中。我的代码是:

#if 1
#define UNICODE
#define _UNICODE
#endif

#include <windows.h>
#include <tchar.h>
#include <stdio.h>

#define L 30+1
#define SETFILEPOINTER_OVERLAPPING 1
#define N 3
#define BUF_SIZE 1000

struct myacc {
    int id;
    long int acc_number;
    TCHAR surname[L];
    TCHAR name[L];
    int amount;
};

int _tmain(int argc, _TCHAR* argv[])
{
    HANDLE hIn;
    OVERLAPPED ov = {0, 0, 0, 0, NULL};
    DWORD nIn,n;
    //TCHAR c;
    //TCHAR buffer[BUF_SIZE];
    LARGE_INTEGER filePos;
    struct myacc account;

    if(argc != N) {
        fprintf(stderr, "Error into arguments\n");
        return 1;
    }

    hIn = CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hIn == INVALID_HANDLE_VALUE) {
            fprintf (stderr,"Cannot open input file. Error: %x\n", GetLastError ());
            return 2;
        }

    n=1;
    filePos.QuadPart = (n-1) * sizeof(struct myacc);

#if SETFILEPOINTER_OVERLAPPING
    SetFilePointerEx (hIn, filePos, NULL, FILE_BEGIN);
    while(ReadFile (hIn, &account, sizeof (struct myacc), &nIn, NULL) && nIn > 0) {
        _tprintf (_T("-> %d %ld %s %s %d <-\n"), account.id, account.acc_number, account.surname, account.name, account.amount);
    }
#else
    ov.Offset = filePos.LowPart; /*Uso l'overlapped structure ov se ho asynchronous I/O*/
    ov.OffsetHigh = filePos.HighPart;
    while(ReadFile (hIn, &account, sizeof (struct myacc), &nIn, &ov) && nIn > 0) {
        _tprintf (_T("-> %d %ld %s %s %d <-\n"), account.id, account.acc_number, account.surname, account.name, account.amount);
    }
#endif
    return 0;
}

现在,在这部分代码中

while(ReadFile (hIn, &account, sizeof (struct myacc), &nIn, NULL) && nIn > 0) {
            _tprintf (_T("-> %d %ld %s %s %d <-\n"), account.id, account.acc_number, account.surname, account.name, account.amount);
        }

输出错误,即: enter image description here

为什么我会得到这个?我生成了错误的 bin 文件?或者我管理不好输出功能?我希望你可以帮助我。 先感谢您。

最佳答案

您认为第二个程序是错误的,但我们不知道它是否错误,因为第二个程序的输入也是错误的。

第二个程序的输入(也是第一个程序的输出)应该是一个二进制文件,但它实际上是一个文本文件,与第一个程序的输入相同。它是相同的,因为第一个程序没有进行任何类型的转换。它所做的就是 ReadFile(..., buffer, ..., &nIn, ...) 紧接着 WriteFile(..., buffer, nIn, ...)。这两行只是复制所有数据。

第一个程序应该使用 getline() (如描述 here ,在第二种方法中,基于行的解析)而不是 ReadFile(),获取所有数据,填充一个 struct myacc 对象,以及该对象的 WriteFile 内容。

关于c - 使用 _tprintf 错误地打印出二进制文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30270194/

相关文章:

c# - 尝试挂接键盘时出现 "CallbackOnCollectedDelegate was detected"

c++ - 使用 Winbase.h 的编译错误

c - switch 语句终止后不会重新启动

c - 提取无符号 32 位整数的上下字

windows - 防止已安装的应用程序在静默安装期间启动

node.js - npm 错误! EPROTO : protocol error, 符号链接(symbolic link) '../@babel/parser/bin/babel-parser.js' -> '/home/vagrant/code/proadco.test/node_modules/.bin/parser'

c - 子字符串 C 程序中的段错误

c - printf() var-arg 引用如何与堆栈内存布局交互?

windows - 在 Windows 容器上的 docker 上运行非常慢

c++ - 兼容模式下 x64 窗口上的 native x32 应用程序与 x32 窗口上的 x32 应用程序之间的区别