» »

[C++] problem z binarnimi datotekami

[C++] problem z binarnimi datotekami

microera ::

Imam primer pisanja bufferja v binary file kot je navedeno tukaj:
http://msdn.microsoft.com/en-us/library...

buffer imam definiran:
#define _SizeOfRxBuffer_ 1024
unsigned char RxBuffer[_SizeOfRxBuffer_];

Ponavadi piše OK, vendar včasih mi doda na koncu v file poleg pravih podatkov še: "60" ali pa kakšen byte ali dva na koncu.....

?????
  • spremenil: Senitel ()

microera ::

tole je s spleta....pri meni pa je kot sem omenil!
Kakšen nasvet? Se že mučim dve uri...! :)

p.s.
kako popravim naslov teme? Namreč rad bi dodal še: "... (write binary file)"


// crt__write.c
// 
// This program opens a file for output and uses _write to write
// some bytes to the file.

#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <share.h>

char buffer[] = "This is a test of '_write' function";

int main( void )
{
   int         fileHandle = 0;
   unsigned    bytesWritten = 0;

   if ( _sopen_s(&fileHandle, "write.o", _O_RDWR | _O_CREAT,
                  _SH_DENYNO, _S_IREAD | _S_IWRITE) )
      return -1;

   if (( bytesWritten = _write( fileHandle, buffer, sizeof( buffer ))) == -1 )
   {
      switch(errno)
      {
         case EBADF:
            perror("Bad file descriptor!");
            break;
         case ENOSPC:
            perror("No space left on device!");
            break;
         case EINVAL:
            perror("Invalid parameter: buffer was NULL!");
            break;
         default:
            // An unrelated error occured 
            perror("Unexpected error!");
      }
   }
   else
   {
      printf_s( "Wrote %u bytes to file.\n", bytesWritten );
   }
   _close( fileHandle );
}
LP

www.microera.si

Zgodovina sprememb…

  • spremenil: microera ()

Senitel ::

In kaj nam bo sample koda iz MSDN-a pomagala pri reševanju tvojega problema? Od tebe imamo samo dekleracijo arraya. Torej v file pač ne zapišeš 1024 bytov, ampak ti jih uspe zapisat nekaj več.

In ja naslednjič izberi kakšen bolj deskriptiven naslov teme.

microera ::

#define _SizeOfRxBuffer_		1024
unsigned char RxBuffer[_SizeOfRxBuffer_];	//1kB=0x400=1024 sectors: 0x000..0x3FF, 0x400..0x7FF, 0x800..0xBFF, 0xC00..0xFFF

unsigned int Count_OKbytes;
char	*imeOutFile="RxBuffer.txt";
int SaveBuff2File(unsigned char *Save_buffer,char *imeOUTf,unsigned int NoOfBytes);

//==========================================================================================
//	main
//==========================================================================================
int main( int argc, // Number of strings in array argv
 char *argv[])		// Array of command-line argument strings )
{
.......

	returnStatus=SaveBuff2File(RxBuffer, imeOutFile, Count_OKbytes);	//save buffer to file

.......
}



//-------------------------------------------------------------------------
/* write binary data from buffer to filee */
int SaveBuff2File(unsigned char *Save_buffer,char *imeOUTf,unsigned int NoOfBytes)
{
   int         fileHandle = 0;
   unsigned    bytesWritten = 0;

   if ( _sopen_s(&fileHandle, imeOUTf, _O_WRONLY | _O_CREAT,	_SH_DENYRD,	_S_IREAD) )
      return -1;
	

   if (( bytesWritten = _write( fileHandle, Save_buffer, sizeof(Save_buffer) )) == -1 )
   {
      switch(errno)
      {
         case EBADF:
            perror("Bad file descriptor!");
            break;
         case ENOSPC:
            perror("No space left on device!");
            break;
         case EINVAL:
            perror("Invalid parameter: buffer was NULL!");
            break;
         default:
            // An unrelated error occured 
            perror("Unexpected error!");
      }
   }
   else
   {
      printf_s( "Wrote %u bytes to file: %s\n", bytesWritten, imeOUTf);
   }
   _close( fileHandle );
   return 0;
}
LP

www.microera.si

Senitel ::

Odvisno od tega ali prevajaš za 32bit ali 64bit ti bo tale koda zapisala ali 4 ali pa 8 bajtov v datoteko.
Bo treba malo razmislit kako in zakaj in ne samo copy paste-at kodo okrog. Tvoja funkcija vzame za paramter "NoOfBytes", zakaj za vraga ne uporabiš tega?

microera ::

HVALA za odgovore!

sem spremenil na:
int SaveBuff2File(unsigned char *Save_buffer,char *imeOUTf)
{......
   if (( bytesWritten = _write( fileHandle, Save_buffer, sizeof(Save_buffer) )) == -1 )
......
}

tako, da mi znotraj funkcije izračuna velikost bufferja, ki se bo zapisal v file!


Kako pa naredim, da se file izbriše in nato vpiše buffer v file (rewrite)?
Torej vedno imam samo pisanje (rewrite)(najprej brisanje nato pa vpis)!
Katere FLAG-e nastavit?
   if ( _sopen_s(&fileHandle, imeOUTf, _O_WRONLY | _O_CREAT,	_SH_DENYNO,		_S_IREAD | _S_IWRITE) )
      return -1;	


Namreč sedaj mi file pusti in npr. če je buffer "1234" pusti vse kot je samo na začetku vpiše 1234
LP

www.microera.si

Vesoljc ::

se vedno ne razumes kaj ti je hotel senitel povedat...
Save_buffer je POINTER na buffer in sizeof(POINTER) je 4/8 byte-ov
ali pripelji velikost prek parametra tako kot si imel na zacetku ali pa dereferenciraj pointer: sizeof(*POINTER)

po dokumentaciji sodec moras uporabit _O_TRUNC flag
Abnormal behavior of abnormal brain makes me normal...

microera ::

v arrayeu oz. RxBuffer-ju so štirje byte-i, array do konca je zafilan z 0x00
Če dam sizeof(*Save_buffer)
mi zapiše v file samo 1.byte!
:(


_O_TRUNC flag mi vedno samo briše in nič ne zapiše!
(to bom nekako reši, da bom najprej file zbrisal pa nato vpisal nov file)
LP

www.microera.si

Zgodovina sprememb…

  • spremenil: microera ()

microera ::

sedaj sem spremenil vse v globalne spremenljivke in mi zadeva dela!
Edino Buffer, ki je dolg 1kB se zapiše tudi kot 1kB!
In tudi če dam namesto sizeof(Rxbuffer) kar število bytov, ki jih želim zapisati npr. 4 (če imam 4byte-e) mi vseeno zapiše v file 1kB (namesto samo 4byte)
... no nekaj ste mi pomagali!
LP

www.microera.si

mallard ::

Poženi tole:
#include <iostream>

void foo(char* buf)
{
    std::cout << sizeof(buf) << '\n'
              << sizeof(*buf);
}

int main()
{
    char buf[] = "zapis si za uhelj: arrayi niso pointerji.";
    std::cout << sizeof(buf) << '\n';
    foo(buf);
}


pa boš upam dojel, v čem se tvoja koda razlikuje od tiste z MSDN-a.

Array, dokler si v scope-u v katerem je definiran, nosi podatek o svoji velikosti (sizeof vrne število elementov krat sizeof enega elementa). Se pa, ko ga pošlješ kot argument fukciji, implicitno pretvori v kazalec na prvi element in takrat pač ni več array.

Zgodovina sprememb…

  • spremenilo: mallard ()


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

[C] LPC1343 - UART - AT commands

Oddelek: Programiranje
91025 (915) JanezovJanez
»

C in funkcije ter #define

Oddelek: Programiranje
463765 (2126) misek
»

[c] Enaki datoteki

Oddelek: Programiranje
7936 (796) Spura
»

[baze] Povezava do slike ali BLOB?

Oddelek: Programiranje
101574 (1371) BlueRunner
»

[C#] unmanaged->managed code

Oddelek: Programiranje
112062 (1937) Zzzzzzz

Več podobnih tem