Visualizzazione dei risultati da 1 a 9 su 9
  1. #1

    [C++] Creare file preferenze

    Salve,

    avrei bisogno di creare un file preferenze per memorizzare alcuni settings della mia app. Per adesso mi accontento di salvare le coordinate della finestra x,y entrambi short. Per fare questo volevo creare un file binario dove memorizzare le coordinate in esadecimale. I primi due bytes sarebbero la X e i successivi 2 bytes sarebbero la Y.

    codice:
    short x = 20;
    short y = 20;
    
    #include <fstream>
    std::ofstream hfile;
    hfile.open("pref.txt", std::ios::out|std::ios::binary);
    hfile.write(x);
    hfile.write(y);
    hfile.close();
    come faccio a salvare i dati in binario (hex) ??

    grazie
    Alla batteria dai retta ballA

  2. #2
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    codice:
    hfile << hex << x;
    hfile << hex << y;
    every day above ground is a good one

  3. #3
    mi server qualcosa che riempa due byte e altri due byte...
    Alla batteria dai retta ballA

  4. #4
    diciamo una cosa del genere: (questa salva a gruppi di 4 bytes a me va benissimo)

    codice:
    #include <sstream>
    
    class hexPack
    {
    public:
    	hexPack(int value) : m_value(value) { }
    	friend std::ostream& operator<<(std::ostream& os, const hexPack& pack)
    	{
    		return os.put((pack.m_value >> 24) & 0xFF).put((pack.m_value >> 16) & 0xFF).put((pack.m_value >> 8) & 0xFF).put(pack.m_value & 0xFF);
    	}
    private:
    	unsigned m_value;
    };
    
    (...)
    
    	// Write Packed Data //
    	//
    	{
    		std::stringstream k;
    
    		std::ofstream hfile;
    		hfile.open(szPrefFile, std::ios::out|std::ios::binary);
    		if(hfile.bad())
    			return -1;
    
    		k << hexPack(20);  // Top
    		k << hexPack(25);  // Left
    		k << hexPack(650); // Width
    		k << hexPack(450); // Height
    
    		hfile.write(k.str().c_str(), 4*4);
    
    		hfile.close();
    	}
    	///////////////////////
    soltanto che ora devo trovare un modo per rigirare la classe, ovvero gli passo 4 bytes e mi ritorna l'int...
    Alla batteria dai retta ballA

  5. #5
    Avevo scritto una roba del genere una volta per scrivere i dati in esadecimale con in più un byte di controllo; il tutto parte di una classe per gestire una sezione di un file .ini. Interessa?
    Amaro C++, il gusto pieno dell'undefined behavior.

  6. #6
    beh si, però anche una soluzione al problema
    Alla batteria dai retta ballA

  7. #7
    Per scrivere dati binari di qualunque lunghezza in esadecimale:
    codice:
    //Structure
    
    void INISection::PutKey(const std::_tcstring & Key, const void * Struct, size_t StructSize)
    {
    	unsigned char checksum=0;
    	const unsigned char * castedStruct=(const unsigned char *)Struct;
    	strStream.clear();
    	strStream.str(_T(""));
    	TCHAR oldFill=strStream.fill(_T('0'));
    	strStream<<std::hex;
    	for(const unsigned char * readPtr=castedStruct;readPtr<castedStruct+StructSize;readPtr++)
    	{
    		strStream<<std::setw(2)<<*readPtr;
    		checksum=checksum+*readPtr;
    	}
    	strStream<<std::setw(2)<<checksum; //<-- se non ti serve il checksum, togli tutta la parte che lo riguarda
    	PutKey(Key,strStream.str()); //<-- nel tuo caso qui scriverai su file
    	strStream<<std::dec;
    	strStream.fill(oldFill);
    }
    Per rileggere questa roba:
    codice:
    //Structure
    void INISection::GetKey(const std::_tcstring & Key, void * Struct, size_t StructSize) const
    {
    	if(!KeyExists(Key))
    		return;
    	unsigned char checksum=0, checksum2=0;
    	unsigned char * castedStruct=(unsigned char *)Struct;
    	//Get the string
    	std::_tcstring strValue=GetKey(Key,_T("")); //<-- nel tuo caso qui leggerai dal file
    	if(strValue.size()==0)
    		return;
    	const TCHAR * readPtr=strValue.c_str();
    	//Length check
    	if(strValue.size()<(StructSize+1)*2)
    		throw std::runtime_error(ERROR_STD_PROLOG "The stored value is not valid for this structure.");
    	//Convert the string
    	for(unsigned char * writePtr=castedStruct;
    		writePtr<castedStruct+StructSize;
    		writePtr++,readPtr+=2)
    	{
    		*writePtr=getByte(readPtr);
    		checksum=checksum+*writePtr;
    	}
    	checksum2=getByte(readPtr);
    	//Compare the checksums
    	if(checksum!=checksum2)
    		throw std::runtime_error(ERROR_STD_PROLOG "Invalid checksum.");
    }
    
    //Returns a byte from a pair of hexadecimal digits
    unsigned char INISection::getByte(const TCHAR * str)
    {
    	unsigned char ret=0;
    	TCHAR ch;
    	for(int i=0;i<2;i++)
    	{
    		ch=_totupper(str[i]);
    		if(BETWEEN(ch,_T('0'),_T('9')))
    			ret|=(ch-_T('0'))<<((1-i)<<2);
    		else if(BETWEEN(ch,_T('A'),_T('F')))
    			ret|=(ch-_T('A')+10)<<((1-i)<<2);
    		else
    			throw std::runtime_error(ERROR_STD_PROLOG "Invalid character.");
    	}
    	return ret;
    }
    Ignora ERROR_STD_PROLOG (è una macro usata per aggiungere qualche informazione al messaggio di errore*); _tcstring è un typedef per std::basic_string<TCHAR>; BETWEEN è definita come
    codice:
    #define BETWEEN(n,min,max) ((n)>=(min)&&(n)<=(max))
    /*
    	Note that the argument n is evaluated two times.
    
    	Example of use of the BETWEEN macro:
    
    	int n;
    	//...
    	if(BETWEEN(n,15,17))
    		cout<<"n is between 15 and 17";
    */
    e serve semplicemente per verificare se il primo parametro passato sta tra due valori.

    * per i curiosi:
    codice:
    #define ERROR_STD_PROLOG    "Exception thrown in function: " __FUNCSIG__ " (in " __FILE__ ", last modified on " __TIMESTAMP__ ", line " TOSTRING( __LINE__ ) ").\nMessage: "
    ci sono modi migliori per fare questo, ma non avevo tempo né voglia di cambiare tutte le classi di eccezioni.
    Amaro C++, il gusto pieno dell'undefined behavior.

  8. #8
    perfetto!
    Alla batteria dai retta ballA

  9. #9

    Dimenticavo, strStream è ovviamente uno string stream (nel mio caso basato sui TCHAR); non è dichiarato perché nel codice da cui sono tratte le due procedure è comune a tutta la classe.
    Amaro C++, il gusto pieno dell'undefined behavior.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.