Newsgroup: it.comp.lang.c++
Titolo: Realizzare semplice programma

Salve a tutti,
per un progetto universitario dovrei realizzare una semplice routine che 
setti a 0 gli ultimi 4 bit di ogni byte di un file generico..
Purtroppo ho poca esperienza di C++ e una giornata di ricerche su google non 
mi ha aiutato a risolvere in maniera semplice il problema.
Sfortunatamente ho poco tempo quindi mi trovo nella situazione di chiedere 
una mano a chi ha più esperienza di me.
Qualsiasi dritta è ben accetta!
Zippo.

 setti a 0 gli ultimi 4 bit di ogni byte di un file generico..
Se per "ultimi 4 bit" intendi quelli meno significativi allora prova con
n &= ~0xF;
EMG
--
EMAG Software Homepage:     
http://www.emagsoftware.it
The EMG's ZX-Spectrum Page: 
http://www.emagsoftware.it/spectrum
The Best of Spectrum Games: 
http://www.emagsoftware.it/tbosg
The EMG Music page:         
http://www.emagsoftware.it/emgmusic
 

 n &= ~0xF;
Sě, intendevo i 4 meno significativi.
Grazie per la risposta ma non so "dove" e "come" applicare il comando che mi 
hai dato..
Il massimo che sono riuscito a fare č aprire il file char per char, ma non 
so nemmeno se ho fatto la cosa giusta..

 
per l'istruzione che setta a zero gli ultimi 4 bit di un char (che è
garantito essere sempre di un byte), puoi usare facilmente l'operatore
di "and" bit-a-bit, ovvero:
carattere &= 0xF0;
dopodiché, basta aprire un file in lettura, uno in scrittura, ed
iterarci sopra.
// ------------------------
#include <fstream>
#include <functional>
#include <iterator>
#include <algorithm>
#include <iostream>
#include <ios>
struct set_z_r4b : public std::unary_function<const char&, char> {
public:
  char operator() ( const char& c ) { return c & _mask; }
private:
  static const char _mask;
};
const char set_z_r4b::_mask = 0xF0;
int // give me two parameters: input file and output file
main( int argc, char* argv[] ) {
  using namespace std;
  if( argc != 3 ) return -1;
  ifstream ifs( argv[1], ios::binary | ios::in );
  ofstream ofs( argv[2], ios::binary | ios::out );
  if( ifs == 0 || ofs == 0 ) {
    cerr << "complain loudly." << endl;
    return -1;
  }
  set_z_r4b func;
  transform( istream_iterator<char> (ifs),
	     istream_iterator<char> (),
	     ostream_iterator<char> (ofs),
	     func );
  ifs.close();
  ofs.close();
}
// -------------------------
aggiustalo tu se lo vuoi più semplice.
dovresti inoltre operare a blocchi per aumentare le prestazioni su file
di grandi dimensioni, invece che carattere per carattere come faccio
qui. inoltre non controllo bene per possibili problemi durante la
lettura del file.
- --
Matteo Settenvini
FSF Associated Member
Email : 
mat...@member.fsf.org
- -----BEGIN GEEK CODE BLOCK-----
Version: 3.12
GCS d--(-) s+:- a-- C++ UL+++
P?>++ L+++>$ E+>+++ W+++ N++ o?
w--- O- M++ PS++ PE- Y+>++
PGP+++ t+ 5 X- R tv-- b+++ DI+
D++ G++ e h+ r-- y?
- ------END GEEK CODE BLOCK------
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - 
http://enigmail.mozdev.org
iD8DBQFDZ5BtUDehq0srSdYRAmnZAJ4/lv1BwEd8ZWCG1O8xH8mJCq58cACeIfwD
0zjv6OL82PhHr5k0JUkjGog=
=qgx9
-----END PGP SIGNATURE-----

      func );
Cos'è transform?
Ho provato il tuo prog su una immagine non compressa YUV 4:2:0 di 155.648 
byte e il file prodotto invece è di 151.552 byte.
Non dovrebbero avere la stessa dimensione?
Grazie per il supporto! 

Ho risolto il problema con un codice abbastanza semplice, grazie a tutti per 
il supporto!
Il risultato è questo:
____________
#include <iostream>
#include <fstream>
#include <string>
#include <conio.h>
using namespace std;
int main() {
    ifstream file("1cif.yuv", ios::in | ios::binary);
    int lunghezzaFile=0;
    file.seekg(0L,ios::end);
    lunghezzaFile=file.tellg();
    cout << "Dimensione del file (byte): "<< lunghezzaFile << endl;
    file.close();
    ifstream file2("1cif.yuv", ios::in | ios::binary);
    ofstream file_out("2cif.yuv", ios::binary | ios::out);
    unsigned char c;
    int i=0;
    while(i<lunghezzaFile){
        c = file2.get();
        file_out<<(char)(c&0xF0);
        i++;
    }
    file2.close();
    file_out.close();
    getch();
    return 0;
}
____________ 

 
transform è una utile funzione delle STL definita nell'header standard
algorithm, insieme a copy, sort ed a tante altre. Puoi trovarne una
descrizione ed un paio di esempi qui:
http://www.sgi.com/tech/stl/transform.html
tra parentesi sì, dovrebbero avere la stessa dimensione... ci sarà
qualcosa che non va nel mio programma, l'ho scritto in fretta.
Ciao,
- --
Matteo Settenvini
FSF Associated Member
Email : 
mat...@member.fsf.org
- -----BEGIN GEEK CODE BLOCK-----
Version: 3.12
GCS d--(-) s+:- a-- C++ UL+++
P?>++ L+++>$ E+>+++ W+++ N++ o?
w--- O- M++ PS++ PE- Y+>++
PGP+++ t+ 5 X- R tv-- b+++ DI+
D++ G++ e h+ r-- y?
- ------END GEEK CODE BLOCK------
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - 
http://enigmail.mozdev.org
iD8DBQFDZ8GIUDehq0srSdYRAoCeAKCNm4ZZzAcmsweWDkwS7rL/0oXTLQCeLi3h
OEOk9YJEUIfF36QwLVfliaI=
=sCCO
-----END PGP SIGNATURE-----

 lettura del file.
Sarebbe bene, ma è molto difficile. Gli stream non danno molte
informazioni sulle cause delle errori. In ogni caso, tutte le
errori son memorizate nello stream. Puoi sempre provare dopo:
    if ( ifs.bad() ) {
        cerr << "read error!!!" << end l
    }
    ifs.close() ;
    ofs.close() ;
    if ( ! ofs ) {
        cerr << "write error!!!" << endl ;
    }
--
James Kanze                                           GABI Software
Conseils en informatique orientée objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, 
+33 (0)1 30 23 00 34

     }
Sì, avevo pensato anche io di usare il metodo "bad"; tra parentesi, qual
è la differenza tra "bad" e "fail"?
Comunque colgo l'occasione per dire dove sta il problema che era emerso
con il mio programma, e cioé che producesse un output più piccolo
dell'originale: l'istream_iterator non fa altro che applicare
l'operatore "<<" dal file a un suo campo interno (in questo caso, una
stringa). Ciò significa che spezza parola per parola usando come
delimitatore qualsiasi carattere di spaziatura (blank, "\t", "\r", "\n"...).
Non ho assolutamente trovato un modo furbo di modificare il
comportamento di istream_iterator proprio a causa del suo "contratto",
quindi NON credo sia il modo giusto per risolvere il problema. Forse, è
meglio leggere il file sequenzialmente con getc/putc, o comunque a
"blocchi".
Grazie,
- --
Matteo Settenvini
FSF Associated Member
Email : 
mat...@member.fsf.org
- -----BEGIN GEEK CODE BLOCK-----
Version: 3.12
GCS d--(-) s+:- a-- C++ UL+++
P?>++ L+++>$ E+>+++ W+++ N++ o?
w--- O- M++ PS++ PE- Y+>++
PGP+++ t+ 5 X- R tv-- b+++ DI+
D++ G++ e h+ r-- y?
- ------END GEEK CODE BLOCK------
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - 
http://enigmail.mozdev.org
iD8DBQFDa5aTUDehq0srSdYRAnmfAJ9FUinRW9OBQOk021XkYYvTyxFyjwCgrNj7
wj/nPWBCy7LjHagkbh1r9aI=
=D896
-----END PGP SIGNATURE-----

Matteo Settenvini wrote:
 > kanze wrote:
 >>Matteo Settenvini wrote:
 >>    [...]
 >>> ifstream ifs( argv[1], ios::binary | ios::in );
 >>> ofstream ofs( argv[2], ios::binary | ios::out );
 >>> if( ifs == 0 || ofs == 0 ) {
 >>Scusa, mÃ  cos'Ã¨ questo? Non ho mai visto scritto cosi. In
 >>generale si scrive:
 >>    if ( ! ifs || ! ifo ) ...
 >>PerchÃ¨ la forma inabituale?
 > Senti, ma che fastidio ti dÃ ? Sempre a cercare il pelo
 > nell'uovo... se a me piace di piÃ¹ cosÃ¬, potrÃ² ben scriverlo
 > come mi pare, no?
Se t'è eguale se altri può capire il codice o non. Ho solo
domandato; non ho mai visto la tua formulazione primo? Bisognavo
un paio di minuti anche per capirlo. Allora, mi son domandato se
c'è una ragione. Penso che non l'ha fatto per caso.
 >>>inoltre non controllo bene per possibili problemi durante la
 >>>lettura del file.
 >>Sarebbe bene, ma Ã¨ molto difficile. Gli stream non danno
 >>molte informazioni sulle cause delle errori. In ogni caso,
 >>tutte le errori son memorizate nello stream. Puoi sempre
 >>provare dopo:
 >>    if ( ifs.bad() ) {
 >>        cerr << "read error!!!" << end l
 >>    }
 >>    ifs.close() ;
 >>    ofs.close() ;
 >>    if ( ! ofs ) {
 >>        cerr << "write error!!!" << endl ;
 >>    }
 > SÃ¬, avevo pensato anche io di usare il metodo "bad"; tra
 > parentesi, qual Ã¨ la differenza tra "bad" e "fail"?
La funzione bad() prova solo il "badbit", fail "badbit | failbit".
In generale:
Ci son tre bits d'"errore" possibile:
badbit:
     Errore "hard", tipo errore di lecture o di scrittura. In
     fatti, viene messo a uno a tutto errore in scrittura, invece
     quando il streambuf alza un'exception in lettura.
failbit:
     Altro errore, tipi errore di formattagio o fine di file.
     Nella pratica, non viene mai in scrittura. In lettura,
     significa o bene che abbiamo cercato a leggere dopo la fine,
     o bene che c'è stato un errore nel format (catena "abc" in
     entrata, e >> verso un int, da essempio).
eofbit:
     Viene messo a uno ogni volta che la funzione di conversion
     vede la fine de file, anche si la vede solo nel
     "look-ahead". (Cioè: può venire messo a uno anche a una
     lettura senza errore.)
Le funzione son anche diverse:
bad():
     Ritorna (rdstate() & badbit) != 0. Allora, è vero solo se
     c'è stato errore fisica di lettura.
fail():
     Ritorna (rdstate() & (badbit | failbit)) != 0. È vero ogni
     volta che l'ultima azione non a riuscito. In lettura sarà
     sempre vero se abbiamo letto tutto il file.
     È il più importante degle funzioni. È la basa degli
     operatori ! et (void*). Serva dopo ogni lettura per sapere
     se abbiamo letto qualcosa.
eof():
     Ritorna (rdstate() & eofbit) != 0. Da eofbit può essere
     messo a uno anche quando la lettura riesce, si usa
     praticammente solo dopo fail(), quando fail() è vero -- se
     hai fail() && ! eof(), significa che c'è un errore di
     format.
good():
     Ritorna (rdstate() == 0). Cioè false, anche se c'è solo
     eofbit. Non ne ho mai trovato un'utilisazione.
Come vedi, la semantica delle funzioni non è cosi chiare. Per
quello, molti esperti consigliano usare piùtosto l'operator! o
la conversione:
     input >> i ;
     if ( input ) {
         //  a riuscito...
     }
o
     input >> i ;
     if ( ! input ) {
         //  non a riuscito...
     }
Se non ha riuschito (e solo allora), puoi domandare perche:
     input >> i ;
     if ( ! input ) {
         if ( input.bad() ) {
             //  probleme di hardware...
         } else if ( ! input.eof() ) {
             //  errore di format...
         } else {
             //  fine di file...
         }
     } else {
         //  riuscito, i è buono...
     }
Infine, noti che provo lo stato del file di uschita *dopo* il
close. Infatti, certi errori di uscita non sono riconusciuti che
nel close. È solo dopo il close che puoi dire se tutte le date
son state scritte o non.
 > Comunque colgo l'occasione per dire dove sta il problema che
 > era emerso con il mio programma, e cioÃ© che producesse un
 > output piÃ¹ piccolo dell'originale: l'istream_iterator non fa
 > altro che applicare l'operatore "<<" dal file a un suo campo
 > interno (in questo caso, una stringa). CiÃ² significa che
 > spezza parola per parola usando come delimitatore qualsiasi
 > carattere di spaziatura (blank, "\t", "\r", "\n"...).
Infatti, per una copia cosi, vale meglio utilisare
istreambuf_iterator.
 > Non ho assolutamente trovato un modo furbo di modificare il
 > comportamento di istream_iterator proprio a causa del suo
 > "contratto",
Prova:
     input.unsetf( std::ios::skipws ) ;
prima di fare la copia.
Ma trova che si vuoi copiare tutti, cioè si non vuoi occuparti
dal format, istreambuf_iterator dice meglio cosa vuoi fare.
-- 
James Kanze                                 mailto: 
james...@free.fr
Conseils en informatique orientée objet/
                        Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France 
+33 (0)1 30 23 00 34



Grazie mille per la risposta accurata. Proverò appena ho tempo.
Ciao,
-- 
Matteo Settenvini
FSF Associated Member
Email : 
mat...@member.fsf.org
-----BEGIN GEEK CODE BLOCK-----
Version: 3.12
GCS d--(-) s+:- a-- C++ UL+++
P?>++ L+++>$ E+>+++ W+++ N++ o?
w--- O- M++ PS++ PE- Y+>++
PGP+++ t+ 5 X- R tv-- b+++ DI+
D++ G++ e h+ r-- y?
------END GEEK CODE BLOCK------