Separatore delle stringhe

di il
4 risposte

Separatore delle stringhe

Buona sera a tutti,io devo separare i campi usando la |,quindi ho scritto la funzione che deve separare i caratteri dei campi,ma non sono sicuro che sia quella corretta,potreste aiutarmi a creare la funzione split in c++?

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

struct person {
	string lastname;
	string firstname;
	int sequenze_number;
};

void init(person &p);
void save_archivio(person p[100], int n);
int load_archivio(person p[100]);

int main() {
	person p[100];
	int n;
	do
	{
		cout << "Inserisci n: ";
		cin >> n;
	} while (n < 0 || n>100);

	for (int i = 0; i < n; ++i) {
		init(p[i]);
	}

	save_archivio(p, n);
	n = load_archivio(p);

	cout << "Caricati " << n << " elementi" << endl;

	system("pause");

	return 0;

}

void init(person &p) {
	cout << "Cognome:";
	cin >> p.lastname;
	cout << "Nome:";
	cin >> p.firstname;
	p.sequenze_number = 1;

}

void save_archivio(person p[100], int n) {
	ofstream archivio("archivio.csv");
	if (archivio.is_open()) {
		for (int i = 0; i < n; ++i) {
			archivio << p[i].lastname << "|";
			archivio << p[i].firstname << endl;
		}

		archivio.close();
	}
}

int load_archivio(person p[100]) {
	int count = 0;
	string line;
	ifstream archivio("archivio.csv");
	if (archivio.is_open()) {
		while (getline(archivio, line)) {
			cout << line << endl;
			++count;
		}
	}

	return count;

}
void split(const char *line, char campi[][256]) {

	int i, j;
	for (i = 0; i < 256; i++)
		for (j = 0; j < 256; j++)
			if (line == '\0' && campi[i][j] == '\0')
				campi[i][j] == '|';
	cout << campi[i][j] << endl;
}






4 Risposte

  • Re: Separatore delle stringhe

    Perché non usi la strtok ?
  • Re: Separatore delle stringhe

    oregon ha scritto:


    Perché non usi la strtok ?
    Perchè non abbiamo mai usato la strtok?
  • Re: Separatore delle stringhe

    Beh è il momento dj cogliere il suggerimento, cercare e studiare la funzione strtok, non credi?
  • Re: Separatore delle stringhe

    In C, per non usare strtok() (non perché non vada bene, solo per "speculazione"), ho trovato comodo predisporre una funzione estrai_elemento() con queste caratteristiche:
    
    /*==============================================================================
    
     PARAMETRI IN INGRESSO
    
        const char *s   la stringa dalla quale estrarre il primo elemento
                        eventualmente disponibile, individuato usando il
                        carattere sep come separatore tra gli elementi
                        (N.B. '\n' indica il punto dove termina la lettura
                              dei dati e NON DEVE mancare)
    
        char sep        il carattere che viene usato per riconoscere il punto
                        di separazione tra gli elementi contenuti nella stringa
                        passata in s
    
     PARAMETRI IN USCITA
    
        char **e        in caso di successo dell'operazione, una copia
                        dell'elemento, in uno spazio di memoria allocato
                        dinamicamente con calloc(); spetta al chiamante
                        liberare la memoria eventualmente allocata
    
        int *le         in caso di successo dell'operazione, la lunghezza
                        dell'elemento copiato in *e
    
     VALORE DI RITORNO
    
        int             un codice di errore che puo' assumere uno dei seguenti
                        valori...
    
                        0: elemento estratto correttamente
                        1: elemento estratto correttamente
                           e fine dei dati raggiunta
                        2: puntatore non valido tra i parametri
                        3: nessun dato nella stringa dei dati
                        4: new line mancante nella stringa dei dati
                        5: allocazione fallita
    
                        N.B. in caso di errore non viene allocata memoria dinamica,
                             per cui in caso di errore non si deve liberare nulla;
                             in caso di errore, *e e' NULL e *le e' -1
    
    ==============================================================================*/
    
    int estrai_elemento( char **e, int *le, const char *s, char sep ) {
        /*
           se e e' valido, per prudenza preimposta *e su NULL
           se tutti i parametri sono validi...
           |   se la stringa non e' vuota...
           |   |   se la stringa contiene '\n'...
           |   |   |   trova la fine del primo elemento in s
           |   |   |   rileva la lunghezza dell'elemento trovato
           |   |   |   alloca memoria per una copia dell'elemento trovato
           |   |   |   se l'allocazione e' riuscita...
           |   |   |   |   copia l'elemento trovato nello spazio di memoria allocato
           |   |   |   |   segnala il puntatore alla copia in *e
           |   |   |   |   segnala la lunghezza della copia in *le
           |   |   |   |   restituisce 0 se ci sono altri elementi, 1 se e' l'ultimo
           |   |   |   ...se l'allocazione non e' riuscita, restituisce 5
           |   |   ...se la stringa non contiene '\n', restituisce 4
           |   ...se la stringa e' vuota restituisce 3
           ...se ci sono puntatori non validi tra i parametri restituisce 2
        */
    }
    
    Nel mio programma di prova ho usato la funzione direttamente nel main(), così:
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    const char kStr[] = "Uno|Due||Quattro|5\n";
    char kSep = '|';
    
    int estrai_elemento( char **e, int *le, const char *s, char sep ) {
        // implementazione
    }
    
    int main() {
        const char *pAux;
        char *elemento;
        int err, lElemento;
    
        for( pAux=kStr, err=0; err<1; pAux += lElemento+1) {
            err = estrai_elemento( &elemento, &lElemento, pAux, kSep );
            printf( "%s\n", elemento );
            free( elemento );
        };
    
        if( err > 1 ) printf( "Errore: %d\n\n", err );
    
        return 0;
    }
    
    Sempre per speculazione fine a se stessa... rispetto a strtok(), usare una funzione "personalizzata" come quella che m'è venuta in mente può dare alcuni vantaggi, ad esempio...

    - la possibilità di usare stringhe costanti
    - di conseguenza, la possibilità di mantenere intatta la stringa passata
    - la possibilità di rilevare campi vuoti (strtok() li salta?)
    - la possibilità di trattare più stringhe "in parallelo" senza "interferenze"

    Svantaggi che mi vengono in mente sono l'uso della memoria dinamica e (internamente, ad ogni chiamata) della funzione strrchr() per verificare la presenza del '\n'. Anche la necessità di aggiornare il puntatore ausiliario esternamente alla funzione potrebbe essere considerato uno scomodo orpello.

    Trattandosi di codice amatoriale, la mia funzione è inoltre sicuramente meno efficiente di strtok() (e magari contiene pure degli errori).
Devi accedere o registrarti per scrivere nel forum
4 risposte