Мне нужно прочитать двоичный файл, но у меня неправильный вывод. Я начинаю с текстовый файл, который содержит:Неверный вывод из двоичного файла с помощью _tprintf
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);
}
выход неправильно, то есть:
Почему я получаю это? Я генерирую неправильный файл bin? Или я плохо справляюсь с выходной функцией? Я надеюсь, что вы можете мне помочь. Спасибо заранее.
Вы буквально дублируете свой текстовый файл. Вся первая программа могла быть написана с помощью одного вызова win32 api, [CopyFile] (https://msdn.microsoft.com/en-us/library/windows/desktop/aa363851%28v=vs.85%29 .aspx). Просто потому, что вы реплицировали файл, он не волшебным образом преобразует его в структурированный макет, который, как вы ожидаете, со вторым кодом. Мне кажется, ваша * первая * программа должна читать текст, * переводить * его в структурированный макет, который вы хотите, а затем писать * это *. – WhozCraig
Как вы сказали в [другом обсуждении] (http://stackoverflow.com/questions/30269383/), ваш входной файл НЕ БИНАРНЫЙ ФАЙЛ, это ФАЙЛ ТЕКСТА. Он НЕ содержит в себе двоичные структуры, поэтому перестаньте читать его, как если бы он это сделал. Прочитайте его как текстовый файл. Для его открытия используйте стандартный класс 'std :: ifstream', тогда вы можете использовать такие вещи, как' operator >> 'или' std :: getline() 'и' std :: istringstream', чтобы читать и анализировать текст как необходимо. Чтение необработанных байтов исходного файла и запись их как-в другой файл не создает двоичный файл автоматически. Вы должны преобразовывать данные. –
, вы можете посмотреть, как этот ответ: в отношении использования обычного текста или используя unicode. Вы изучили подготовленный файл, чтобы узнать, каково его «фактическое содержание»? –
user3629249