2010-02-02 11 views
14

C++ no es mi idioma preferido.Necesita ayuda básica para analizar una cadena en C++

Tengo un archivo que contiene lo siguiente:

e 225,370 35,75 

quiero separar e, 225, 370, 35 y 75 entre sí en un char y enteros, pero estoy teniendo problemas. Intenté hacer todo lo que encontré en línea y en mi libro de C++ y aún no está funcionando. Por favor ayuda.

Me sería más fácil hacer esto en Java.

+0

Cuéntanos lo que tiene. – bmargulies

+0

Gracias chicos. C++ es muy frustrante para mí a veces, ya que aprendí Java primero. –

+2

Aunque a veces puede ser frustrante, ayuda a tener acceso a algunas bibliotecas poderosas que no siempre están agrupadas directamente como lo están con Java. Imagine lo frustrante que sería Java si todo lo que tenía era el lenguaje central y no las bibliotecas. – joshperry

Respuesta

-1
#include <iostream> 
#include <fstream> 

using namespace std; 

int main() 
{ 
     ifstream f("a.txt"); // check for errors. 

     char ch,dummy; 
     int i1,i2,i3,i4; 

     f>>ch>>i1>>dummy>>i2>>i3>>dummy>>i4; 

     cout<<ch<<endl<<i1<<endl<<i2<<endl<<i3<<endl<<i4<<endl; 

     return 0; 
} 
2

Suponiendo que usted ha leído los datos en una cadenas ...

  1. strchr es como String.index.
  2. strtol es como Integer.parseInt()

¿Qué más se puede pedir?

+1

strtok sería más conveniente que strchr –

+0

'strtok' no es seguro para subprocesos, sin embargo, si eso es una preocupación. – greyfade

2
#include <fstream> 

/* ... */ 

ifstream file; 
file.open("yourfile.txt"); 
char c, dummy; 
int i[4]; 
file >> c >> i[0] >> dummy >> i[1] >> i[2] >> dummy >> i[3]; 
file.close(); 
+0

No estoy seguro del comportamiento, ya que no soy un programador de C++, pero me sorprendería si esto simplemente ignorase las comas en el archivo. ¿Lo hace? – danben

+0

@danben: puede, pero por defecto no lo hará. Incluso la mayoría de los programadores dedicados de C++ nunca tocan las partes de la biblioteca necesarias para hacer que ignore las comas (hay que crear una 'faceta ctype 'personalizada, crear una' locale' que contenga esa 'faceta', luego' imbue' la secuencia con ese 'locale'). –

+0

@danden, tienes razón. He actualizado mi solución. –

4

Si usted tiene control sobre el formato, que va a ser (un poco) más fácil de leer si se eliminan las comas, y sólo tiene como entrada

e 225 370 35 75

Con este formato, el código de Poita_ para leer los datos funcionará [editar: desde que actualizó su código para leer explícitamente y omitir las comas]. De lo contrario, tendrá que saltar de forma explícita sobre las comas:

char ingore1, ignore2; 
char ch; 
int i[4]; 

file >> ch >> i[0] >> ignore1 >> i[1] >> i[2] >> ignore2 >> i[3]; 

[Editar: si usted es paranoico o realmente necesita para verificar su entrada, en este punto se puede comprobar que ignore1 y ignore2 contienen comas.]

En la mayoría de los casos, sin embargo, los datos están probablemente relacionados, por lo que desea leer una línea completa en una sola estructura (o clase):

struct data { 
    char ch; 
    int i[4]; 

    std::istream &operator>>(std::istream &is, data &d) { 
     char ignore1, ignore2; 
     return is >> ch >> i[0] >> ignore1 >> i[1] >> i[2] >> ignore2 >> i[3]; 
    } 
}; 

una vez hecho esto, se puede leer una entero data objeto a la vez:

std::ifstream infile("my data file.txt"); 
data d; 

infile >> d; 

O, si usted tiene un archivo completo lleno de estos, puede leerlos todos en un vector:

std::vector<data> d; 

std::copy(std::istream_iterator<data>(infile), 
    std::istream_iterator<data>(), 
    std::back_inserter(d)); 
+0

Bueno. Usualmente estoy jugando con los métodos de búsqueda y substracción de cadenas. – StackedCrooked

3

Si desea utilizar el viejo tiempo de ejecución C moda

FILE * pf = fopen(filename, "r"); 
char e; 
int a, b, c, d; 
int ii = fscanf(pf, "%c %d,%d %d,%d", &e, &a, &b, &c, &d); 
if (ii < 5) 
    printf("problem in the input file"); 
fclose (pf); 

editar: comprobación de errores añadidos según el comentario de dreamlax

+1

Este es muy limpio. Sin embargo, asegúrese de comprobar que el valor de retorno de 'fscanf' es 5 para asegurarse de que todas las variables se hayan asignado correctamente. – dreamlax

+1

En estas situaciones, creo que fscanf es superior a las formas C++. – StackedCrooked

+0

¿Qué pasa con todo el disco por rebajas en esta respuesta? el puntaje actual es +4 -3, y no hay un solo descuento dispuesto a explicar por qué. –

2

Uso Boost Tokenizer para dividir la cadena. Estoy suponiendo que sólo el primer token es un char, por lo que el código de ejemplo sería algo así como:

#include <iostream> 
#include <boost/tokenizer.hpp> 
#include <string> 
#include <vector> 

using namespace std; 

... 

typedef boost::tokenizer<boost::char_separator<char> > tokenizer; 

string teststring("e 225,370 35,75"); 
boost::char_separator<char> separators(", "); 
tokenizer tokens(teststring, separators); 
vector<string> substrings; 
for (tokenizer::iterator iter = tokens.begin(); iter != tokens.end(); ++iter) 
{ 
    substrings.push_back(*iter); 
} 

y, voila, usted tiene todas las subcadenas en un vector ordenado.El char está en subcadenas [0] como std :: string, y los siguientes valores int se encuentran en las subcadenas [1] y las siguientes, también como std :: string. Tendrá que convertirlos a valores enteros. Para esto, sugiero que mires stringstream.

+0

Las bibliotecas de Boost se pueden encontrar aquí: http://www.boost.org/users/download/ – Demi

13

El C++ String Toolkit Library (StrTk) tiene la siguiente solución a su problema:

 
int main() 
{ 
    std::string data("e 225,370 35,75"); 
    char c1; 
    int i1,i2,i3,i4; 
    strtk::parse(data,", ",c1,i1,i2,i3,i4); 
    return 0; 
} 

Más ejemplos se pueden encontrar Here

Cuestiones relacionadas