c++ - sirve - ¿Cómo puedo usar delimitadores no predeterminados cuando leo un archivo de texto con std:: fstream?
ofstream c++ example (2)
Puedes usar
istream::getline(char* buffer, steamsize maxchars, char delim)
aunque esto solo soporta un solo delimitador. Para dividir aún más las líneas en sus diferentes delimitadores, puede usar
char* strtok(char* inString, const char* delims)
que lleva múltiples delimitadores. Cuando usas strtok solo necesitas pasarle la dirección de tu búfer la primera vez; después, solo pasa un nulo y te dará el siguiente token del último que te dio, devolviendo un puntero nulo cuando no haya Más.
EDITAR: Una implementación específica sería algo así como
char buffer[120]; //this size is dependent on what you expect the file to contain
while (!myIstream.eofbit) //I may have forgotten the exact syntax of the end bit
{
myIstream.getline(buffer, 120); //using default delimiter of /n
char* tokBuffer;
tokBuffer = strtok(buffer, "''- ");
while (tokBuffer != null) {
cout << "token is: " << tokBuffer << "/n";
tokBuffer = strtok(null, "''- "); //I don''t need to pass in the buffer again because it remembers the first time I called it
}
}
En mi código C ++, quiero leer un archivo de texto (* .txt) y registrar cada entrada. Más específicamente, quiero poder leer palabras individuales de un archivo, como "formato", "pila", "Jason", "europa", etc.
Elegí usar fstream
para realizar esta tarea, y no sé cómo establecer su delimitador a los que quiero usar (espacio, /n
, así como guiones e incluso apóstrofes como en "Mcdonal''s"). Pensé que espacio y /n
son los delimitadores predeterminados, pero los guiones no lo son, pero quiero tratarlos como delimitadores para que al analizar el archivo, aparezcan las palabras en "bla bla xxx animal - gato" como simplemente "bla" , "bla", "xxx", "animal", "gato".
Es decir, quiero poder obtener dos cadenas de "desbordamiento de pila", "eres", etc., y aún poder mantener /n
espacio como delimitadores al mismo tiempo.
Un istream trata el "espacio en blanco" como delimitadores. Utiliza una configuración regional para decirle qué caracteres son espacios en blanco. Una configuración regional, a su vez, incluye una facet
ctype que clasifica los tipos de caracteres. Tal faceta podría verse algo como esto:
#include <locale>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <vector>
#include <sstream>
class my_ctype : public
std::ctype<char>
{
mask my_table[table_size];
public:
my_ctype(size_t refs = 0)
: std::ctype<char>(&my_table[0], false, refs)
{
std::copy_n(classic_table(), table_size, my_table);
my_table[''-''] = (mask)space;
my_table[''/'''] = (mask)space;
}
};
Y un pequeño programa de prueba para demostrar que funciona:
int main() {
std::istringstream input("This is some input from McDonald''s and Burger-King.");
std::locale x(std::locale::classic(), new my_ctype);
input.imbue(x);
std::copy(std::istream_iterator<std::string>(input),
std::istream_iterator<std::string>(),
std::ostream_iterator<std::string>(std::cout, "/n"));
return 0;
}
Resultado:
This
is
some
input
from
McDonald
s
and
Burger
King.
istream_iterator<string>
usa >>
para leer las cadenas individuales de la secuencia, por lo que si las usa directamente, debería obtener los mismos resultados. Las partes que debe incluir son la creación de la configuración regional y el uso de imbue
para que la transmisión use esa configuración regional.