2008-09-22 54 views

Respuesta

3

El siguiente código C++ leerá un archivo completo ...

 

#include <iostream> 
#include <fstream> 
#include <string> 
using namespace std; 

int main() 
{ 
    string line; 
    ifstream myfile ("foo.txt"); 

    if (myfile.is_open()){ 

    while (!myfile.eof()){ 
     getline (myfile,line); 
     cout << line << endl; 
    } 
    myfile.close(); 
    } 
    return 0; 
} 
 

publicar su código y yo le puede dar una ayuda más específica a su problema ...

+1

Usar _good() _ es mejor que _eof() _. Si se requiere la lectura de char por char _if (mi_archivo >> ch) _ es la correcta, y la comprobación de eof no es correcta. Consulte: http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.5 – legends2k

22

Para el cifrado, que está mejor abrir su archivo en modo binario. Usar algo como esto para poner los bytes de un archivo en un vector:

std::ifstream ifs("foobar.txt", std::ios::binary); 

ifs.seekg(0, std::ios::end); 
std::ifstream::pos_type filesize = ifs.tellg(); 
ifs.seekg(0, std::ios::beg); 

std::vector<char> bytes(filesize); 

ifs.read(&bytes[0], filesize); 

Editar: arreglado un error sutil como por los comentarios.

+1

Lo siento, esto tiene un error sutil. Se llama a la sobrecarga de 'seekg' que toma solo un desplazamiento y termina leyendo solo dos bytes (el valor de 'std :: ios: end). Debería llamar a seekg (0, std :: ios :: end) y seekg (0, std :: ios :: beg). –

+1

Buena captura. Debería ser correcto ahora – luke

13

no he probado esto, pero creo que es necesario borrar el "saltar espacios en blanco" bandera:

inFile.unsetf(ios_base::skipws); 

utilizo la siguiente referencia para los flujos de C++: IOstream Library

+1

sí, definitivamente necesita agregar esto si desea leer datos binarios, ya que está activado de manera predeterminada. –

+0

Yo también necesitaba esto _en adición_ a ios :: bandera binaria – jtooker

1

Para el cifrado, probablemente deberías usar read(). Los algoritmos de cifrado generalmente tratan con bloques de tamaño fijo. Ah, y para abrir en modo binario (sin traducción frmo \ n \ r a \ n), pase ios_base :: binary como el segundo parámetro a constructor o llamada abierta().

2

Puede llamar al int fstream::get(), que leerá un solo carácter de la transmisión. También puede usar istream& fstream::read(char*, streamsize), que realiza la misma operación que get(), un poco más de varios caracteres. Los enlaces dados incluyen ejemplos de uso de cada método.

También recomiendo leer y escribir en modo binario. Esto permite que los caracteres de control ASCII se lean y escriban correctamente en los archivos. De lo contrario, un par de operaciones de cifrado/descifrado puede dar como resultado archivos no idénticos. Para hacer esto, abra el filestream con el indicador ios::binary. Con un archivo binario, desea utilizar el método read().

46

Probablemente la mejor manera es leer el contenido de todo el archivo en una cadena, que se puede hacer muy fácilmente usando rdbuf() método de ifstream:

std::ifstream in("myfile"); 

std::stringstream buffer; 
buffer << in.rdbuf(); 

std::string contents(buffer.str()); 

A continuación, puede utilizar la manipulación normal de cadena ahora que tienes todo desde el archivo.

Mientras Tomek estaba preguntando por la lectura de un archivo de texto, el mismo enfoque funciona para leer datos binarios, aunque los std :: ios :: indicador binario debe ser proporcionada al crear el flujo de archivo de entrada.

+0

¿Cómo puedo volver a votar esto más? Esto me habría ahorrado HORAS de codificación ... Te sorprendería la cantidad de consejos * malos * (incluso para usuarios experimentados de la pila) que existen en este sitio. –

3

Una gran parte de la ventaja de la capa istream es proporcionar formato básico y análisis para tipos simples ro y de una secuencia. Para los fines que describe, nada de esto es realmente importante y solo le interesa el archivo como una secuencia de bytes.

Para estos fines, es mejor utilizar la interfaz basic_streambuf proporcionada por un archivo bbu. El comportamiento 'skip whitespace' es parte de la funcionalidad de la interfaz istream que simplemente no necesita.

filebuf subyace un ifstream, pero es perfectamente válido para usarlo directamente.

std::filebuf myfile; 
myfile.open("myfile.dat", std::ios_base::in | std::ios_base::binary); 

// gets next char, then moves 'get' pointer to next char in the file 
int ch = myfile.sbumpc(); 

// get (up to) the next n chars from the stream 
std::streamsize getcount = myfile.sgetn(char_array, n); 

también echar un vistazo a las funciones snextc (mueve el 'conseguir' puntero hacia adelante y luego devuelve el carbón actual), sgetc (obtiene el carbón actual, pero no se mueve el puntero 'get') y sungetc (respalda el puntero 'get' en una posición si es posible).

Cuando no necesita ninguno de los operadores de inserción y extracción proporcionados por una clase istream y solo necesita una interfaz de bytes básica, a menudo la interfaz streambuf (filebuf, stringbuf) es más apropiada que istream (ifstream, istringstream)

-5

Como Charles Bailey señaló correctamente, no necesita los servicios de Fstream solo para leer bytes. Así que olvida esta estupidez iostream, usa fopen/fread y termina con eso. C stdio es parte de C++, ya sabes;)

+2

Pero al usar transmisiones, la transmisión no necesita ser solo un archivo. Podría ser una cadena, un socket o cualquier otra cosa que te guste. streambuf_iterator <> –

+0

Estoy de acuerdo, pero OP indicó específicamente que el objetivo era "leer un archivo txt". – Constantin

0

simple

#include <fstream> 
#include <iomanip> 


ifstream ifs ("file"); 
ifs >> noskipws 

eso es todo.

+0

¿te refieres a "ifs >> noskipws >> some_string"? – Vanuan

3
std::ifstream ifs("filename.txt"); 

std::string str((std::istreambuf_iterator<char>(ifs)), 
       std::istreambuf_iterator<char>() 
       ); 
0
ifstream ifile(path); 
std::string contents((std::istreambuf_iterator<char>(ifile)), std::istreambuf_iterator<char>()); 
ifile.close(); 
2

Otra manera mejor es usar istreambuf_iterator, y el código de ejemplo es la siguiente:

ifstream inputFile("test.data"); 

string fileData(istreambuf_iterator<char>(inputFile), istreambuf_iterator<char>()); 
0

También me parece que el método de objeto ifstream get() también puede leer todos los caracteres de el archivo, que no requiere unset std::ios_base::skipws. Presupuesto de C++ Primer:

Varias de las operaciones sin formato lidiar con una corriente de un byte a la vez. Estas operaciones, que se describen en la Tabla 17.19, leen en lugar de ignorar espacios en blanco.

Estas operaciones son la lista de la siguiente manera: is.get(), os.put(), is.putback(), is.unget() y is.peek().

A continuación se muestra un código mínimo de trabajo

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

int main(){ 
    std::ifstream in_file("input.txt"); 

    char s; 

    if (in_file.is_open()){ 
     int count = 0; 
     while (in_file.get(s)){ 

      std::cout << count << ": "<< (int)s <<'\n'; 
      count++; 
     } 

    } 
    else{ 
     std::cout << "Unable to open input.txt.\n"; 
    } 
    in_file.close(); 

    return 0; 
} 

El contenido del archivo de entrada (cat input.txt) es

ab cd 
ef gh 

La salida del programa es:

0: 97 
1: 98 
2: 32 
3: 99 
4: 100 
5: 10 
6: 101 
7: 102 
8: 32 
9: 103 
10: 104 
11: 32 
12: 10 

10 y 32 son representaciones decimales de carácter de nueva línea y espacio. Obviamente, todos los personajes han sido leídos.

Cuestiones relacionadas