PDA

Visualizza la versione completa : [C++] convertire stringhe in numeri


davide84
06-04-2010, 18:12
Ciao a tutti, mi si presenta il seguente problema:
devo scrivere un programma in C++ che legga da un file con estensione .out delle righe, organizzate in colonne, cioè del tipo



1 3 1 2 0 688.5 4.9338 -4.3086 -2.4037 13980.000 13980.001 -0.000308208 -0.000171943
1 3 1 2 0 446.1 1.6010 -1.1634 -1.0999 13980.000 13980.000 -0.000083229 -0.000078682
2 -10 1 0 0 0.5833 8.0218 2.2202 7.7085 -13980.000 13980.006 0.000116279 0.001091720

fin qui tutto bene con la funzione getline.
Devo poi epurare queste righe da quelle che contengono dei meno in certe colonne, tipo la terza riga con -10. fin qui ci sono arrivato utilizzando l'istruzione


if (line[10]=='-'), dove line è il secondo parametro utilizzato nella funzione getline, il primo è il nome del file, mentre 10 è il posto in cui dovrebbe essere messo il -.

ora devo scrivere queste righe, riorganizzandole, in un file ROOT, il problema che mi sono posto è che devo mantenere la formattazione originale, inoltre in questo momento, io ho una string, cioè un insieme di caratteri, mentre ROOT richiede dei numeri, quindi il file deve essere riempito con dei numeri. Cercando in giro ho trovato le funzioni atoi, atof etc. ma come faccio a richiamarle per trasformare tutti i numeri di ogni singola riga? e come faccio a trasformare i numeri che hanno più di una cifra?
grazie in anticipo a tutti coloro che volessero aiutarmi.
Ciao

P.S. Vi assicuro che la formattazione dei dati è giusta, non riesco a riprodurla nel post ma le righe sono ben allineate

antotan
06-04-2010, 18:29
Per convertire una stringa in un numero, in C++, usa gli stringstream:



#include <iostream>
#include <sstream>
#include <string>

using namespace std;

template <typename T>
T parse(string str)
{
stringstream ss;
T t;

ss << str;
ss >> t;

return t;
}

int main()
{
int x;
double y;
int z;

x = parse<int>("-144");
y = parse<double>("-87.98");
z = parse<int>("12312");

cout << x << endl;
cout << y << endl;
cout << z << endl;

return 0;
}


:ciauz:

davide84
06-04-2010, 20:27
beh grazie davvero per l'aiuto,
il programma converte delle stringhe costanti in numeri,
ma come posso fare a convertire delle stringhe che ho letto da un file???

grazie ancora per l'aiuto

antotan
06-04-2010, 21:02
Originariamente inviato da davide84
beh grazie davvero per l'aiuto,
il programma converte delle stringhe costanti in numeri


Precisamente, la funzione parse converte dei std::string in numeri.
Indirettamente, nel programma convertiamo dei char* in numeri, dato che std::string ha un costruttore che accetta un char*.



ma come posso fare a convertire delle stringhe che ho letto da un file???

grazie ancora per l'aiuto

nella stessa maniera. Leggi il file, ottieni le stringhe e passale alla funzione. Ad esempio, se hai un file come questo:



1 10 -23
5 9.324 43


in cui ogni numero è diviso da uno spazio e ogni riga è separata dal carattere di a capo, puoi fare così:



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

using namespace std;

template <typename T>
T parse(string str)
{
stringstream ss;
T t;

ss << str;
ss >> t;

return t;
}

int main()
{
ifstream inFile("num.txt");
string line;

if(inFile.is_open())
{
while( getline(inFile, line) )
{
stringstream ss;
string num;

ss << line;

while( getline(ss, num, ' ') )
{
cout << "|" << parse<double>(num) << "|" << endl;
}
}
}

return 0;
}


Nel primo ciclo leggi una riga, nel ciclo più interno splitti la riga, utilizzando lo spazio come separatore.

Ora ti basta adattarlo al formato del tuo file

:ciauz:

davide84
06-04-2010, 22:55
Grazie davvero infinitamente
l'ho provato e funziona.
una domanda però (più a scopo educativo)...perchè hai inserito il carattere | nella cout del ciclo più interno?
grazie mille ancora

antotan
06-04-2010, 23:33
E' un mio mezzo-debug che faccio in fase di test con l'output su console.
Capita spesso di trovare stampe su console strane (ad esempio, non vedi nulla in console dopo una stampa) e ti chiedi "perchè? sarà una stringa vuota? sarà una stringa che contiene un solo carattere di spaziatura, tipo spazio o tab?".
Utilizzando il carattere '|' sia prima che dopo la stringa, sai con buona sicurezza cosa c'è al suo interno.

Per dirne una, prima, mentre facevo i test sul tuo programma (nel primo test non usavo ancora la parse, scrivevo solo con cout << "|" << num << "|" << endl;), in output ho letto qualcosa come:



.
.
|-23
5|
.
.


Mi sono subito accorto di essermi dimenticato del carattere di newline, che veniva incluso nella stringa dunque.
Se non avessi usato le pipe probabilmente non mi sarei accorto subito dell'errore, con tutte le conseguenze del caso (in particolare, non sarei riuscito a ottenere il numero "5", in quanto lo stringstream avrebbe incontrato '\n' all'interno della stringa e si sarebbe fermato, ritornandomi solo "-23")

:ciauz:

davide84
08-04-2010, 10:25
Scusate se riposto,
il programma che ha scritto antotan funziona, l'unica cosa è che trasforma anche gli spazi bianchi in numeri (li trasforma in 0 ) quindi c'è un po di confusione tra gli zeri presenti nella linea e quelli che provengono dalla trasformazione della funzione....
Sapreste dirmi come ovviare a questo problema???

Grazie ancora infinitamente

Loading