Save the contents of a .txt in a char * in C ++

0

I have a program that works with a variable char * word="Text" but I want to get the value of the variable from a txt

file

Hello.txt

Hola mundo!

Adios.txt

Adios mundo!

I have the following code.

Archivo.open(archivo);
if(!Archivo.fail()){
    char* palabra;
    // Guardar el contenido del archivo en la variable
}
    
asked by akko 22.12.2016 в 04:39
source

2 answers

5

I would recommend that you use ifstream , then you can create a streambuf iterator of the file and initialize the string with that value:

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

int main(){

    std::ifstream t("file.txt");
    std::string str((std::istreambuf_iterator<char>(t)),
                 std::istreambuf_iterator<char>());
    const char *cstr = str.c_str();
    std::cout<<cstr<<std::endl;
    return 0;
}

Now you have the char* in cstr

    
answered by 22.12.2016 / 04:50
source
1

It is very easy to read data from a file using ifstream and std::getline , what is not simple (and does not make much sense) is to read in char * .

Having the text data in a pointer implies that the programmer must take charge of the management of said pointer, being this prone to errors.

Read a line in a pointer to character ... bad idea.

char *lee_de_archivo(const std::string nombre)
{
    std::ifstream archivo(nombre);
    std::string linea{};

    if (std::getline(archivo, linea))
    {
        char *resultado = new char[linea.size() + 1];
        std::copy(linea.begin(), linea.end(), resultado);
        resultado[linea.size()] = 0;
        return resultado;
    }

    return nullptr;
}

This function obtains the text of the file but the programmer must take charge of releasing the requested memory after its use:

char *palabra = lee_de_archivo("Hola.txt");
delete [] palabra;

Otherwise, there would be a memory leak , as in the following examples:

std::cout << lee_de_archivo("Hola.txt") << '\n';
std::string mensaje = std::string("Mensaje: ") + lee_de_archivo("Hola.txt");
std::copy(lee_de_archivo("Hola.txt"), lee_de_archivo("Hola.txt") + 10, ptr);

Especially the last line is ominous because in addition to memory leaks it would cause invalid access to memory since the return of lee_de_archivo returns different pointers on each call.

Why not access the internal pointer of a std::string ?

The proposal for eLRuLL access the internal pointer of a std::string object using the c_str and this can also be problematic, we can see it adapting the function lee_de_archivo :

char *lee_de_archivo(const std::string nombre)
{
    std::ifstream archivo(nombre);
    std::string linea{};

    if (std::getline(archivo, linea))
    {
        return linea.c_str();
    }

    return nullptr;
}

By the time we exit the function lee_de_archivo the linea object that the pointer to the string gives us ceases to exist, and consequently the pointed data is no longer valid.

The eLRuLL code does not have that problem since the life cycle of std::string and pointer the internal data match, but it is considered bad practice to break the encapsulation by saving pointers or references to internal data of an object.

  

I have to use char * and not string. - akko

It's a pointless limitation in modern C ++. The current trend is for low-end pointers to fall into disuse being replaced by smart pointers or other objects that handle the cycle. life of dynamic memory.

My advice is to forget that limitation and use std::string that gives less problems:

std::string lee_de_archivo(const std::string nombre)
{
    std::ifstream archivo(nombre);
    std::string linea{};
    std::getline(archivo, linea);

    return linea;
}
    
answered by 22.12.2016 в 10:57