es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Pregunta de C++ sobre cómo ifstream lee líneas y columnas.

Estaba leyendo algunos de mis viejos códigos y me di cuenta de que no sé exactamente cómo funciona ifstream. El siguiente código simplemente debería leer un archivo, guardar su contenido en un objeto y crear otro archivo con exactamente los mismos datos, escritos de la siguiente manera:

#include <iostream>
#include <fstream>

using namespace std;

class grade {
  public:
    float grade1;
    float grade2;
    float grade3;
};

void read_file(grade data[]){
    ifstream myfile("data.txt");
    int i=0;
    while(myfile >> data[i].grade1){
            myfile >> data[i].grade2 >> data[i].grade3;
            i=i+1; }
    myfile.close();
    myfile.clear();
}

void write_file(grade data[]){
    ofstream myfile("data_out.txt");
    for(int i=0; i<3; i++){
        myfile << data[i].grade1 << "\t" << data[i].grade2 << "\t" << data[i].grade3 << endl;
    }
    myfile.close();
    myfile.clear();
}


int main()
{
    grade data[3];
    read_file(data);
    write_file(data);

    return 0;
}

Con “data.txt” teniendo:

23.5    10.1    11.6
14.3    8.2     9.3
6.5     6.7     5.3

El código funciona bien, pero no entiendo cómo ifstream “sabe” en qué línea o columna debería estar en un momento dado, ya que la variable i no se utiliza para controlar myfile. Estoy suponiendo que ifstream tiene dos variables internas de control, una para la línea y otra para la columna, de modo que cada vez que se identifica un comando myfile >> xxx, se incrementa la variable de columna, y cada vez que se repite el bucle se incrementa la variable de línea. ¿Es algo así? No controlar explícitamente en qué línea o columna se encuentra el código en un momento dado es bastante confuso para mí.

Digamos, por ejemplo, que en este ejemplo me gustaría leer solo los datos de la segunda línea y columna. ¿Podría acceder directamente a ellos utilizando alguna expresión explícita como ‘myfile[1][1] >> xxx’? Supongo que podría usar getline, pero como se usa para cadenas, realmente no lo sé.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    La clase ifstream se utiliza para leer datos de entrada desde archivos. Cuando se utiliza el operador >> con un objeto ifstream, se lee el próximo valor de entrada disponible en el archivo, que puede ser un número, una cadena o un carácter, dependiendo del tipo de dato de la variable en la que se está leyendo.

    En el código dado, la función read_file lee datos del archivo “data.txt” en un array de objetos grade. El bucle while lee los datos del archivo línea por línea, y para cada línea, lee tres valores de punto flotante (calificaciones) en el objeto grade en el índice actual i. Dado que el comando myfile >> xxx lee datos secuencialmente desde el archivo, el objeto ifstream avanza automáticamente a la siguiente línea o columna a medida que lee datos. La variable i se utiliza para realizar un seguimiento del índice actual en el array data, que se incrementa después de cada línea de datos leída.

    Para leer solo una línea o columna específica del archivo, puedes modificar el bucle en consecuencia. Por ejemplo, para leer la segunda línea de datos, puedes agregar una variable de contador line_count al bucle y leer datos solo cuando line_count sea igual a 1:

    void read_file(grade data[]){
        ifstream myfile("data.txt");
        int i=0, line_count=0;
        while(line_count < 2 && myfile >> data[i].grade1){ // se lee hasta que se alcance la segunda línea
            myfile >> data[i].grade2 >> data[i].grade3;
            line_count++;
            i++;
        }
        myfile.close();
        myfile.clear();
    }
    

    De manera similar, para leer solo la segunda columna, puedes modificar el bucle para omitir la primera calificación en cada línea y leer solo la segunda y tercera calificaciones:

    void read_file(grade data[]){
        ifstream myfile("data.txt");
        int i=0;
        while(myfile >> data[i].grade1){ // se lee hasta que se alcance el final del archivo
            myfile.ignore(std::numeric_limits<std::streamsize>::max(), '\t'); // se omite la primera calificación
            myfile >> data[i].grade2 >> data[i].grade3;
            i++;
        }
        myfile.close();
        myfile.clear();
    }
    

    No se puede acceder a elementos específicos de un objeto ifstream como si fuera un array (myfile[1][1]), ya que no tiene una estructura bidimensional. Si necesitas acceder a líneas o columnas específicas de datos de un archivo, puedes utilizar la función getline para leer una línea completa de texto y luego analizarla utilizando funciones de manipulación de cadenas o bibliotecas externas como Boost.

Comments are closed.