Reading from txt file

Hello, I have serious problem.
Is it impossible to read files from this txt document C++ Thanks
2a monday 1 history 2 math 3 biology 4 x
2a tuesday 1 math 2 history 3 art 4 music
2a wednesday 1 biology 2 history
2a thursday 1 math 2 programming 3 art
2a friday 1 math 2 x
2b monday 1 math 2 biology 3 art 4 x
2b tuesday 1 art 2 math 3 biology 4 x
2b wednesday 1 biology 2 geography 3 music
2b thursday 1 histrory 2 math 3 art
2b friday 1 music 2 technology 3 math
Last edited on
deividas717 wrote:
Is it impossible to read files from this txt document C++
No, it is not impossible.
So how it should be?
That depends on what the data actually means. I assume you have some assignment to go along with this data that explains what the data means?
Ok so 2a and 2c are classes name monday-friday name of the week 1 lesson number and for example math lesson name. I need that all these things to be written in differerent variables. I know that it is really hard to do because every day number of lessons arent the same.
And what is 'x' please?
2a monday 1 history 2 math 3 biology 4 x


Also, and perhaps more important, what do you need to do with the data after reading it?
Last edited on
sorry x - describes that lesson cannot be at that time.
I need to put all my data to the class
But what sort of output will you be needing? That can affect how you choose to store the data within the program.
And when you say class, does that mean a c++ class or a class such as 2a?


As a starting point I would read from the text file line by line using getline(), then use a stringstream in order to read the individual details from the current line.
Last edited on
Ok so i need a c++ class. I dont understand how much variables i need to use, because in every line number of lessons aren't the same.
Well, there are some fixed pieces of data which always occur on every line. After that there is a variable part, which you might represent as an array or a vector within the class. A vector is easier as it allows you to add as many or as few items as you like. Or use an array of say 10 elements (again within the class) and use as many or as few elements as necessary. If you did that, you would need to have a count variable to specify how many elements are in use.

Reading the data is not very hard, one you have some sort of place where you will put the data.

The very last line of the file looks different to the others. It ends with the number 3 but there is no text following it. Is that deliberate?
Ohh sorry no it is my fault. Could you writte example how this code should look like? Because I'm new at programming and I don't know much. Also I don't know anything about vectors in c++ so maybe there are another suggestion or alternative?
I did say, instead of using a vector,
" Or use an array of say 10 elements (again within the class) and use as many or as few elements as necessary. If you did that, you would need to have a count variable to specify how many elements are in use. "


I'm willing to help, but I don't want to write all the code for you. You could make a start at defining the class - there are some fixed values there, so you could write the code for those. Have you ever used an array? If so you could add that too.

Now there is a question: what goes in the array? Well, there is a pair of values, such as "1 math", so you could use separate arrays for each, or another very simple class to contain just those two values.

I'm getting the feeling already that I'm doing the work for you. I think you need to make a start at writing the code and we will look at how it is progressing after that.

OK Chevril, here's my class

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
#include <iostream>
#include <fstream>
#include <string>

const char CD1[]="Classes.txt";
const char MAX = 100;

class Lesson{
private: 
	 string class;
	 string day;
	 int nr;
	 string lesson;
public:
	void Set(string class, string day, int nr, string lesson);
	 string GetClass{return class;}
	 string GetDay(){return day;}
	 int GetNr(){return nr;}
	 string GetLesson(){return lesson;}
};
void Lesson::Set(string class, string day, int nr, string lesson){
	 Lesson::class=class;
	 Lesson::day=day;
	 Lesson::nr=nr;
         Lesson::lesson=lesson;
}
void Read (const char CD1[], Lesson p[], int & n);

int main(){
Lesson p[MAX];
int n=0;

Read(CD1, p, n);

cin.ignore();
return 0;
};
void Read (const char CD1[], Lesson p[], int & n){
ifstream fd(CD1);
  while(!fd.eof()){
         fd >> p[n++].GetClass() >> p[n++].GetDay();
  while(fd.peek() != '\n')
	 fd >> p[n++].GetiNr() >> p[n++].GetLesson();
  }
fd.close();
}
Last edited on
Well, I don't know whether you tried to compile that, there are a few issues.

I added a new member function, addLesson.
1
2
3
4
5
void Lesson::addLesson(int num, std::string lesson)
{
    nr = num;
    this->lesson = lesson;
}


The function which reads the file had a number of problems, I re-worked it a little:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void Read (const char CD1[], Lesson p[], int & n)
{
    std::ifstream fd(CD1);

    std::string Klass;
    std::string day;

    int number;
    std::string lesson;

    while (fd >> Klass >> day)
    {
        p[n].Set(Klass, day, 0, "");

        while(fd.peek() != '\n')
        {
            fd >> number >> lesson;
            p[n].addLesson(number, lesson);
        }
        ++n;
    }

    fd.close();
}

That was just a quick attempt. I regard the current method of using peek() and checking for a newline character to be somewhat fragile. For example if there is additional whitespace it may not work, or if the last line has no newline, the program may enter an infinite loop. Using getline and a stringstream as I suggested earlier would be better.

So far there is only space to hold a single lesson, but this should give you something to think about, how to progress forwards from here.
Last edited on
Chevril, Thank You!
Here's my varaint
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void Read(const char CD[], Lesson p[], string & class, string & day, int & nr, string & lesson, int & sum){
	ifstream fd(CD);
sum = 0;
while(!fd.eof()){
		fd >> class >> day;
		while(fd.peek() != '\n' && !fd.eof() ){
			 fd >> nr >> lesson;
		p[sum].Set(class, day, nr, plesson);
		}
cout << p[sum].GetClass() << " " << p[sum].GetDay() << " "  << p[sum].GetNr() << " "  << p[sum].GetLesson() << endl;
	   sum++;	
	   
}
fd.close();
}

But there are one serious problem. When I try to cout << p[sum].GetClass() << " " << p[sum].GetDay() << " " << p[sum].GetNr() << " " << p[sum].GetLesson() << end on the screen it prints just for examle
2a monday 4 x
2a tuesday 4 music
and so on
so it prints class day and LAST LESSON NUMBER why? Thanks.
Last edited on
I did point to that problem already in my previous post:
Chervil wrote:
So far there is only space to hold a single lesson,


The solution, as I mentioned several times in this thread, is to allow space for multiple lessons, by using an array or vector.

In my previous post, I added this code:
1
2
3
4
5
void Lesson::addLesson(int num, std::string lesson)
{
    nr = num;
    this->lesson = lesson;
}

This is actually needed. Because we don't know in advance how many different lessons there will be, then we must repeatedly add each one as it is read from the file.

Of course currently, the values are always placed in the same variables, nr and lesson, so whichever value was most recently stored will be the one you see printed out.

What you need to do is to keep a count of how many lessons have been added, and store each one in a new location in the array.

For example you could change
1
2
    int nr;
    string lesson;

to:
1
2
3
    int nr[6];
    string lesson[6];
    unsigned int count;

Then, set the initial value of count to 0 when the Lesson object is created. Each time the function addLesson() is called, store the data in the latest position and add 1 to count.

There will be a few other changes following on as a consequence of making that change, for example like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    int GetNr(unsigned int n) const {
        if (n<count)
            return nr[n];
        else
            return 0;
    }

    std::string GetLesson(unsigned int n) const {
        if (n < count)
            return lesson[n];
        else
            return "";
    }

    unsigned int getCount() const { return count; };
Last edited on
Topic archived. No new replies allowed.