I am trying to learn C++ and a foreign language

And to combine both of them I thought to make a program in C++ that verifies the sentences that I hear on the audio book.
I have two text file ROM.txt and GER.txt. I want the program to ask me for a random sentence from my mother language (ROM.txt) and to verify if the text that I enter is correct.

Basically the first line from ROM.txt has the translation on first line of the second file GER.txt, second line with second from the other file and so 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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <iostream>
#include <vector>
#include <string>
#include <time.h>
#include <stdlib.h>
#include <fstream>

using namespace std;
int main()
{
	int initial, initial2, random;
	int identifier;
	srand(time(NULL));
	string ro[5], de[5];
	string verification, verification2;
	string help = "help";
	ifstream fileROM, fileGER;
	fileROM.open("ROM.txt");
	if (!fileROM)
	{
		cout << "Error at opening Romanian file";
		system("pause");
		exit(-1);
	}
	initial = 0;
	while (!fileROM.eof())
	{
		getline(fileROM, ro[initial]);
		initial++;
	}
	fileROM.close();

	fileGER.open("GER.txt");
	if (!fileGER)
	{
		cout << "Error at opening German file";
		system("pause");
		exit(-1);
	}
	initial2 = 0;
	while (!fileGER.eof())
	{
		getline(fileGER, de[initial2]);
		initial2++;
	}
	fileGER.close();

	while (1)
	{
		random = rand() % 5;
		for (identifier = random; ;)
		{
			cout << "Translation for: \n";
			cout << ro[identifier] << " e" << endl;
			getline(cin, verification);
			if (verification == help)
			{
				cout << de[identifier] << endl;
			}
			else
			{
				if (verification == de[identifier])
				{
					cout << "Correct! \n";
				}
				else
				{
					cout << "Incorrect! \n";

					while (verification != de[identifier])
					{
						getline(cin, verification);
						if (verification == de[identifier])
						{
							cout << "Correct! \n";
						}
						else
						{
							cout << "Keep trying! \n";
						}
					}
				}
			}
			break;

		}
		system("pause");
		system("cls");
	}


	return 0;
}


My program is incomplete and i want to add that when I type help to show the translation and for the screen to clear and ask me again to translate the same sentences for which I typed help...I am a little lost.

Also I do not know how to make string functions. For example I have this loop:
1
2
3
4
5
6
7
8
9
10
11
12
while (verification != de[identifier])
		{
			getline(cin, verification);
			if (verification == de[identifier])
			{
			cout << "Correct! \n";
			}
			else
			{
			cout << "Keep trying! \n";
			}
		}

and I want it to make it as a function. How do I put the string values "verification" and "de[indentifier]" as parameters for that function. I tried like this but it wouldn't work.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void function(int identifier, string& verification, string& de[identifier]); 

int main()
{...
...
...

function(identifier, verification, de[identifier]);
...
...
return 0;
}

void function(int identifier, string& verification, string& de[identifier])
{
...
do stuff
}


Help would be much appreciated. :)


void foo(string & s);
...

main()
foo(de[identifier]);

OR
void foo(string* ps, int id); //you may want the whole DE array in some function later
something( ps[id]);
...
main()
foo(de, identifier); //note that parameter names and input variables don't have to match.
//the parameter name in the function is just a placeholder name that is an alias for the current input to the function.
Last edited on
Line 26,41: 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
  }


Lines 14,50: Not sure why you're hardcoding 5 here. That implies you never have more than 5 records in your files. Never a good idea to use hard coded constants for the number of records read from a file. I would suggest using a std::vector.
1
2
3
4
5
6
7
8
9
10
11
12
13
    vector<string> ro;
    vector<string> de;
    string temp;
...
    while (getline(fileROM, temp))
    {   ro.push_back(temp);
    }
...
    while (getline(fileGER, temp))
    {   de.push_back (temp); 
    }
...
    random = rand() % min_(ro.size(), de.size());  // Do min in case the files are different sizes 


Last edited on
Thank you jonnim and abstraction for answering me.

For jonnin. I am trying this code but it doesn't work:
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
#include <iostream>
#include <vector>
#include <string>
#include <time.h>
#include <stdlib.h>
#include <fstream>

void functie(string* ps, int id); // getting an error: string undeclared indentifier ; ps undeclared indentifier ; type int unexpected

using namespace std;
int main()
{
	int initial;
	string de[5];
	ifstream fileGER;
	fileGER.open("GER.txt");
	if (!fileGER)
	{
		cout << "Error at opening German file";
		system("pause");
		exit(-1);
	}
	initial = 0;
	while (!fileGER.eof())
	{
		getline(fileGER, de[initial]);
		initial++;
	}
	fileGER.close();
	functie(de, initial); // functie identifier not found 
	system("pasue");

	return 0;
}

void functie(string* ps, int id)
{
	int i = 2;
	cout << ps[2] << endl;

}


For abstractionanon. Temporarily I only have 5 phrases. I said to make first the code and see that works properly, then add all the ~500 phrases.
Do you mean like this :

1
2
3
4
while getline(fileROM, ro[initial])
{
		initial++;
}

Those this memorize my phrase on string arrays too? so that I can access them later individually?
/ getting an error: string undeclared indentifier

Your use of string precedes using namespace std; so the compiler doesn't know where to look for std::string.

Either qualify line 8 as std:;string or move line 8 after line 10.

this memorize my phrase on string arrays too? so that I can access them later individually?

Yes.
Last edited on
it...WORKS!! Thank you so much from the bottom of my hearth!


Regarding AbstractionAnon comment "This means after you read the last record of the file, eof is still false"

I observed that even though I have only five sentences in my text file, I needed to declare the string "de[5]" , meaning that it will count 6, because it goes from 0 to 5, right?
I really didn't know why it didn't let me to put 4, because I only had 5 phrases in the text file, so accordingly to what you have said it makes sense for the 5th requirement. Am I right about this?

Again, thank you guys.
I observed that even though I have only five sentences in my text file, I needed to declare the string "de[5]" , meaning that it will count 6, because it goes from 0 to 5, right?
No, that declares an array of 5 elements, from 0 to 4 inclusive. The 5 between the brackets is the size of the array, not the index of the last element.
You are perfectly right :)
Greetings.
I managed to make my program to work perfectly ( at least the logical part ) and I encountered some minor problems :

○ Is there a method for the console to show special characters?
Currently it shows "HauptstΣdte" instead of "Hauptstädte".

○ I coded the program w/o using functions, with some goto requirements because I encountered the following problem and my limited knowledge couldn't find an answer.
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
int main()
{
	
	...
	...
	
			cout << "Translation for: \n";
			cout << ro[identifier] << " e" << endl;
			getline(cin, verification);

			ajutor(verification, de, identifier, help, ro);  //encounter1
			
			{
				if (verification == de[identifier])   //encounter2
	...
	...
	
	return 0;
}


void ajutor(string verf1, string* deH, int inH, string helpH, string* roH) //help_foo
{

	while (verf1 == helpH)
	{
		
		cout << deH[inH] << endl;
		system("pause");
		system("cls");
		cout << "Traducerea pentru:\n" << roH[inH] << " e " << endl;
		getline(cin, verf1); //encounter3
	}
	
}


The problem is that encounter1 is calling the function and encounter2 doesn't work anymore because encounter3 doesn't stock the string value to verification on encounter2, so my if code is skipped. Does it make snese what I am trying to say?
I tried something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int main()
{
...
while (functie(verification, de, identifier) == help)
			{
				cout << de[identifier];
			}

			{
				if (functie() == de[identifier])
				{
				cout << "Correct! \n";
				}
...
return 0;
}

string functie(string verf1, string* deH, int idH)
{
	getline(cin, verf1);
	if (verf1 == deH[idH])
		return functie(deH); // error that says no suitable constructor
}


Thank you in advance.
ascii 132 is ä; look at an ascii table online and the extended chars. It supports a FEW non English chars, but not very many.

I have no idea what you said, but goto can usually be avoided.
I don't see a goto in your example, and I didn't fully get what you were saying either.

gotos usually provide one of 4 things:
1 a loop surrogate
2 a conditional branch surrogate
3 a 'break' or 'continue' replacement (sometimes this can't be easily avoided due to nested loops)
4 a function/subroutine surrogate

string functie(string verf1, string* deH, int idH)
{
getline(cin, verf1);
if (verf1 == deH[idH])
return deH[idH]; // error that says no suitable constructor
return "";
}

the above will work and you can check the result against empty string "" to know if it was verified or not? Does that help?


Last edited on
Yes it help me a lot. Slowly I am organizing my knowledge. I made progression too while reading Brain Overland's book "C++ Without Fear".

Thank you very much for your patience and support :) Kudos.
Topic archived. No new replies allowed.