This code is confusing for information storage

I have a code that is used to store information in a .txt file and when the code runs it is suppose to grab the info from that .txt file and display it but every time I run the code it just ends and idk why.

Code:
#include<fstream>
#include<string>
#include<iostream>
using namespace std;

int main()
{
string str[20]; //string array
int i = 0, j = 0, last; // counter variables
ifstream myFile("Records.txt"); // input file object
if (! myFile) // always check this
{
cout << "Unable to open input file" << endl;

return -1;
}

while (! myFile.eof()) //loop through data
{
if ((i + 1) % 4 ==0) getline(myFile, str[i++]);
else getline(myFile, str[i++], '\t');

}
last = i;

i = 0;

while (i < last)
{

cout << "\nRecord Number:\t" << ++j << endl;
cout << "Forename:\t" << str[i++] << endl;
cout << "Surname:\t" << str[i++] << endl;
cout << "Department:\t" << str[i++] << endl;
cout << "Tel.No.:\t" << str[i++] << endl;
}
myFile.close();
return 0;
}
Last edited on
@Daisuke,
PLEASE USE CODE TAGS (the <> formatting button to the right), when posting code!

Along with the proper indenting, it makes it easier to read your code, and thus also easier to respond to your post.

Tutorials on how to use code tags:

http://www.cplusplus.com/articles/jEywvCM9/
http://www.cplusplus.com/articles/z13hAqkS/


I've found the second link to be the most help.

Hint: You can hit "edit post", highlight your code and then press the <> formatting button.
Note: This will not automatically indent your code! That part is up to you!

I've found it's easiest to copy and paste pre-indented code directly from the IDE, that way it is already properly formatted.

You can use the "preview" button at the bottom to see how it looks.

Using Code Tags, @Handy Andy, from cplusplus.com

I will look over your code and see what I can do.
Thanks!
max
Last edited on
Ok, here's your code, edited for readability:
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
#include <fstream>
#include <string>
#include <iostream>

using namespace std;

int main ()
{
	string str[20]; //string array
	
	int i = 0, j = 0, last; // counter variables
	
	ifstream myFile ("Records.txt"); // input file object
	
	if (!myFile) // always check this
	{
		cout << "Unable to open input file" << endl;
		return -1;
	}

	while (!myFile.eof()) //loop through data
	{
		if ((i + 1) % 4 ==0) 
			getline(myFile, str[i++]);
		else 
			getline(myFile, str[i++], '\t');
	}
	
	last = i;

	i = 0;

	while (i < last)
	{
		cout << "\nRecord Number:\t" << ++j << endl;
		cout << "Forename:\t" << str[i++] << endl;
		cout << "Surname:\t" << str[i++] << endl;
		cout << "Department:\t" << str[i++] << endl;
		cout << "Tel.No.:\t" << str[i++] << endl;
	}
	
	myFile.close();
	
	return 0;
}

Perhaps you could also post your text file, so I know what kind of formatting you're using, because without that, I can't really test your code.
Last edited on
This is what the .TXT looks like
txt:
John Smith School 1282828
Owen Smith School None
Brittani Smith School 921421351
Nick Smith School I dont know

And the code still just ends and doesn't do anything
Last edited on
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
#include<fstream>
#include<string>
#include<iostream>

using namespace std;

int main()
{
    string fName[20], sName[20], deptName[20], teleNo[20];

    int i = 0, LAST = 0;
    ifstream myFile("Records.txt");

    if (! myFile)
    {
        cout << "Unable to open input file" << endl;
        return -1;
    }

    while ( myFile >> fName[i] >> sName[i] >> deptName[i])
    {

        myFile.ignore();
        getline(myFile, teleNo[i]);

        i++;
    }
    LAST = i;

    i = 0;
    while (i < LAST)
    {
        cout << "Record Number:\t" << i << endl;
        cout << "Forename:\t" << fName[i] << endl;
        cout << "Surname:\t" << sName[i] << endl;
        cout << "Department:\t" << deptName[i] << endl;
        cout << "Tel.No.:\t" << teleNo[i] << endl;
        i++;
    }

    myFile.close();
    return 0;
}


Record Number:	0
Forename:	John
Surname:	Smith
Department:	School
Tel.No.:	1282828
Record Number:	1
Forename:	Owen
Surname:	Smith
Department:	School
Tel.No.:	None
Record Number:	2
Forename:	Brittani
Surname:	Smith
Department:	School
Tel.No.:	921421351
Record Number:	3
Forename:	Nick
Surname:	Smith
Department:	School
Tel.No.:	I dont know
Program ended with exit code: 0
Still didnt do anything I still get it saying
(Program ended with exit code: -1) Idk What im doing wrong
Would I remove this part:
{
cout << "Unable to open input file" << endl;
return -1;
}
Last edited on
If it was unable to open the file then it's probably because your data file can't be found. There are numerous solutions:
1. Put the data file together in the same directory/folder as the .exe or app file.
2. Adjust your system/ IDE path configuration
3. Make the filename the complete path.
im still very new to this can you show me what That would look like?
1 and 3 aren't easy?
Either cut and paste, or alternatively find out and use the full path file name eg "Daisuke/some_directories/Records.txt" instead of just "Records.txt"
Hello Daisuke,

You need to mention what IDE and operating system you are using and how you are running the program. Is it from the IDE or the command line? It makes a difference.

It helps to do this every time.

Also prefer to user the new line, (\n) over the function "endl". These days the (\n) does the same as the "endl".

while (! myFile.eof()) //loop through data does not work the way that you are thinking. It will loop 1 extra time before it detects that "eof" has been reached.

salem c once wrote:

eof() is a state (the result of a past event), not a prediction (of a future).
If you have a 10 line file, then calling getline 10 times does NOT make eof() true. You have to try and read the file for the 11th time to make eof() become true. That's why you have the i-- "oops, one too many" bodge.


This is in http://www.cplusplus.com/forum/beginner/278122/ if you want to read about it.

Andy
@Daisuke,
I ran your code, and it worked, at least as far as I could tell.
Record Number:	1
Forename:	John Smith School 1282828
Owen Smith School None
Brittani Smith School 921421351
Nick Smith School I dont know
Surname:	
Department:	
Tel.No.:	

Not sure if this is what you want, but it's a start.

I'd go with putting all your files in the same folder, that should eliminate your error. If it doesn't, then your IDE or compiler has a problem.

I second what @Handy Andy said, it wuld be very helpful to know your computer's operating system– Windows, macOS, Linux, Debian, Unix, etc– and what IDE or compiler you are using.
Hello Daisuke,

After getting your program to run I discovered a problem. Your input file is not consistent.
1
2
3
4
John Smith School 1282828
Owen Smith School None
Brittani Smith School 921421351
Nick Smith School I dont know

Lines 1 - 3 work, but line 4 is a problem.

In the first 3 lines the last field is 1 number or 1 word and that is fine. Line 4's last field is a string with spaces. This needs to be dealt with differently.

Another option, if you can, is to make the the file a CSV file
1
2
3
4
John,Smith,School,1282828
Owen,Smith,School,None
Brittani,Smith,School,921421351
Nick,Smith,School,I dont know

This would make it easier to separate the fields. Then it would not matter what the last field is a simple "std::getline" would read whatever is left. Just a suggestion.

Since you did not say what the program needs to do no one knows if you need to be working on parallel arrays or something else. It is always a good idea to post the directions or instructions, whatever you call them, with your first post, so that you do not get suggestions that you can not use.

Here is an idea with potential for modification in the future:
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include<iostream>
#include<string>

#include<fstream>

using namespace std;  // <--- Best not to use.

struct Student
{
    std::string sForeName;
    std::string sSurName;
    std::string sDepartment;
    std::string sTelNo;
};

int main()
{
    ifstream myFile("Records.txt"); // input file object

    if (!myFile) // always check.
    {
        cerr << "\n     Unable to open input file\n";

        return 1;
    }

    constexpr int MAXSIZE{ 20 };

    Student students[MAXSIZE]; //string array

    int idx{}, recNumber{}, last{}; // counter variables  // <--- ALWAYS initialize all your variables.

    //while (idx < MAXSIZE && std::getline(myFile, students[idx].sForeName, ' '))
    //{
    //    std::getline(myFile, students[idx].sSurName,' ');
    //    std::getline(myFile, students[idx].sDepartment, ' ');
    //    std::getline(myFile, students[idx++].sTelNo);  // [b]<--- No delimiter.[\b]
    //}

    while (idx < MAXSIZE &&
           myFile >> students[idx].sForeName && myFile>>students[idx].sSurName &&
           myFile>>students[idx].sDepartment)
    {
        std::getline(myFile >> std::ws, students[idx++].sTelNo);  // [b]<--- No delimiter.[\b]
    }

    last = idx;

    idx = 0;

    while (idx < last)
    {
        cout <<
            "\n"
            "Record Number:\t" << ++recNumber << "\n"
            "Forename:\t" << students[idx].sForeName << "\n"
            "Surname:\t" << students[idx].sSurName << "\n"
            "Department:\t" << students[idx].sDepartment << "\n"
            "Tel.No.:\t" << students[idx].sTelNo << "\n";

        idx++;
    }

    //myFile.close();  // <--- Not required as the dtor will close the file when the function looses scope.

    return 0;
}

I put opening the file 1st because if there is a problem you exit the program before you define any variables or do anything else.

There are 2 while loops. Either one works. They just demonstrate 2 different ways to accomplish the same thing.

If you can not use the struct you will need parallel "std::string" arrays to hold each field. Trying to put each record into a single string will make splitting it apart more work than need to be.

Last point, line 53, you do not need a "cout" for each line. That is what the insertion operator, (<<), if for. For this particular output it gives you a better idea of what it will look like on the screen.

Should each line be just a quoted string it looks more like what you will see on the screen.

Be careful using (\t) as you are. At the beginning of a string it is not a problem. In the middle of a string, or the way that you are using it, the (\t) does not always space out the way you are thinking or wanting. For now, in this program, it appears to work.

Last, prefer to use the new line, (\n), over the function "endl". These days the (\n) works much the same as "endl" unless you have a very old compiler, pre2011 standards.

Andy

Edit:

The output I get is:

Record Number:  1
Forename:       John
Surname:        Smith
Department:     School
Tel.No.:        1282828

Record Number:  2
Forename:       Owen
Surname:        Smith
Department:     School
Tel.No.:        None

Record Number:  3
Forename:       Brittani
Surname:        Smith
Department:     School
Tel.No.:        921421351

Record Number:  4
Forename:       Nick
Surname:        Smith
Department:     School
Tel.No.:        I Don't Know

Last edited on
These days the (\n) works much the same as "endl"

I don't think they're quite the same. The '\n' just works as an escape character, and std::endl does that and clears the buffer, or something like that.
Correct, endl flushes the buffer, which can waste tons of I/O time if you're redirecting or writing to a file where such frequent flushes are detrimental. (Matters less for console output because the console probably flushes after every newline anyway.)
Last edited on
Topic archived. No new replies allowed.