Parsarea fişierului de ieşire

Aşa cum puteţi vedea aici, parsarea intrării este foarte avantajoasă când este nevoie să salvăm timp la execuţie. Deşi mai rar întâlnită, parsarea ieşirii se poate dovedi şi ea utilă în multe cazuri. Ca şi în materialul precedent, vom oferi bucăţi de cod exemplu, atât pentru varianta funcţională (compatibilă cu limbajul C), cât şi pentru cea obiectuală (compatibilă cu C++, asemănătoare cu sintaxa cout).

Cod compatibil cu limbajul C++ şi sintaxa <fstream> (obiectual)

Acesta este un cod demonstrativ pentru parsarea fişierului de ieşire folosind metoda obiectuală:

#include <cstdio>
#include <cstring>

using namespace std;

class OutParser {
private:
    FILE *fout;
    char *buff;
    int sp;
 
    void write_ch(char ch) {
        if (sp == 50000) {
            fwrite(buff, 1, 50000, fout);
            sp = 0;
            buff[sp++] = ch;
        } else {
            buff[sp++] = ch;
        }
    }
 
 
public:
    OutParser(const char* name) {
        fout = fopen(name, "w");
        buff = new char[50000]();
        sp = 0;
    }
    ~OutParser() {
        fwrite(buff, 1, sp, fout);
        fclose(fout);
    }
 
    OutParser& operator << (int vu32) {
        if (vu32 <= 9) {
            write_ch(vu32 + '0');
        } else {
            (*this) << (vu32 / 10);
            write_ch(vu32 % 10 + '0');
        }
        return *this;
    }
 
    OutParser& operator << (long long vu64) {
        if (vu64 <= 9) {
            write_ch(vu64 + '0');
        } else {
            (*this) << (vu64 / 10);
            write_ch(vu64 % 10 + '0');
        }
        return *this;
    }
 
    OutParser& operator << (char ch) {
        write_ch(ch);
        return *this;
    }
    OutParser& operator << (const char *ch) {
        while (*ch) {
            write_ch(*ch);
            ++ch;
        }
        return *this;
    }
};

Cum folosim acest cod?

Aveţi mai jos un exemplu care urmează sintaxa fstream:

int main()
{
	OutParser fout("exemplu.out");
	fout << 324 << "sdfjhj 87473hriufhe" << '\n' << 638274623846 << '\n'; // !!! endl nu funcţionează, şi oricum şi în fstream este lent. Folosiţi '\n'.
	return 0;
}

Cod compatibil cu limbajul C (procedural)

Această variantă este perfect compatibilă cu standardele C, întrucât foloseşte funcţii pentru fiecare tip în parte.

#include <stdio.h>
 
/** Funcţiile necesare parsării fişierului de ieşire **/
FILE *_fout;
int _out_loc; char _out_buff[50000];
 
void write_init(const char* name) // Apelaţi această funcţie la începutul funcţiei <main>
{
    _fout = fopen(name, "w");
    _out_loc = 0;
}
 
void write_ch(char ch) // Apelaţi această funcţie pentru a scrie un caracter (cum ar fi ' ' sau '\n')
{
    if (_out_loc == 50000) {
        fwrite(_out_buff, 1, 50000, _fout);
        _out_loc = 0;
        _out_buff[_out_loc++] = ch;
    } else {
        _out_buff[_out_loc++] = ch;
    }
}
 
void write_u32(unsigned int vu32) // Apelaţi această funcţie pentru a scrie un număr ce se încadrează în categoria <unsigned int>
{
    if (vu32 <= 9) {
        write_ch(vu32 + '0');
    } else {
        write_u32(vu32 / 10);
        write_ch(vu32 % 10 + '0');
    }
}
 
void write_u64(unsigned long long vu64) // Apelaţi această funcţie pentru a scrie un număr ce se încadrează în categoria <unsigned long long>
{
    if (vu64 <= 9) {
        write_ch(vu64 + '0');
    } else {
        write_u64(vu64 / 10);
        write_ch(vu64 % 10 + '0');
    }
}
 
void write_appendix() // ###! ATENŢIE, Apelaţi această funcţie la finalul prgramului. Altfel, fisierul outpt NU VA CONŢINE ÎN ÎNTREGIME ceea ce doriţi!
{
    fwrite(_out_buff, 1, _out_loc, _fout);
    fclose(_fout);
}

Cum folosim acest cod?

Aveţi mai jos un exemplu care urmează sintaxa C:

int main()
{
	write_init(exemplu.out");
	write_u32(1465423745);
	write_ch(' ');
	write_u64(23441465423745);
	write_ch('\n');
	write_ch('&');
	write_appendix(); // Din nou, NU UITAŢI ACEASTĂ FUNCŢIE! Ea copiază ce a rămas din buffer în fişier.
	return 0;
}