Connecting Tech Pros Worldwide Help | Site Map

Text file Program help please

ComicCaper
Guest
 
Posts: n/a
#1: May 13 '06
Hi all,

I use a quiz program that accepts a text file for questions and answers
in this format:

Question
Answer1 <----is the correct answer. Quiz randomizes answers.
Answer2
Answer3
Answer4
0 <-------corresponds to which Answer is the correct one.

(4 lines of blank space then the next set.)



In order to make my life easier I created a program that will take 3
files and combine them into one using the above formatting.

Using vocab style questions I have a keyword file for the Questions, one
that has the correct answer and then one that has 3 wrong answers.

Problem: if I have 2 or 3 keywords the program works great. If I dump in
over 300 keywords the program gets stuck in a loop. I can think of only
two things that there is a hidden character in the keyword file that's
causing the problem (how do I find hidden characters?) and (for fear of
sounding stupid) that the CPU and RAM can't keep up with what is going on.

Here's my program:

/*Matt Short

*/

#include <iostream>
#include <fstream>

using namespace std;

int main()
{

const int SIZE = 30; //setting up keywordFile;
fstream keywordFile;
char input[SIZE];

const int LINE = 400; //setting up definition file;
fstream defFile;
char def[LINE];

fstream ansFile; //setting up answer file
char ans[LINE];

ofstream quizFile("c:\\quizFile.txt"); //setting up final quiz file


keywordFile.open("c:\\keyword.txt", ios::in);
defFile.open("c:\\defFile.txt", ios::in);
ansFile.open("c:\\ansFile.txt", ios::in);

while (!keywordFile.eof())
{

keywordFile.getline(input, SIZE);
defFile.getline(def, LINE);
quizFile << input << endl << def << endl;

ansFile.getline(ans, LINE);
quizFile << ans << endl;

ansFile.getline(ans, LINE);
quizFile << ans << endl;

ansFile.getline(ans, LINE);
quizFile << ans << endl << "0" << endl << endl << endl << endl << endl;

}
keywordFile.close();
quizFile.close();
ansFile.close();
defFile.close();


return 0;

}
Daz
Guest
 
Posts: n/a
#2: May 13 '06

re: Text file Program help please



ComicCaper wrote:
[color=blue]
> Problem: if I have 2 or 3 keywords the program works great. If I dump in
> over 300 keywords the program gets stuck in a loop. I can think of only
> two things that there is a hidden character in the keyword file that's
> causing the problem (how do I find hidden characters?) and (for fear of
> sounding stupid) that the CPU and RAM can't keep up with what is going on.[/color]

I would recommend you have a look at the output file when your program
hangs and you terminate it, to see how far it got, and then check out
the other files for anything out of the ordinary. The only hidden
characters that would affect you (as far as I know) , are the common
ones that appear in a plain text file, such as '\n' and '\r'.

Please don't take this as gospel, I am fairly new to C++, but this is
the first logical-sounding step I would take.

Daz
Guest
 
Posts: n/a
#3: May 13 '06

re: Text file Program help please


Daz wrote:[color=blue]
> ComicCaper wrote:
>[color=green]
> > Problem: if I have 2 or 3 keywords the program works great. If I dump in
> > over 300 keywords the program gets stuck in a loop. I can think of only
> > two things that there is a hidden character in the keyword file that's
> > causing the problem (how do I find hidden characters?) and (for fear of
> > sounding stupid) that the CPU and RAM can't keep up with what is going on.[/color]
>
> I would recommend you have a look at the output file when your program
> hangs and you terminate it, to see how far it got, and then check out
> the other files for anything out of the ordinary. The only hidden
> characters that would affect you (as far as I know) , are the common
> ones that appear in a plain text file, such as '\n' and '\r'.
>
> Please don't take this as gospel, I am fairly new to C++, but this is
> the first logical-sounding step I would take.[/color]

In addition, I would also use std::string as opposed to a character
array. In my limited experience, there is nothing you can do with a
character array that you can't do with a std::string. I'm not sure if
this will fix your problem, however, strings are completely dynamic so
it doesn't matter how long it is.

You could also use a regex to flag any characters that aren't in the
range you specify. If you don't already know regex, it's worth
learning, but will probably take too long to learn for the purpose you
need it.

Daz
Guest
 
Posts: n/a
#4: May 13 '06

re: Text file Program help please



Daz wrote:[color=blue]
> In addition, I would also use std::string as opposed to a character
> array. In my limited experience, there is nothing you can do with a
> character array that you can't do with a std::string. I'm not sure if
> this will fix your problem, however, strings are completely dynamic so
> it doesn't matter how long it is.
>
> You could also use a regex to flag any characters that aren't in the
> range you specify. If you don't already know regex, it's worth
> learning, but will probably take too long to learn for the purpose you
> need it.[/color]

Err... you might find it's also useful to check if the files you are
trying to open, are actually open. For debugging small programs like
this, I often add a few 'cout' lines, so every line that is going to be
added to the file, can be seen on the console. You will see if anything
is out of the ordinary here in your mock-matrix-style screen. :D

Jonathan Mcdougall
Guest
 
Posts: n/a
#5: May 13 '06

re: Text file Program help please


ComicCaper wrote:[color=blue]
> Hi all,
>
> I use a quiz program that accepts a text file for questions and answers
> in this format:
>
> Question
> Answer1 <----is the correct answer. Quiz randomizes answers.
> Answer2
> Answer3
> Answer4
> 0 <-------corresponds to which Answer is the correct one.
>
> (4 lines of blank space then the next set.)
>
>
>
> In order to make my life easier I created a program that will take 3
> files and combine them into one using the above formatting.
>
> Using vocab style questions I have a keyword file for the Questions, one
> that has the correct answer and then one that has 3 wrong answers.
>
> Problem: if I have 2 or 3 keywords the program works great. If I dump in
> over 300 keywords the program gets stuck in a loop. I can think of only
> two things that there is a hidden character in the keyword file that's
> causing the problem (how do I find hidden characters?) and (for fear of
> sounding stupid) that the CPU and RAM can't keep up with what is going on.[/color]

Are you sure it is stuck? Can you output something at each loop to see
what's happening?
[color=blue]
> Here's my program:
>
> /*Matt Short
>
> */
>
> #include <iostream>
> #include <fstream>
>
> using namespace std;[/color]

http://www.parashift.com/c++-faq-lit....html#faq-27.5
[color=blue]
> int main()
> {
> const int SIZE = 30; //setting up keywordFile;
> fstream keywordFile;
> char input[SIZE];
>
> const int LINE = 400; //setting up definition file;
> fstream defFile;
> char def[LINE];
>
> fstream ansFile; //setting up answer file
> char ans[LINE];[/color]

For these three blocks:
1) use std::string (from <string>)
2) don't define an object if you cannot initizalise it
3) use either std::ofstream or std::ifstream, not std::fstream (except
in special cases)

These should therefore be

std::ifstream keywordFile("c:\\keywork.txt");
std::ifstream defFile("c:\\defFile.txt");
std::ifstream ansFile("c:\\ansFile.txt");

For the character arrays, see below.
[color=blue]
> ofstream quizFile("c:\\quizFile.txt"); //setting up final quiz file
>
> keywordFile.open("c:\\keyword.txt", ios::in);
> defFile.open("c:\\defFile.txt", ios::in);
> ansFile.open("c:\\ansFile.txt", ios::in);[/color]

When you use std::ifstream, ios::in is redundant.
[color=blue]
> while (!keywordFile.eof())[/color]

You may read past beyond EOF with this. Think: EOF is detected after
reading, that means ....
[color=blue]
> {
> keywordFile.getline(input, SIZE);[/color]

..... here. Oups.
[color=blue]
> defFile.getline(def, LINE);
> quizFile << input << endl << def << endl;
>
> ansFile.getline(ans, LINE);
> quizFile << ans << endl;
>
> ansFile.getline(ans, LINE);
> quizFile << ans << endl;
>
> ansFile.getline(ans, LINE);
> quizFile << ans << endl << "0" << endl << endl << endl << endl << endl;[/color]

Now, if you decide to use std::string, these would look like

std::string line;

getline(keywordFile, line);
quizFile << line << "\n";

getline(defFile, line);
quizFile << line << "\n";

// ...

Note that outputing std::endl flushes the buffer of the stream, which
may not be what you want (ie a new line).
[color=blue]
> }[/color]
[color=blue]
> keywordFile.close();
> quizFile.close();
> ansFile.close();
> defFile.close();[/color]

Redundant (that's what destructor are for).


Jonathan

Daz
Guest
 
Posts: n/a
#6: May 13 '06

re: Text file Program help please



Jonathan Mcdougall wrote:
[color=blue]
> ComicCaper wrote:[color=green]
> > Hi all,
> >
> > I use a quiz program that accepts a text file for questions and answers
> > in this format:
> >
> > Question
> > Answer1 <----is the correct answer. Quiz randomizes answers.
> > Answer2
> > Answer3
> > Answer4
> > 0 <-------corresponds to which Answer is the correct one.
> >
> > (4 lines of blank space then the next set.)
> >
> >
> >
> > In order to make my life easier I created a program that will take 3
> > files and combine them into one using the above formatting.
> >
> > Using vocab style questions I have a keyword file for the Questions, one
> > that has the correct answer and then one that has 3 wrong answers.
> >
> > Problem: if I have 2 or 3 keywords the program works great. If I dump in
> > over 300 keywords the program gets stuck in a loop. I can think of only
> > two things that there is a hidden character in the keyword file that's
> > causing the problem (how do I find hidden characters?) and (for fear of
> > sounding stupid) that the CPU and RAM can't keep up with what is going on.[/color]
>
> Are you sure it is stuck? Can you output something at each loop to see
> what's happening?
>[color=green]
> > Here's my program:
> >
> > /*Matt Short
> >
> > */
> >
> > #include <iostream>
> > #include <fstream>
> >
> > using namespace std;[/color]
>
> http://www.parashift.com/c++-faq-lit....html#faq-27.5
>[color=green]
> > int main()
> > {
> > const int SIZE = 30; //setting up keywordFile;
> > fstream keywordFile;
> > char input[SIZE];
> >
> > const int LINE = 400; //setting up definition file;
> > fstream defFile;
> > char def[LINE];
> >
> > fstream ansFile; //setting up answer file
> > char ans[LINE];[/color]
>
> For these three blocks:
> 1) use std::string (from <string>)
> 2) don't define an object if you cannot initizalise it
> 3) use either std::ofstream or std::ifstream, not std::fstream (except
> in special cases)
>
> These should therefore be
>
> std::ifstream keywordFile("c:\\keywork.txt");
> std::ifstream defFile("c:\\defFile.txt");
> std::ifstream ansFile("c:\\ansFile.txt");
>
> For the character arrays, see below.
>[color=green]
> > ofstream quizFile("c:\\quizFile.txt"); //setting up final quiz file
> >
> > keywordFile.open("c:\\keyword.txt", ios::in);
> > defFile.open("c:\\defFile.txt", ios::in);
> > ansFile.open("c:\\ansFile.txt", ios::in);[/color]
>
> When you use std::ifstream, ios::in is redundant.
>[color=green]
> > while (!keywordFile.eof())[/color]
>
> You may read past beyond EOF with this. Think: EOF is detected after
> reading, that means ....
>[color=green]
> > {
> > keywordFile.getline(input, SIZE);[/color]
>
> .... here. Oups.
>[color=green]
> > defFile.getline(def, LINE);
> > quizFile << input << endl << def << endl;
> >
> > ansFile.getline(ans, LINE);
> > quizFile << ans << endl;
> >
> > ansFile.getline(ans, LINE);
> > quizFile << ans << endl;
> >
> > ansFile.getline(ans, LINE);
> > quizFile << ans << endl << "0" << endl << endl << endl << endl << endl;[/color]
>
> Now, if you decide to use std::string, these would look like
>
> std::string line;
>
> getline(keywordFile, line);
> quizFile << line << "\n";
>
> getline(defFile, line);
> quizFile << line << "\n";
>
> // ...
>
> Note that outputing std::endl flushes the buffer of the stream, which
> may not be what you want (ie a new line).
>[color=green]
> > }[/color]
>[color=green]
> > keywordFile.close();
> > quizFile.close();
> > ansFile.close();
> > defFile.close();[/color]
>
> Redundant (that's what destructor are for).
>
>
> Jonathan[/color]

Nice tutorial Jonathan! Very good explanations and reasons. Very well
done, I take my hat off to you!

Many thanks.

Daz

Closed Thread