Primero, haga un ifstream
:
#include <fstream>
std::ifstream infile("thefile.txt");
Los dos métodos estándar son:
Suponga que cada línea consta de dos números y lea token por token:
int a, b;
while (infile >> a >> b)
{
// process pair (a,b)
}
Análisis basado en líneas, utilizando secuencias de cadena:
#include <sstream>
#include <string>
std::string line;
while (std::getline(infile, line))
{
std::istringstream iss(line);
int a, b;
if (!(iss >> a >> b)) { break; } // error
// process pair (a,b)
}
No debe mezclar (1) y (2), ya que el análisis basado en tokens no engulle nuevas líneas, por lo que puede terminar con líneas vacías espurias si lo usa getline()
después de que la extracción basada en tokens lo lleve al final de un línea ya.
int a, b; char c; while ((infile >> a >> c >> b) && (c == ','))
while(getline(f, line)) { }
construcción y con respecto al manejo de errores, eche un vistazo a este (mi) artículo: gehrcke.de/2011/06/… (Creo que no necesito tener mala conciencia publicando esto aquí, incluso un poco antes fecha esta respuesta).Use
ifstream
para leer datos de un archivo:Si realmente necesita leer línea por línea, haga esto:
Pero probablemente solo necesite extraer pares de coordenadas:
Actualizar:
En su código que utiliza
ofstream myfile;
, sin embargo, significao
in . Si desea leer desde el archivo (entrada) use . Si quiere leer y escribir, use .ofstream
output
ifstream
fstream
fuente
getline
está a lastring
vista , así que no olvides el#include <string>
La lectura de un archivo línea por línea en C ++ se puede hacer de diferentes maneras.
[Rápido] Loop con std :: getline ()
El enfoque más simple es abrir un std :: ifstream y un bucle usando llamadas std :: getline (). El código es limpio y fácil de entender.
[Rápido] Utilice el archivo_description_source de Boost
Otra posibilidad es usar la biblioteca Boost, pero el código se vuelve un poco más detallado. El rendimiento es bastante similar al código anterior (bucle con std :: getline ()).
[Más rápido] Usar código C
Si el rendimiento es crítico para su software, puede considerar usar el lenguaje C. Este código puede ser 4-5 veces más rápido que las versiones de C ++ anteriores, consulte el punto de referencia a continuación
Punto de referencia: ¿cuál es más rápido?
He hecho algunos puntos de referencia de rendimiento con el código anterior y los resultados son interesantes. He probado el código con archivos ASCII que contienen 100,000 líneas, 1,000,000 líneas y 10,000,000 líneas de texto. Cada línea de texto contiene 10 palabras en promedio. El programa se compila con
-O3
optimización y su salida se reenvía/dev/null
para eliminar la variable de tiempo de registro de la medición. Por último, pero no menos importante, cada fragmento de código registra cada línea con laprintf()
función para mantener la coherencia.Los resultados muestran el tiempo (en ms) que tomó cada fragmento de código para leer los archivos.
La diferencia de rendimiento entre los dos enfoques de C ++ es mínima y no debería hacer ninguna diferencia en la práctica. El rendimiento del código C es lo que hace que el punto de referencia sea impresionante y puede cambiar el juego en términos de velocidad.
fuente
std::cout
frenteprintf
.printf()
función en todos los casos por coherencia. También he intentado usarstd::cout
en todos los casos y esto no hizo absolutamente ninguna diferencia. Como acabo de describir en el texto, la salida del programa pasa a/dev/null
modo que no se mide el tiempo para imprimir las líneas.cstdio
. Deberías haber intentado con la configuraciónstd::ios_base::sync_with_stdio(false)
. Supongo que habría obtenido un rendimiento mucho mejor (aunque no está garantizado ya que está definido por la implementación cuando se desactiva la sincronización).Dado que sus coordenadas pertenecen juntas como pares, ¿por qué no escribir una estructura para ellas?
Luego puede escribir un operador de extracción sobrecargado para istreams:
Y luego puedes leer un archivo de coordenadas directamente en un vector como este:
fuente
int
tokens de la transmisiónoperator>>
? ¿Cómo se puede hacer que funcione con un analizador de retroceso (es decir, cuandooperator>>
falla, retroceda el flujo a la posición anterior y devuelva falso o algo así)?int
tokens, lais
secuencia se evaluaráfalse
y el ciclo de lectura terminará en ese punto. Puede detectar estooperator>>
al verificar el valor de retorno de las lecturas individuales. Si desea revertir la transmisión, debe llamaris.clear()
.operator>>
que es más correcto deciris >> std::ws >> coordinates.x >> std::ws >> coordinates.y >> std::ws;
ya que de lo contrario se está asumiendo que su flujo de entrada está en el modo de omisión de espacios en blanco.Ampliando la respuesta aceptada, si la entrada es:
aún podrá aplicar la misma lógica, como esta:
fuente
Aunque no es necesario cerrar el archivo manualmente, es una buena idea hacerlo si el alcance de la variable del archivo es mayor:
fuente
Esta respuesta es para Visual Studio 2017 y si desea leer del archivo de texto qué ubicación es relativa a su aplicación de consola compilada.
primero coloque su archivo de texto (test.txt en este caso) en su carpeta de soluciones. Después de compilar, mantenga el archivo de texto en la misma carpeta con applicationName.exe
C: \ Users \ "nombre de usuario" \ source \ repos \ "solutionName" \ "solutionName"
fuente
Esta es una solución general para cargar datos en un programa C ++ y utiliza la función readline. Esto podría modificarse para los archivos CSV, pero el delimitador es un espacio aquí.
fuente