Unable to open second file after the first

I have a problem with the following code(Only the lower part,upper are just for explanatory purposes )
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
  struct info                 /*declarations/*
{
    char ID;
    char name;
    float marks;
}students;

struct data
{
    char subCode[10];
    char subName[25];
    int creDit;
    info students[30];
}subjects[10];

int x;

int main()
{
    ifstream extract;
    ifstream get;
    int counter;
    char fileName[25];
    char a[50];
    char sourceFile[20]; */

Declarations

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
39
40
41
42
43
44
45
46
47
48
49
cout<<"What file would you want to open?";   //Subjects.txt
    cin>>fileName;
    extract.open(fileName);
    if(!extract)
   {
      cout<<"Cannot find file."<<endl;
      exit (1);
   }

    else
    {
        extract>>x;
        for(counter=1;counter<=x;counter++)
        {
            extract>>subjects[counter].subCode;
            extract.ignore();             extract.getline(subjects[counter].subName,sizeof(subjects[counter].subName));
            extract>>subjects[counter].creDit;

 /*The upper part has nothing wrong with it, the problem is the following/*
            cout<<"Source file 1:";
            cin>>sourceFile;
            get.open(sourceFile);
            {
                if(!get)
                {
                    cout<<"Unable to open source text.";
                    exit(1);
                }


                else
                {
                    int y=1;
                    while(!get.eof())
                    {

                        get>>subjects[1].students[y].ID;
                        get>>(subjects[1].students[y].name);
                        get>>subjects[1].students[y].marks;
                        y++;
                    }
                }
            }

        }



    } */

For some reason, during the second prompt,nothing happens after I typed in the filename, the error message appears if I typed some gibberish into it.In the event a right text file is entered, the program stays blinking and stuck until I have to terminate it...


If anyone can point out the problem, I would be grateful. Thanks in advance.
Last edited on
cin>>fileName;
fileName is presumably a std::string? in that case use getline(std::cin, fileName) for reading input from console into strings
http://www.programmingincpp.com/standard-input-function.html
as regards reading objects from files you may wish to take a look here re some best practices:
https://isocpp.org/wiki/faq/serialization
Hello adventccy,

On lines 20 - 22 you are opening a file inside a for loop. How many times do you need to open the file? With out the proper file to test the program with it makes it hard to run and see what is happening.

The else statements at line 10 and 31 are not really needed.

The opening "{" on line 23 will work, but it is not necessary to define that block of code.

I am thinking that you might want to put a "}" on line 18 before you open the next file.

Hope that helps,

Andy

A few obvious problems:

1) Your comments are improperly terminated. C style comments are terminated with */, not /*.

2) Line 13,33: Your loop is going to cause an out of bounds reference. Arrays are addressed from 0, not 1. Your entries are subjects[0] to subjects[9]. Your loop is going to reference subjects[10] which is out of bounds, if the number of subjects in the file (x) is 10.

3) You have no check to prevent x exceeding the maximum subjects entries (10).

4) Line 34: Do not loop on (! stream.eof()) or (stream.good()). This does not work the way you expect. The eof bit is set true only after you make a read attempt on the file. This means after you read the last record of the file, eof is still false. Your attempt to read past the last record sets eof, but you're not checking it there. You proceed as if you had read a good record. This will result in reading an extra (bad) record. The correct way to deal with this is to put the >> (or getline) operation as the condition in the while statement.
1
2
3
  while (stream >> var) // or while (getline(stream,var))
  {  //  Good operation
  }

@gunnerfunner I was thinking cin works fine, as my input does not include any spaces.(Subjects.txt). Regarding the binary opening, I am not allowed to do so as the lecturer have not touched on that topic yet.

@HandyAndy The number of files needed to be opened depends on how many subjects,hence a file is read whenever the loop executes(explaining why it is in the loop).

@AbstractionAnon
The comments were typed in only on this site, but I see now that it is wrong.
2.I was starting the loop as counter=1,and the loop stops reading from the first text file after counter becomes 10, surely this would prevent that?
4. Apologies for being a noob, but I do not quite understand this. When I tried
1
2
3
4
5
6
7
8
9
10
11
12
13
 else
                {
                    int y=1;
                    while(get>>subjects[counter].students[y].ID)
                    {

                        get>>subjects[counter].students[y].ID;
                        get>>(subjects[counter].students[y].name);
                        get>>subjects[counter].students[y].marks;
                        y++;
                    }
                }

the code manages to read one file before stating that the second file is invalid.(despite correct input).Can you explain what the var of (stream>>var) is? [Number of records x=3]

Thank you guys for all the feedback!
Hello adventccy,

@gunnerfunner I was thinking cin works fine, as my input does not include any spaces.
That may work for now, but something may change in the future. And you never know what a user of the program might do. A future assignment might have you validate the file name that a user will input where you might have to deal with a space.

@HandyAndy The number of files needed to be opened depends on how many subjects
. That was not clear in the beginning, but now I understand. I did not that all you do in the program is open files, but you never close a file. Not sure what the limit is on open files so this could become a problem at some point.

I was starting the loop as counter=1,and the loop stops reading from the first text file after counter becomes 10, surely this would prevent that?
Yes and no. See point 2) of AbstractionAnon message. All I can add to that is when the subscript is at maximum and you are outside the bounds of the array you do not know what bit of memory you are messing with or what kind of problem it will cause with your code or something else. If you have forgotten this any version of the C languages along with several other programing languages are zero based. Starting your counter at 1 means that you are not using the very first element of the array which would make that wasted memory.

In the code of your last message line 7 should have been moved to line 5 not copied. As you have it you are reading into the same variable twice and that will through everything off. The code should be:
1
2
3
4
5
6
7
8
9
10
 else
                {
                    int y=1;
                    while(get>>subjects[counter].students[y].ID)
                    {
                        get>>(subjects[counter].students[y].name);
                        get>>subjects[counter].students[y].marks;
                        y++;
                    }
                }

this way when the end of file is reached the while loop will fail and you will not have an empty record at the end.

(stream>>var) stream refers to any kind of stream i.e., cin, cout, cerr, a file or any other way of receiving input/ The ">>var" tells the input where to go. I look at that as a shorthand rather than using proper names.

Hope that helps,

Andy
@Handy Andy
First of all, I appreciate the detailed response, thank you for taking the time to reply and I wish you a good day sir.

All I can add to that is when the subscript is at maximum and you are outside the bounds of the array you do not know what bit of memory you are messing with or what kind of problem it will cause with your code or something else.

To be honest, this part sounds quite mystical to my untrained ears, but I do see where you stand about using 0 as starting point. I will attempt to take note of it in future coding.


Regarding the code correction, yes, now it does make sense when you put it out like that, I seem to have forgotten that kind of structure does work.Despite that, the result stays the same with the code accepting only one filename before stating my second source file as false and terminating. I am wondering if its something about char buffer needed to be cleaned or some sorts?

Thank you again, kind sir for the reply.

Topic archived. No new replies allowed.