stuck on initializer problem with assignment

Hello!

I have to make an assignment that can code and decode an input text file. I'm at the early stages of the beginner class so I probably made alot of mistake. Recently I have encounterd a problem with "initializers". I found pieces of code on the net which could help me with my code in it's whole. Except they don't work and I don't understand why. (later on I have to detect Lychrel numbers provided in the text document; if anyone has any input for that please let me know haha).

the specific part of code that im stuck on is the following; if you want to look at the whole code scroll below the first part:

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
 }
void codeer (ifstream & invoer) { // Wanneer er input wordt gegeven voor coderen
                                  // wordt het stuk hier onder aangesproken om
                                  // daadwerkelijk te gaan coderen
void codeer (ofstream & uitvoer)

char kar1 ; // Hier worden karakters die elkaar direct opvolgen staan gescheiden
char kar2 ; // Hier worden karakters die elkaar direct opvolgen staan gescheiden
bool toggle = false ; // Hier wordt het aantal cijfers achter elkaar berekent
int i = 1 ; // Hier wordt geteld hoeveel karakters het zelfde zijn
int k = 1 ; // Hier wordt geteld hoeveel karakters er ingevoerd ziin
int j = 0 ; // Hier worden alle uitgevoerde karakters berekend
int r = 1 ; // Hier worden alle regels geteld (\n)
int p = 0 ; // Hier wordt de "samendrukking" in % benoemd
kar1 = invoer.get() ; // Hier wordt er gecodeerd
kar2 = invoer.get () ; // Hier wordt er gecodeerd
while (!invoer.eof()) {
    k++ ;
    if ( kar1 =='\n') {
        uitvoer.put('\n') ;
        r++ ;
        j++ ;
    }
    else {
        if (kar1!=kar2) {
            if (bslash(kar1) || getal(kar1)) {
            uitvoer.put ('\\') ;
            j++;
        }
        uitvoer.put (kar1) ;
        j++ ;
        if (i>1) {
            uitvoer << i ;
            j += cijfers (i) ;
        }
        i=1;
    }
        else {
            i++;
        }
    }
    if (getal(kar1)) { // Hier worden de getallen gepubliceerd bij de uitvoer
        cout << kar1 ;
        toggle = true ;
        }
    kar1 = kar2 ;
    if (!getal(kar2) && toggle == true ) { // Scheiden van niet cijfers
        cout << endl ;
        toggle = false ;
    }
    kar2 = invoer.get () ;
}
uitvoer.put (kar1) ; // Schrijven van het einde
if (i>1){
    uitvoer << i ;
    j++;
}


// This is the code in it's whole:

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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177

#include <iostream>
#include <fstream>

using namespace std;

void infoblokje () { // Infoblokje
cout << endl;
cout << "Dit is het programma Code" << endl;
cout << "Gemaakt door: " << endl;
cout << " Backx, rechtsgeleerdheid 2012, " << endl;
cout << "" << endl;
cout << "Gemaakt op 13 oktober 2017" << endl;

}
bool bslash (char c) { // De bool geeft aan of het karakter een blackslash is.
    if ( c == 92) {
        return true;
    }
    else return false;
}
bool getal (char c) { // De bool geeft aan of het karakter een cijfer is.
    if ((c > 48 && c < 58)) {
        return true ;
        }
        else return false ;
}
int cijfers (int getal) { // De integer berekend het aantal cijfers die worden
                          // gecodeerd en telt deze op
    int teller = 0 ;
    do {
        getal = getal % 10 ;
        getal = getal / 10 ;
        teller++ ;
    }
    while (getal != 0) ;
    return teller ;
}
void codeer (ifstream & invoer) { // Wanneer er input wordt gegeven voor coderen
                                  // wordt het stuk hier onder aangesproken om
                                  // daadwerkelijk te gaan coderen
void codeer (ofstream & uitvoer)

char kar1 ; // Hier worden karakters die elkaar direct opvolgen staan gescheiden
char kar2 ; // Hier worden karakters die elkaar direct opvolgen staan gescheiden
bool toggle = false ; // Hier wordt het aantal cijfers achter elkaar berekent
int i = 1 ; // Hier wordt geteld hoeveel karakters het zelfde zijn
int k = 1 ; // Hier wordt geteld hoeveel karakters er ingevoerd ziin
int j = 0 ; // Hier worden alle uitgevoerde karakters berekend
int r = 1 ; // Hier worden alle regels geteld (\n)
int p = 0 ; // Hier wordt de "samendrukking" in % benoemd
kar1 = invoer.get() ; // Hier wordt er gecodeerd
kar2 = invoer.get () ; // Hier wordt er gecodeerd
while (!invoer.eof()) {
    k++ ;
    if ( kar1 =='\n') {
        uitvoer.put('\n') ;
        r++ ;
        j++ ;
    }
    else {
        if (kar1!=kar2) {
            if (bslash(kar1) || getal(kar1)) {
            uitvoer.put ('\\') ;
            j++;
        }
        uitvoer.put (kar1) ;
        j++ ;
        if (i>1) {
            uitvoer << i ;
            j += cijfers (i) ;
        }
        i=1;
    }
        else {
            i++;
        }
    }
    if (getal(kar1)) { // Hier worden de getallen gepubliceerd bij de uitvoer
        cout << kar1 ;
        toggle = true ;
        }
    kar1 = kar2 ;
    if (!getal(kar2) && toggle == true ) { // Scheiden van niet cijfers
        cout << endl ;
        toggle = false ;
    }
    kar2 = invoer.get () ;
}
uitvoer.put (kar1) ; // Schrijven van het einde
if (i>1){
    uitvoer << i ;
    j++;
}
j++;
cout << endl;
cout << "De file is gecodeerd." << endl;
cout << "De file heeft " << r <<
cout << " aantalregels (met inbegrip van lege regels):" << endl;
cout << endl;
cout << "De invoerfile heeft een totaal aantal tekens van: " << k << endl;
cout << "De uitvoerfile heeft een totaal aantal tekens van: " << j << endl;

p = ((double)j / (double)k) * 100 ; // procentuele compressie
cout << "compressie = " << p << "%" << endl;
}

void decodeer (ifstream & invoer) // hiermee initieert zich het codeer proces
void decodeer (ofstream & uitvoer) { // hiermee initieert zich de uitvoer
char kar1 ; // Hier worden karakters die elkaar direct opvolgen staan gescheiden
char kar2 ; // Hier worden karakters die elkaar direct opvolgen staan gescheiden
int getal = 0; // Hier worden de getallen tot hele getallen gemaakt
int j = 1; // Hier worden de getallen geteld voor het afronden
kar1 = '\n';
kar2 = invoer.get ();
while (!invoer.eof()) { // Hier begint het decoderen
    if (getal(kar2))
        getal = getal * 10 + kar2 - '0' ;
    else {
        if (getal > 0) {
            for ( j=1 ; j < getal ; j++)
                uitvoer.put (kar1) ;
            getal = 0 ;
}
        if (bslash(kar2))
            kar2 = invoer.get() ;
        uitvoer.put(kar2) ;
        kar1 = kar2;
    }
        kar2 = invoer.get () ;
}
cout << "Uw document is gedecodeerd." << endl;
}

int main () {
ifstream invoer ; // Activatie voor het coderen
ofstream uitvoer ; // Activatie voor het decoderen
string filenaamin ; // filenaam van het te (de)coderen bestand
string filenaamuit ; // filenaam van het te (de)coderen bestand
char ed ;
infoblokje () ;
cout << "Wilt u een bestand coderen voer dan de hoofdletter E in" << endl;
cout << "Wilt u een bestand decoderen voer dan de hoofdletter D in" << endl;

cin >> ed ;
cout << endl;
cout << "Voer de naam van uw bestand in (let op hoofdletter en"
cout << "locatie gevoelig)" << endl;
cin >> filenaamin ;
cout << "Hoe wilt u het uitkomende bestand noemen?" << endl;
cin >> filenaamuit ;
invoer.open (filenaamin.c_str(), ios::in);
    if (!invoer) {
        cout << "File kon niet worden geopend of gevonden" << endl;
        return (1) ;
}
uitvoer.open ( filenaamuit.c_str(), ios::out);
if ( ! uitvoer ) {
    cout << "Uw uitvoerbestand is niet correct" << endl;
    return (1) ;
}
cout << endl ;<<>>
if (ed == 'E') { // Hier wordt er gebruik gemaakt van de activatie cin
    codeer(invoer , uitvoer);
}
else if (ed == 'D') { // Hier wordt er gebruik gemaakt van de activatie cin
    decodeer (invoer , uitvoer) ;
}
else {
    cout << "Ongeldige input" << endl;
    return (1) ;
}
invoer.close() ;
uitvoer.close() ;

return 0;
}


What actually is the problem - compile errors, wrong output, no output, crash....?
Hello Backx,

Welcome to the forum and thank you for using code tags and nicely commented code.

Bear with me as I will have to translate some of the language to understand what is going on here.

One thing I noticed right off is using "eof" in your while loops. This is a bad idea as it does not work the way you might think. By the time "eof" is set you will usually process the last input twice which is not what you want.

I am not sure what you mean by "initializes", but I can say that it is a good idea to initialize your variables.An example:

1
2
3
4
5
6
7
char kar1{} ; // Hier worden karakters die elkaar direct opvolgen staan gescheiden
char kar2{} ; // Hier worden karakters die elkaar direct opvolgen staan gescheiden
bool toggle = false ; // Hier wordt het aantal cijfers achter elkaar berekent
// Already initialized.
int i = 1 ; // Hier wordt geteld hoeveel karakters het zelfde zijn
int k = 1 ; // Hier wordt geteld hoeveel karakters er ingevoerd ziin
int j = 0 ; // Hier worden alle uitgevoerde karakters berekend 


I see several places in your code that has uninitialized variables. The {} are called a uniform initialization, from C++11, and being empty will initialize numeric variables to zero, strings to empty and I am not sure what it will put in a "char".

From what you said I believe the input file is just text to be encrypted.

I will start to work on this and see what else I can find.

Hope that helps for now,

Andy
Thanks alot Andy,

This already helps; I missed some insight on how to initialize some variables as kar1.

I have noticed I made some few other mistakes in the code so I'm rewriting some parts of it; so dont waste to much of your time here. I can imagine I made a bit to many mistakes.

And yes I just have to make an program which can Code and Decode a certain textfile.
The example given is (these are the karakters for used in the example):
Dit is een voorbeeldfile voor het verslag in latex In de volgende regels zullen we wat backslahes en cijfers proberen: 123/44455///////33223//1/2/3///// of we doen het zo:
46573948574??????????????????????????????????|||||||||12221234412.....

Which should roughly result in the following:

Dit is e2n vo2rbe2ldfile vo2r het verslag in latex In de volgende regels zul2en we wat backslahes en cijfers proberen: \1\2\3/\43\52/7\32\22\3/2\1/\2/\3/5 of we doen het zo:
\4\6\5\7\3\9\4\8\5\7\4?34|9\1\23\1\2\3\42\1\2.5


Meanwhile my program should check if any of the text that would be inserted contains Lychrel numbers which I wrote the following formula for which I haven't applied yet:

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
int nummer;
cin >> nummer;
long long int Reverse(long long int nummer){
    long long int rem = 0;
    while (nummer > 0)
    {
    rem = (rem * 10) + (nummer % 10) ;
        nummer = nummer / 10;
    }
    return rem;
}

bool is_palindroom(long long int num)
{
    return (num == Reverse)
(num));
}

bool isLychrel(int num, const int iterCount = 50)
{
    long long int temp = num;
    long long int rev;
    int iteraties=0
    for (int i = 0; i < iterCount; i++)
    {
        rev = Reverse(temp);
        if (is_palindroom(rev + temp))
            return false;
        temp = temp + rev;
        iteraties = iteraties + 1;
    }
    std::cout<< "" << nummer << "has" << iteraties << "iteraties."
    return true;
}}

int main()
{
    bool l = isLychrel(4994);
    std::cout << l << endl;
    1 = isLychrel(196)
    std::cout << l << endl;
    1 = isLychrel (57);
    std::cout << l << endl;


If there are any forumrules i'm not following properly just adress them and I'll change it :)

Hello Backx,

After loading up the program I found that there are many errors that would not let the program compile.

You are missing tha header file "<string>"

Line 147 is missing a ; at the end.

1
2
3
4
void codeer (ifstream & invoer) { // Wanneer er input wordt gegeven voor coderen
                                  // wordt het stuk hier onder aangesproken om
                                  // daadwerkelijk te gaan coderen
void codeer (ofstream & uitvoer)

Line 1 is neither a proto type, no ; after the closing), nor is it a function, no closing }. Line 4 is the start of a function, but has no opening { for the block. Also it is missing a function parameter. The way you have coded these two lines, one and four, do not make a function. What you need is:
void codeer(ifstream& invoer , ofstream & uitvoer) // <--- Not enough parameters. Added input stream.

Line 117 "getal" is a local variable that you are trying to use as a function call and it does not work.

I m not sure what you are trying to do here: if (getal(kar2)), but this is not a function call because "getal" is defined as a local variable of type "int" and it is confusing the compiler. The variable "getal" in the "decodeer" function needs to have a different name form the function call to "getal" to work as a local variable. A few lines later in the for loop int "j" is compared to the "bool" return value of the function "getal". Not quite what you wanted to do here. And since it is a type mismatch it does not work.

Line 98: Either you are missing something or at the end you need to replace "<<" with a ";". If line 99 is part of line 98 then you need to remove "cout <<" as it is not needed. If not then each line needs to be a separate command.

line 104 everything to the right of = is changed to a double for the math. And yes even 100 is promoted to 100.00 for the math. The problem is when you are done you store the answer into an int loosing any decimal part of the number. It might be better to make "p" a double.

Just need to figure out this last problem around line 117 to get the code to compile so I can see what it is doing.

Hope that helps,

Andy
Hello Backx,

Two more things I noticed:

Line 149 and 151 would work better as std::getline(std::cin, filenaamin/filenaamuit). This way if the naam has a space in it this will keep the space whereas cin >>filenaamin will only get up to the space leaving the rest in the input buffer for the next read to extract.

When opening a file, if you are using C++11 standards or after, a std::string will work. You do not have to convert it to a C string.

Andy
Hello Backx,

After working with the program I discovered that this bit of code should output one line.
1
2
cout << "Voer de naam van uw bestand in (let op hoofdletter en"
cout << "locatie gevoelig)" << endl;


To do this properly it would look like this:
1
2
cout << "Voer de naam van uw bestand in (let op hoofdletter en"
     << "locatie gevoelig)" << endl;


Or you could just use this:
 
cout << "Voer de naam van uw bestand in (let op hoofdletter en locatie gevoelig)" << endl;


Everything from the beginning of the program down to "codeer" appears to work without any problem.

In the function"codeer" I changed the variable "p" from int to double.

The while (!invoer.eof()) works here because you read kar2 just before you return to the while condition, so here it works. I do not know if you did this by design or accident, but you got it right. The rest of the code down to where you figure the value of "p" appears to work.

After running the program several times I realized that the value of "p" was incorrect. It was showing me that the compression rate was 90+% when it should have said 9+%. I adjusted the formula to this p = (1 - ((double)j / (double)k)) * 100; to achieve the correct answer.

This leaves the output with 4 numbers to the right of the decimal point, but that can be changed with
std::cout << std::fixed << std::showpoint << std::setprecision(?); // <--- Requires the header file "<iomanip>". where the ? is a whole number of seconds.

In the "decodeer function" I changed "int getal;" to "int iGetal" so as not to be confused with the function call "getal()". When I tested the decoding of the file all worked well.

In main I changedcin >> filenaamin; to std::getline(cin, filenaamin); just in case the file name would have a space in it. The new code looks like this now:
1
2
3
cout << "Enter the name of your file (note capital and location sensitive)" << endl;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file "<limits>".
std::getline(cin, filenaamin);

Line 2 needs to follow a "cin >> something" and precede any "getline()" because the "cin" will leave a "\n" in the input buffer that "getline" will extract from the buffer and move on not giving you a chance to enter anything from the keyboard. The same is true for reading from a file just change "std::cin" to the name you used for the file stream.

This may help you understand the ".ignore" http://www.cplusplus.com/reference/istream/istream/ignore/

I opened the output file this way uitvoer.open(filenaamuit, ios::out | std::ios::trunc | std::ios::ate); This way the file is cleared each time the program is run, so as not to confuse you trying to figure out what you are working with. Later on you may choose to remove "trunc" if so be sure to change "ate" to "app".

In the if/else if statements I changed the condition to if (toupper(ed) == 'E'). If for some reason you can not use this I would suggest if (ed == 'E' || ed == 'e') to catch either case.

Overall you did a good job with the program. I am impressed.

The new functions that you posted look OK with the exception of "is_palindroom". I believe "Reverse" should be a function call. And the next line 16 has no point or use. Very likely to cause a compile error. I can add these functions to the program, but other than testing I am not sure where you would want to put the function calls.

There is something to work on.

Hope that helps,

Andy
Wow Andy thats alot of thought you put in there, thank you very much.

Indeed I saw I didnt adjust all variables correctly. Your feedback helps alot. I put the project down for a few days and restarted it today. Acctually going really well.
I think it will work after today! I will probably post it here afterwards.

Cheers!

Sjoerd
Topic archived. No new replies allowed.