Usted ya ha dicho su std::getline
, pero que no mencionar un detalle que probablemente encontrará útil: cuando se llama getline
, también puede pasar un parámetro contarla qué personaje tratar como el final de la entrada. Para leer su número, puede utilizar:
std::string number;
std::string name;
std::getline(infile, number, ':');
std::getline(infile, name);
Esto pondrá los datos hasta el ':' en number
, desechar la ':', y leer el resto de la línea en name
.
Si desea utilizar >>
para leer los datos, puede hacerlo también, pero es un poco más difícil y se adentra en un área de la biblioteca estándar que la mayoría de las personas nunca toca. Una secuencia tiene asociado locale
que se utiliza para formatear números y (lo que es más importante) determinar qué constituye "espacio en blanco". Puede definir su propia configuración regional para definir ":" como espacio en blanco y el espacio ("") como no como espacio en blanco. Indique a la transmisión que use esa configuración regional y le permitirá leer sus datos directamente.
#include <locale>
#include <vector>
struct colonsep: std::ctype<char> {
colonsep(): std::ctype<char>(get_table()) {}
static std::ctype_base::mask const* get_table() {
static std::vector<std::ctype_base::mask>
rc(std::ctype<char>::table_size,std::ctype_base::mask());
rc[':'] = std::ctype_base::space;
rc['\n'] = std::ctype_base::space;
return &rc[0];
}
};
Ahora usarlo, que "imbuir" la corriente con una configuración regional:
#include <fstream>
#include <iterator>
#include <algorithm>
#include <iostream>
typedef std::pair<int, std::string> data;
namespace std {
std::istream &operator>>(std::istream &is, data &d) {
return is >> d.first >> d.second;
}
std::ostream &operator<<(std::ostream &os, data const &d) {
return os << d.first << ":" << d.second;
}
}
int main() {
std::ifstream infile("testfile.txt");
infile.imbue(std::locale(std::locale(), new colonsep));
std::vector<data> d;
std::copy(std::istream_iterator<data>(infile),
std::istream_iterator<data>(),
std::back_inserter(d));
// just for fun, sort the data to show we can manipulate it:
std::sort(d.begin(), d.end());
std::copy(d.begin(), d.end(), std::ostream_iterator<data>(std::cout, "\n"));
return 0;
}
Ahora sabes por qué esa parte de la biblioteca está tan descuidado. En teoría, hacer que la biblioteca estándar haga su trabajo es excelente, pero de hecho, la mayoría de las veces es más fácil hacer este tipo de trabajo por su cuenta.
corrientes en C++ son una de las cosas que odio de C++. – AraK
Como soy nuevo en C++, esperaba que las transmisiones fueran una de esas cosas que finalmente conducen a una epifanía de "oooooh que es inteligente", pero después de su comentario, estoy empezando a pensar que eso nunca sucederá. :( – dreamlax