PDA

Visualizza la versione completa : [C++] Cast da PSHORT a char*


gianvituzzi
04-01-2010, 01:38
Salve,

stavo curiosando tra le differenze tra la libreria C++ <fstream> e la C <stdio.h> per leggere files binari...in particolare nella spiegazione della fread trovo:



size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );

ptr -> Pointer to a block of memory with a minimum size of (size*count) bytes.
...
...
...


ed avevo trovato un codice in rete che faceva una cosa del genere:



while ( (dwRead=fread(pWAVBuffer,sizeof(SHORT),dwSamples,p FileIn)) >0 )
// dove pWAVBuffer è:
// PSHORT pWAVBuffer = NULL;
// pWAVBuffer = new SHORT[dwSamples];


allora volevo provare a rifare l'esempio ma usando la <fstream>



int main()
{
PSHORT pBuffer = NULL;
pBuffer = new SHORT[20];

std::ifstream inFile;
inFile.open( file, std::ios::in|std::ios::binary );
inFile.seekg(0, std::ios::beg);
inFile.read(pBuffer, 20);
inFile.close();

printf("%s\n", buffer);

system("pause");
}


naturalmente mi da problemi di cast...come posso forzare la conversione??

grazie

NB: che senso ha definire un buffer di dati con:

// PSHORT pWAVBuffer = NULL;
// pWAVBuffer = new SHORT[dwSamples];

???

oregon
04-01-2010, 02:23
Il buffer può essere allocato in una riga



PSHORT pBuffer = new SHORT[20];


Il cast è semplice ... basta che tu faccia attenzione ai tipi dei parametri ... e ricorda che la grandezza è in byte



inFile.read((LPSTR)pBuffer, 20*sizeof(SHORT));


Ovviamente questo deve essere così



printf("%s\n", pBuffer);


e la funzione si aspetta un int di ritorno



return 0;




grazie


prego

gianvituzzi
04-01-2010, 02:37
il codice risale al 2000 e l'autore l'ha scritto in C (credo). Volevo portarlo a C++ usando <fstream> dato che il compilatero mi da degli warnings (deprecated) quando uso fopen e le relative funzioni.

mi domando allora quale fosse la differenza di fondo nel fare così:



int main()
{
LPSTR pBuffer = new char[20];

std::ifstream inFile;
inFile.open( file, std::ios::in|std::ios::binary );
inFile.seekg(0, std::ios::beg);
inFile.read(pBuffer, 20);
inFile.close();

printf("%s\n", pBuffer);

system("pause");
}


se il fare PSHORT pBuffer = new SHORT[20]; appartenesse ad una mentalità C

gianvituzzi
04-01-2010, 02:52
Poi ho notato una cosa, se uso 20*sizeof(SHORT) mi vengono ritornati più di venti caratteri anche se PSHORT pBuffer = new SHORT[20];

se provo a leggere un file testuale dopo aver letto n caratteri la printf mi stampa strani caratteri un printable.

infine ho provato a turno tre diversi modi:



// LPSTR pBuffer = new char[20]
// PSHORT pBuffer = new SHORT[20]
// PBYTE pBuffer = new BYTE[20]


ed entrambi mi sembrano andare bene...ho letto che:

SHORT = A 16-bit integer. The range is –32768 through 32767 decimal.
BYTE = Byte (8 bits).
LPSTR = Pointer to a null-terminated string of 8-bit Windows (ANSI) characters.

se devo fare un buffer che contiene dati binari...quale dovrei scegliere??

grazie

oregon
04-01-2010, 03:02
Originariamente inviato da gianvituzzi
ho letto che:

SHORT = A 16-bit integer. The range is –32768 through 32767 decimal.
BYTE = Byte (8 bits).
LPSTR = Pointer to a null-terminated string of 8-bit Windows (ANSI) characters.

se devo fare un buffer che contiene dati binari...quale dovrei scegliere??

grazie

Scusa gianvituzzi, ma quindi tu non lavori nel campo dell'informatica ... dato che non conosci la differenza tra uno short e un byte.

Uno short è un valore numerico intero con segno a 16 bit (quindi ogni valore occupa due byte in memoria, in formato binario in complemento a due ... quindi non stampabili in quanto non ASCII)

Un char rappresenta un singolo carattere ASCII standard (quindi occupa un singolo byte stampabile)

Per il buffer, dipende da che tipo di dati binari questo deve contenere. Ma questo è indipendente dal fatto che la read o la write operino poi come se questo buffer fosse una semplice sequenza di byte binari (non stampabili).

gianvituzzi
04-01-2010, 10:23
devo ammettere che usando linguaggi ad alto livello e anche usando di solito bytes ovvero 8 bit per char 0/255 nello scrivere/leggere dati binari non mi era ancora capitata una cosa del genere! Sopratutto ho sempre inteso short come un tipo rivolto solo ai numeri interi.

Ora mi è più che chiaro perchè l'autore di quel codice a usato lo SHORT. doveva leggere un file WAVE a 44.1Khz Stereo 16 bit

a questo punto mi chiedo se per leggere il file in questione (.wav) mi convenga usare la classica <cstdio> oppure la <fstream> tenendo presente che la fread mi permettere di leggere il buffer verso un puntatore ad un blocco di memoria generico (sia esso byte o short) mentre ifstream.read mi permette solo LPSTR...e quindi necessita del relativo cast, inoltre fread mi sembra dare più opzioni per leggere dati binary:



fread ( void * ptr, size_t size, size_t count, FILE * stream );


grazie

oregon
04-01-2010, 12:07
Essendo dei "campioni" audio convertiti in binario con 16 bit, il buffer è una sequenza di short.

Ma mi sembra ti stia facendo dei problemi dove non esistono.

Con tutti i due metodi puoi fare quello che vuoi.

shodan
04-01-2010, 12:47
Originariamente inviato da gianvituzzi
dato che il compilatero mi da degli warnings (deprecated) quando uso fopen e le relative funzioni.


Sono solo una seccatura. Puoi ignorarli tranquillamente, anche perché tutte le funzioni che ti danno warning, non sono deprecate nello standard ISO.

gianvituzzi
06-01-2010, 01:06
un'ultima cosa, data questa linea,

dwRead = fread(pWAVBuffer, sizeof(SHORT), dwSamples, pFileIn));

se avessi voluto memorizzare in LPSTR invece che PSHORT, avrei dovuto usare dwSamples*2??

oregon
06-01-2010, 01:35
Sarebbe dovuto essere

(..., sizeof(char), dwSamples*sizeof(SHORT), ...);

Loading