-2

I wanted to write a simple function that will take a file name as an argument and then return a constant char pointer that contains the characters in the text file.

#include <fstream>
#include <vector>
#include <iostream>
#include "text.h"

//function to get the size of a file
unsigned int Get_Size(const char * FileName){
    std::ifstream filesize(FileName, std::ios::in|std::ios::ate);

    unsigned int SIZE = filesize.tellg();

    filesize.close();

    return SIZE;
}

//Takes a file name then turns it into a c-style character array
const char * Get_Text(const char * FileName){

    //get size of the file
    unsigned int SIZE = Get_Size(FileName);


    std::ifstream file(FileName, std::ios::in);

    //I used a vector here so I could initialize it with a variable
    std::vector<char> text(SIZE);

    //here is where I loop through the file and get each character
    //and then put it into the corresponding spot in the vector
    std::streampos pos;
    for(int i = 0; i<SIZE; i++){
            pos=i;
        file.seekg(pos);
        text[i] = file.get();
    }

    //I manually added the terminating Null character
    text.push_back('\0');

    //I set the pointer equal to the address of the first element in the vector
    const char * finalText = &text[0];

    file.close();

    //this works    
    std::cout<<finalText<<std::endl;

    return finalText;
};

int main(){

    //this does not work
    std::cout<<Get_Text("Text.txt")<<std::endl;

    return 0;
}

When I print the the text with the *char pointer inside of my function it works. But when the pointer is passed outside of the function and I try to use it, the output is a white box for each character in the console. I have tried a bunch of different things and nothing gets it to work. I don't understand why it works inside of the function but it doesn't work outside.

4X3L
  • 33
  • 7
  • 2
    Why is this tagged `c`? Which version of the C standard library supplies `std::vector`? –  Dec 31 '13 at 21:56
  • 4
    Also, you are returning the data which points inside the vector, but the vector is destroyed when the function returns, so you get garbage (and undefined behavior). You'd be much better off reading the file into a dynamically allocated buffer (`new string[size]`) and returning that buffer. Even better, just use `std::strng`, `std::getline` and `std::string::operator+=`. –  Dec 31 '13 at 21:58

2 Answers2

0

You could do something fancy and use mmap() (Linux assumed) to map the file into virtual memory. That would postpone the point at which the file was actually read from disk and would save memory. It would also work on arbitrary length files.

bazza
  • 6,143
  • 12
  • 20
0

You're returning a pointer to the vector's underlying element array. However, since the vector is a local variable it goes out of scope when the function Get_Text returns. Automatic variables get destroyed when they go out of scope, whatever is associated with them also get thereby destroyed. Returning the vector itself or even better a string is a better option.

If you absolutely have to do this by returning a char*, then use std::unique_ptr<char[]> text(new char[SIZE]). When returning return text.get() AND in main you have the responsibility of calling delete [] ptr.

legends2k
  • 27,643
  • 22
  • 108
  • 196