Why cant I continue extracting values after first loop ?

Hello, I have to use "Data" function multiple times, but after first time using it, I cant extract any more values. Does it have something to do with it reopening ? And if text file is opened outside this function, it works well, but my text file must be in a function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
void Data(int y, int &Groups, string *&Name, int &People, int *&Grades)
{
    ifstream ifile("text.txt");
    if(y==0)
    {
        ifile >> Groups;
        Name=new string[Groups];
    }
        ifile >> Name[y] >> People;
        Grades=new int[People];
        for(int i=0;i<People;i++)
        {
            ifile >> Grades[i];
        }
    }
int main()
{
    int Groups, People, *Grades, g=0;
    string *Name;
    Data(g, Groups, Name, People, Grades);
    for(g=1;g<Groups;g++)
    {
        Data(g, Groups, Name, People, Grades);
    }
 return 0;
}
Last edited on
I need to see the text file to correctly identify the error. But the line that has the possibility of error is

ifile >> Groups;

This code is changing the value of Groups. As the variable Groups is passed by reference the value is also changed in the main. So that may be why the condition in the loop is failing.
If my ifstream is used before Data function, all is working fine. Groups value is changed only once, before the loop. Heres the text :
4
IF4/8 5 5 7 8 9 10
IF4/9 5 8 5 10 5 6
IF4/10 4 5 5 7 9
IF3/5 4 6 7 9 8
Last edited on
Don't you need a function prototype?
I need to prototype it only if I want to do it below main function. And I like doing everything above :P
Good to know!
I think you need to go back to the drawing board with your code.

The way you are getting your function "Data" to reopen the file each time you want to read a line (I'm guessing) is a mistake. Every time the file is reopened file reads start again from the first line, so all calls to the function Data after the first will try to read the value of Groups and get confused from there.

Adding output to your code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
#include <string>
#include <fstream>
using namespace std;

void Data(int y, int &Groups, string *&Name, int &People, int *&Grades)
{
    ifstream ifile("text.txt");
    if(y==0)
    {
        ifile >> Groups;
        cout << "Groups = " << Groups << "\n";
        Name=new string[Groups];
    }

    ifile >> Name[y] >> People;
    cout << "Name[" << y << "] = " << Name[y] << ", People = " << People << "\n";
    Grades=new int[People];
    for(int i=0;i<People;i++)
    {
        ifile >> Grades[i];
        cout << "Grades[" << i << "] = " << Grades[i] << "\n";
    }
}

int main()
{
    int Groups, People, *Grades, g=0;
    string *Name;
    cout << "* * * call Data with g = " << g << "\n";
    Data(g, Groups, Name, People, Grades);
    for(g=1;g<Groups;g++)
    {
        cout << "* * * call Data with g = " << g << "\n";
        Data(g, Groups, Name, People, Grades);
    }
    return 0;
}


I get:

* * * call Data with g = 0
Groups = 4
Name[0] = IF4/8, People = 5
Grades[0] = 5
Grades[1] = 7
Grades[2] = 8
Grades[3] = 9
Grades[4] = 10
* * * call Data with g = 1
Name[1] = 4, People = 0
* * * call Data with g = 2
Name[2] = 4, People = 0
* * * call Data with g = 3
Name[3] = 4, People = 0


You need to open the file once and read all lines.

Andy

Ps As it stands, the function Data would allocate buffers repeatedly against the Grades variables, to you are leaking memory.
Last edited on
You should also use the .eof() to check if it's the end of file
Thats the problem im having, I dont know how to stop text file from reopening, but still keeping it inside Data function. Im not yet sure if Im allowed to put ifstream outside it. And Zarman, I dont think I need to use it if I know how many lines there will be by "Groups" variable.
Have you tried .close()?
File always reopens due to that function, but I have tried that, didnt make a difference.
I'm no pro at c++ but I don't think you ever used the .open() so that you could use .close()
It should be
ifstream ifile;
ifile.open("yo textile.txt");
//do your stuff
if (ifile.eof())
ifile.close();

Also you are outputting data right? I don't even think you declared your file correct.
Should it be
ofstream file; ?
Last edited on
Its not a must to use .open() to open a text file and to be able to use .close(). Ive worked with text files before, everything was working fine.
I'm no pro at c++ but I don't think you ever used the .open() so that you could use .close()
It should be
ifstream ifile;
ifile.open("yo textile.txt");
//do your stuff
if (ifile.eof())
ifile.close();


The typical usage should be:
1
2
3
4
    std::ifstream in("filename.ext");
    while ( input extraction is successful )
        // do stuff.
    // file is closed automatically when the stream object goes out of scope. 


@OP: This is very poor design. In addition to the issue with the file being re-opened on every call, you've got a memory leak there too. Big surprise with the manual memory management.

I would suggest opening the file in main and feeding the function a reference-to-std::istream from which to extract data. That will fix your file problem, but won't fix the poor design or memory leaks. One thing at a time, I suppose. ;)

Last edited on
I know about "new" which caused me a memory leak, but I don't currently bother using "delete" for very small programs. Are there any other memory leaks I wouldn't know about ?
whenever you use a new, you need to use a delete. it's a good habit to get into. Btw u can use .good() to check if extraction is good
Last edited on
whenever you use a new, you need to use a delete. it's a good habit to get into.


Better yet, don't use new or delete at all :+)

First try to accomplish want you want with the STL containers and algorithms. std::vector looks good for this.

Some situations require a pointer, use a smart pointer std::unique_ptr
Arquon wrote:
I need to prototype it only if I want to do it below main function. And I like doing everything above :P


Prefer to use a function declaration (prototype) before main with function definitions after main. That way main is always at the top, one doesn't have to go looking for it :+)
Topic archived. No new replies allowed.