Reputation: 435
I must read a binary file, but I have wrong output. I start from a txt file that contains:
1 100000 Romano Antonio 1250
2 150000 Fabrizi Aldo 2245
3 200000 Verdi Giacomo 11115
4 250000 Rossi Luigi 13630
I generate the relative binary file by with program:
#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;
}
Now I think that it gives me a binary file. Then, I have to read this binary file and put the data into a struct. My code is:
#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;
}
Now, in this part of code
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);
}
the output is wrong, that is:
Why do I get this? I generate wrong bin file? Or I manage bad the output function? I hope you can help me. Thank you in advance.
Upvotes: 0
Views: 316
Reputation: 16769
You believe that second program is wrong, but we don't know if it is wrong because the input for the second program is also wrong.
Input for the second program (also output of the first program) is supposed to be a binary file, but it is actually a text file, identical to the the input of the first program. It is identical because the first program is not making any kind of conversion. All it does is ReadFile(..., buffer, ..., &nIn, ...)
immediately followed by WriteFile(..., buffer, nIn, ...)
. These two lines just copy all the data.
First program should use getline()
(like described here, in a second method, line-based parsing) instead of ReadFile()
, get all the data, populate one struct myacc
object, and WriteFile
contents of that object.
Upvotes: 1