0

I am new to C++ and lately I was having trouble reading a file. That problem is now fixed. What I'd like to do now is to use the file I read to create an array, but all this has to be done in a function, this means the function has to return an array so I can use it on the main. The process I follow:

  1. Read File
  2. Create Array
  3. Return Array Adress.
  4. In the main: Use function to put an array in a variable. My code so far:

    #include <iostream>
    #include <fstream>
    #include <cstdlib>
    #include <string>
    using namespace std;
    void imprimeArreglo (int[],int);
    int* leeArreglo(string&);
    
    int i;
    void imprimeArreglo(int a[])
    {
        cout << a[i] << endl;
    }
    int* leeArreglo(string nombre)
    {
        ifstream arch(nombre.c_str());
        string tamStr;
        int tam;
    
        if(arch.is_open())
        {
             getline(arch,tamStr); 
             tam=atoi(tamStr.c_str());
             int arr[tam];
             for(int i=0;i<tam;i++)
             {
                 arch >> arr[i];
             }
             int *ret=arr;
             return ret;
         }
         return 0;
    }
    int main()
    {
         string nombre = "arr.txt";  
         int *a= leeArreglo(nombre.c_str());
         imprimeArreglo(a);
         return 0;
    }
    

    What my arr.txt file looks like:

    10
    9 8 22 33 76 0 23 100 -8 45
    

I think this should print (with imprimeArreglo(a)): 9 8 22 33 76 0 23 100 -8 45 But the only thing I get in the console is: 2292592 Which I think it's a memory adress??? What am I doing wrong? Is there a better way to do it without using vectors?
Thanks in advance!

5
  • 2
    a) int arr[tam]; variable length arrays are a non-standard extension. b) Why would you not want to use vectors? Commented Feb 9, 2014 at 17:59
  • a) Is that going to solve my problem? b) Because I really want to make it happen with arrays. Can you read a file and put it into a vector?? Commented Feb 9, 2014 at 18:01
  • a) Indenting your code properly and getting of all these bloody pointers would be a good start. Commented Feb 9, 2014 at 18:02
  • 'Can you read a file and put it into a vector?' Yes! Use a back inserter from the stream. Commented Feb 9, 2014 at 18:03
  • typedef std::istream_iterator<int> istr_it; std::copy(istr_it(arch), is_it(), std::back_inserter(arr)); Vector only takes two lines of code compared to your 20ish. And it's faster, and it works. Commented Feb 9, 2014 at 18:06

3 Answers 3

3

This would be a simple way of doing it:

#include <iterator>
#include <vector>
#include <fstream>

std::vector<int> fileContents(const std::string& filename)
{
  ifstream inputFile(filename.c_ctr());
  std::istream_iterator<int> end;
  std::istream_iterator<int> it(inputFile);
  return std::vector<int>(it, end);
}

This reads all the numbers into a vector. You may have to modify it to ignore the first 10, for example by calling std::advance(it, 1); just after initializing it.

Sign up to request clarification or add additional context in comments.

9 Comments

I would upvote but "Is there a better way to do it without using vectors?"
@0x499602D2 "From the comments: Can you read a file and put it into a vector?? – David Merinos"
@0x499602D2 I also have the impression, the OP's looking for a real world proof solution, and not to solve a stupid restricted programming learning task. At least he'll have an array accessible from the vector.
@MooingDuck I guess it is advance(1), I think there is a number 10 that is the number of elements to read in the next line.
@0x499602D2: Even given those comments, I still consider this to be an excellent and probably the best answer. This answers the question the OP didn't even know he had.
|
2

You are returning a reference to a local variable. When your function go out of scope the array arr is freed and therefore the address return is just garbage. If you want to return an address that lives after the function is called, do something like:

int *arr = new int[tam];

Then the address will be valid after the function is called but in terms of design this is not great as you leave the responsibility to free the array on the caller. I would personally wrap all of this in a class and and have the array member of it.

Comments

0

Ok after some research and consulting, I got the answer! Thank you everyone for helping me :). This is the code that made the things happens (USING ARRAYS!!)

int* readArray(string name)
{
    ifstream fil(name.c_str());
    string sizeStr;
    int size;

    if(fil.is_open())
    {
        getline(fil,sizeStr); 
        size=atoi(sizeStr.c_str());
        int* arr = new int[size+1];
        for(int i=1;i<size+1;i++)
        {
            fil >> arr[i];
        }
        //We stash the size in the first position ;)
        arr[0]=size;
        //cout << arr[0]<< "\n";
        //We point to the position of the array + 1. (The 0 pos is used for the size)
        int *ret=arr+1;
        return ret;
        delete[] ret;
    }
    else cout << "ERROR...!\n";
    return 0;
}

As you can see my function returns a pointer. And I delete it. (Still need to see if that delete[] is well positioned tho.) Also since what I return is a pointer I can't really know what the size of my array is using sizeof(arr)/sizeof(int). So what I did is to save it into a position of the array, that way I can call it whenever I want by using array[-1].

Thank you all again!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.