[C++] Leggere dati da file

franbisc
Ho un file che è strutturato così:
Nome , cognome , codice(=string) :
stringa1.1, int1.1 , stringa2.1 , int2.1
stringa1.2, int1.2 , stringa2.2 , int2.2
ecc...

con il mio codice
    getline(in,nome, ',');
    getline(in,cognome,',');
    getline(in,codice,':');

    while(in.good()) {
        getline(in, string1, ',');
        in>>int1>>empty;
        getline(in, string2, ',');
        in>>int2;
     
      /*utilizzo string1/2, e int1/2 inserendoli dove mi servono
        Nella prossima iterazione del while leggerò la riga successiva contenente sempre
       due string e due int e li inserirò di nuovo dove mi servono
      */
    }


facendo così però,ovviamente,ogni volta insieme alle stringhe salva anche gli spazi e gli "\n" che rimagono con il precedente getline,e non va bene.

Ad esempio potrei controllare dopo ogni input che il primo carattere non sia "\n" o " ",ma nel caso lo fossero?come faccio a non copiarli nella stringa utile?

Risposte
giuscri
In riferimento alla parte di codice in cui devi estrarre una stringa e un intero, una stringa un intero, a capo io farei così: entrarrei tutta la riga salvandola in una variabile di tipo std::string; cercherei le occorrenze della virgola ed estrarrei volta per volta delle sottostringhe da assegnare alle variabili cui si riferiscono.
Per cercare le occorrenze delle virgole puoi usare std::string::find_first_of mentre per le sottostringhe puoi usare std::string::substr. Attenta a quali sono i parametri di quei metodi...

franbisc
verrebbero comunque inclusi gli spazi tra le virgole...

giuscri
"Mifert4":
verrebbero comunque inclusi gli spazi tra le virgole...


Be' no, perché la lunghezza della sottostringa te la gestisci tu. A meno che gli spazi siano disposti in modo irregolare lungo la riga puoi scrivere una procedura per estrarre una sottostringa dalla posizione $p$ alla posizione $q$, entrambe a tua liberissima scelta.

Se hai un file organizzato così, per esempio:

nome , cognome , anno di nascita

e se hai già assegnato a tmp_str i caratteri della riga che hai letto, allora:


  // ...

  std::string tmp_str;
  std::string comma = ",";
  std::size_t first_comma_pos, second_comma_pos;

  first_comma_pos = tmp_str.find_first_of(comma);
  std::string first_name = tmp_str.substr(0, first_comma_pos -1);
  // Just skipped the comma AND the space-char.

  // Now: "find the second comma, but start from the
  // first_comma_pos +1; instead you'll give me again the
  // position of the comma just read", in C++ is:
  second_comma_pos = tmp_str.find_first_of(comma, first_comma_pos +1); 
  std::string last_name;
  last_name = tmp_str.substr(first_comma_pos +2, (second_comma_pos - first_comma_pos) -4);

  int year_of_birth = tmp_str.substr(second_comma_pos +2);

  // ...
  


Faccio un po' di confusione con le posizioni nella stringa e secondo me non è proprio intuitivissimo: potrei aver scritto un 4 invece di un 3, o roba simile. Ma non mi sembra un metodo proprio da buttare questo.

Hai qualche dubbio? Può essere anche che sia una ciofeca come idea, eh...

franbisc
Be si,questo metodo andrebbe benissimo se fossero tutte stringhe,ma il problema è di quegli int in mezzo.

giuscri
"Mifert4":
Be si,questo metodo andrebbe benissimo se fossero tutte stringhe,ma il problema è di quegli int in mezzo.


Giusto.
Però puoi modificare il codice sopra come segue:


// Instead of:
// int year_of_birth = tmp_str.substr(second_comma_pos +2);

// Remember to type #include <sstream>

int year_of_birth;
std::istringstream (tmp_str.substr(second_comma_pos +2)) >> year_of_birth;

// "stringstream provides an interface to
// manipulate strings as if they were
// input/output streams."



Chiaramente ci saranno molte altre possibilità, probabilmente più affini al tuo modo di scrivere codice solitamente.


franbisc
ok,grazie

giuscri
"Mifert4":
ok,grazie


Prego...

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.