|
 |
|
 |
08-17-2005, 10:13 AM
|
#1 (permalink)
|
|
Scott
Join Date: Aug 2005
Posts: 29
|
c++ input question
I am making a program that randomly selects a word from a text file and scrambles it up so that the user can try to guess it.
I am using the fstream library.
i was wondering if there was any way to send the get pointer to a specific line instead of to a certain number of bytes from the beginning.
here is what i am using:
Code:
dictionary.seekg(wordid);
with wordid being the number of bytes that the chosen word is from the beinning of the file.
In the text file i have a word per line with a semicolon on the end for a deliminator.
What i am using now picks up some of the characters that i use to standardize the word length and sometimes even just parts of the word.
perhaps there is a way that i don't know about that allows be to go by lines or a way to cut out the unwanted characters?
thanks in advance.
Scott
|
|
|
08-17-2005, 04:28 PM
|
#2 (permalink)
|
|
[code][/code] enforcer
Join Date: Mar 2003
Location: Netherlands
Posts: 1,544
|
No you can't do that because a system that skips lines or bytes is not portable. So you have to traverse one way or the other. Use std::get or std::getline.
__________________
|
|
|
08-17-2005, 05:02 PM
|
#3 (permalink)
|
|
Scott
Join Date: Aug 2005
Posts: 29
|
Valmont,
WHat do you mean by not portable?
Also if the text is formatted as above with 28 characters (including spaces) per line how many bytes is a line. Does the new line command take up memory?
thanks
Scott
Last edited by smckittr; 08-17-2005 at 06:21 PM.
|
|
|
08-17-2005, 07:18 PM
|
#4 (permalink)
|
|
Scott
Join Date: Aug 2005
Posts: 29
|
sorry for the multiple posts.
I have figured it out. The actual size of a word inmy program is 31 bytes. apparent;y the end line thingie (very technical term =) ) is two bytes large. that threw my calculations right off. but now i have it.
Thanks for the help.
Scott
|
|
|
08-17-2005, 08:55 PM
|
#5 (permalink)
|
|
Scott
Join Date: Aug 2005
Posts: 29
|
Ok,
As i said before I'm making a program that chooses a random word from a "dictionary" file and then scrambles it up.
Having solved the problem with choosing the word, I began work of the scramble function. I declared it to pass in by reference a character array containing the word and an array to recieve the scrambled result. I wrote the first action of the function and had it print out the unscrambled array to see if it got in.
here is my code:
Code:
#include <fstream>
#include <iostream>
#include <time>
#include <stdlib>
#define wordsize 31
using namespace std;
int chooseword(int);
int getfilesize(ifstream&);
void scramble(char&, char&);
int main()
{
char buffer[30];
char scrambled[30];
int wordid;
int filesize;
int wordcount;
ifstream dictionary("dictionary.txt");
if (!dictionary.is_open())
{
cout << "There was error opening the file dictionary.txt. Please read readme.txt for possible solutions.";
exit(1);
}
filesize=getfilesize(dictionary);
cout << filesize << "\n";
wordid=chooseword(filesize);
cout << wordid << "\n";
dictionary.seekg(wordid);
cout << dictionary.tellg() << "\n";
if (dictionary.good() == false)
{
cout << "You have reached the end of the file. Contact the Developer for support.";
exit(1);
}
dictionary.getline (buffer, 30, ';');
cout << buffer << "\n";
cout << scramble(buffer, scrambled);
return 0;
}
int chooseword(int maxnum)
{
int randnum;
int position;
srand(time(0));
randnum= rand() % maxnum + 1;
position = randnum * wordsize;
return position;
}
int getfilesize(ifstream & dictionary)
{
int n1, n2, bytes, words;
n1=dictionary.tellg();
dictionary.seekg(0, ios::end);
n2= dictionary.tellg();
dictionary.seekg(0, ios::beg);
bytes= n2-n1;
words = bytes/wordsize;
return words;
}
void scramble(char & unscrambled, char & scrambled)
{
cout << unscrambled;
}
i keep getting these errors:
"main.cpp": E2034 Cannot convert 'char *' to 'char' in function main() at line 38
"main.cpp": E2340 Type mismatch in parameter 1 (wanted 'char &', got 'char *') in function main() at line 38
"main.cpp": E2340 Type mismatch in parameter 2 (wanted 'char &', got 'char *') in function main() at line 38
"main.cpp": E2188 Expression syntax in function scramble(char &,char &) at line 67
i'm sure theres something terribly simple that i'm not doing right.
any suggestions?
Thanks
Scott
|
|
|
08-18-2005, 01:08 AM
|
#6 (permalink)
|
|
Newbie
Join Date: Jun 2002
Location: Denmark
Posts: 1,726
|
Code:
void scramble(char & unscrambled, char & scrambled)
This is an illformed definition, you have to alter that to:
Code:
void scramble(char * unscrambled, char * scrambled)
then, when calling the function, you can chose to use
Code:
scramble(&buffer, &scrambled);
|
|
|
08-18-2005, 11:16 AM
|
#7 (permalink)
|
|
Newbie
Join Date: Jun 2002
Location: Denmark
Posts: 1,726
|
Let me just catch up on a few items in this.
Quote:
|
Originally Posted by Valmont
No you can't do that because a system that skips lines or bytes is not portable.
|
Quote:
|
Originally Posted by smckittr
What do you mean by not portable?
|
The thing here is, you can never be sure a char is 4 bits on every system.
If you're planing on searching the way you want to in this perticular program, you need to tell it to seek independant, so if you plan on having every line be 28 chars plus your EOL, you can't even be sure it will be 31*sizeof(char), since some systems, like windows, uses <crlf> as EOL where *nix commonly uses <lf>, which is one char shorter than your requested search.
Another thing, why not use
Code:
void scramble(std::string* unscrambled, std::string* scrambled);
as your scramble function, then you can read everything in with the
Code:
...
...
int count(0), select(0);
std::string buffer;
std::string scrambled;
...
if(select = chooseword(getfilesize(dictionary))){
while(dictionary.good() && count < select){
getline (dictionary, buffer, '\n');
++cout;
}
scramble(&buffer, &scrambled);
}
else
// something
...
Which would make it more system independent.. Only problem that exists in that, would be to decide when select is within the number of available lines in the file.
Last edited by redhead; 08-18-2005 at 12:10 PM.
|
|
|
08-19-2005, 05:15 PM
|
#8 (permalink)
|
|
Scott
Join Date: Aug 2005
Posts: 29
|
Thanks for the tips all,
Redhead,
getline won't accept it if I use string.
the end of file problem is solvedby the getfilesize function.
THanks again.
Scott
|
|
|
08-22-2005, 10:01 PM
|
#9 (permalink)
|
|
Scott
Join Date: Aug 2005
Posts: 29
|
I have another problem now.
i got the program to compile using:
Code:
void compare(char * guess, bool & tryagain, bool & quit)
and this is the code that prompts the user to make a guess and calls compare.
Code:
cout << "What is the word? Type \"quit\" to exit and \"give up\" for the solution: ";
cin >> guess;
compare(guess, tryagain, quit);
the program fails just after the cin statement.
any suggestions?
Thanks
Scott
|
|
|
08-23-2005, 01:44 PM
|
#10 (permalink)
|
|
Newbie
Join Date: Jun 2002
Location: Denmark
Posts: 1,726
|
Code:
void compare(char * guess, bool & tryagain, bool & quit)
again here you're violating the allowed deifnition, you cant use the reference operator in a definition, if you plan on using parse by reference, then you ned to define it as a pointer in your definition, and then call the function with the reference to the variable parsed to it. ie:
Code:
void compare(char * guess, bool * tryagain, bool * quit);
char g[LENGTH];
bool tr, q;
compare(&g, &tr, &q);
Here you tell your compare is handling bool pointers, then when calling it with the arguments you're actualy parsing the reference (memory address) of the variable instead of parsing a copy of it.
So if you planed your function correct you are able to mengle with the value stored in the variables without losing it uppon exit from the function.
I don't know what your guess is, but if it's a char array, then I'd use
Code:
compare(&guess, &tryagain, &quit);
And let the function be defined as
Code:
void compare(char * guess, bool *tryagain, bool *quit);
Parsing it this way, would make the guess available as *guess within your function and the bools available as just tryagain and guess, but looking at this makes me wonder if your orriginal design of the program is optimal for what is it supposed to do, eventho I'm not quite sure what that exactly is.
|
|
|
08-24-2005, 07:02 PM
|
#11 (permalink)
|
|
Scott
Join Date: Aug 2005
Posts: 29
|
I see.
THanks
Scott
|
|
|
08-24-2005, 08:00 PM
|
#12 (permalink)
|
|
[code][/code] enforcer
Join Date: Mar 2003
Location: Netherlands
Posts: 1,544
|
Some unusual code goes on in here. Can you post the complete code as you have it so far?
__________________
|
|
|
08-24-2005, 08:18 PM
|
#13 (permalink)
|
|
Scott
Join Date: Aug 2005
Posts: 29
|
Valmont,
here's the code,
Code:
#include <fstream>
#include <iostream>
#include <time>
#include <stdlib>
using namespace std;
int chooseword(int, int);
int getfilesize(ifstream&);
int getwordsize();
void compare(char*, bool *, bool*);
int main()
{
char buffer[30];
char scrambled[30];
char *guess = "quit";
int wordid;
int filesize;
int wordcount;
int wordsize;
int bytesize;
int i;
bool quit=false;
bool tryagain = true;
ifstream dictionary("dictionary.txt");
if (!dictionary.is_open())
{
cout << "There was error opening the file dictionary.txt. Please read readme.txt for possible solutions.";
exit(1);
}
wordsize=getwordsize();
bytesize=getfilesize(dictionary);
filesize=bytesize/wordsize;
cout << filesize << "\n";
wordid=chooseword(filesize, wordsize);
cout << wordid << "\n";
dictionary.seekg(wordid);
cout << dictionary.tellg() << "\n";
if (dictionary.good() == false)
{
cout << "You have reached the end of the file. Contact the Developer for support.";
exit(1);
}
dictionary.getline (buffer, 30, ';');
cout << buffer << "\n";
dictionary.getline (scrambled, 30, ';');
cout << scrambled << "\n\n";
while (!quit)
{
cout << "Welcome to Word Scramble.\n";
cout << "Your word is: " << scrambled << "\n";
while (tryagain)
{
cout << "What is the word? Type \"quit\" to exit and \"give up\" for the solution: ";
cin >> *guess;
if (guess == "quit")
{
quit =true;
tryagain =false;
continue;
}
if (guess == "give up")
{
cout << "The Word is " << buffer;
tryagain=false;
continue;
}
else
{
compare(guess, &tryagain, &quit);
}
}
}
return 0;
}
int chooseword(int maxnum, int wordsize)
{
int randnum;
int position;
srand(time(0));
randnum= rand() % maxnum + 1;
position = randnum * wordsize;
return position;
}
int getfilesize(ifstream & dictionary)
{
int n1, n2, bytes;
n1=dictionary.tellg();
dictionary.seekg(0, ios::end);
n2= dictionary.tellg();
dictionary.seekg(0, ios::beg);
bytes= n2-n1;
return bytes;
}
int getwordsize()
{
ifstream wordtest("wordtest.txt");
return getfilesize(wordtest);
}
void compare(char * guess, bool * tryagain, bool * quit)
{
cout <<"did this work?";
*quit=true;
*tryagain=false;
}
Now it all works except for the fact that if you type "quit" or "give up" it still executes compare. I'm also thinking of replacing the if statements with a switch statement.
Scott
|
|
|
08-24-2005, 10:23 PM
|
#14 (permalink)
|
|
[code][/code] enforcer
Join Date: Mar 2003
Location: Netherlands
Posts: 1,544
|
I'm thinking of replacing a lot more. Since every word has it's own line, you don't need the word size. You only need how many lines there are for the random word choser. There is no way to calculate the number of lines in a portable way so we need to traverse every line once until EOF is reach. While finding a new line we increment a line counter and pass that counter to the random choser. That's all we need.
__________________
|
|
|
08-24-2005, 11:33 PM
|
#15 (permalink)
|
|
[code][/code] enforcer
Join Date: Mar 2003
Location: Netherlands
Posts: 1,544
|
Anyway here's some code. See if you can uphold this style while implementing the game loop and the scrambler/descrambler. Also mind that you don't need a ";" in your wordfile. Just place a word on every line. That's it. You don't need a second file either anymore.
Code:
#include <fstream>
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <string>
unsigned choose_word(unsigned);
unsigned calculate_lines(std::ifstream&);
std::string fetch_word(std::ifstream&, unsigned);
int main()
{
std::string sWord;
std::string sGuess = "quit";
unsigned nLines(0);
std::ifstream dictionary("dictionary.txt");
if (!dictionary)
{
std::cout << "ERROR: There was error opening the file dictionary.txt." << std::endl;
std::cout<< "Please read readme.txt for possible solutions." << std::endl;
std::cout<< "Terminating program...";
exit(1);
}
//Let's first determine how many words there are.
nLines = calculate_lines(dictionary);
//We know how many words there are, so let's choose a random word line.
unsigned RandomLine;
RandomLine = choose_word(nLines);
//We know which line to pick. So let's retreive the word on that line.
sWord = fetch_word(dictionary, RandomLine);
//What we got?
std::cout<<sWord<<std::endl;
return 0;
}
//---------------------------------------------------
//So how many lines (=words) has this file?
unsigned calculate_lines(std::ifstream& dict)
{
unsigned lns(0);
std::string sBuffer;
while( std::getline(dict, sBuffer) )
{
++lns;
}
//Did something went wrong during the read of this stream?
if(!dict.eof())
{
//Yep, something went wrong. Ring the alarms!
std::cout<<"ERROR: something went wrong during file reading.";
dict.close();
std::cout<<"exiting app...";
}
//Do not forget to reset the state of the dictionary file object since it is
//in a error state due to EOF.
dict.clear();
//And let the file pointer point to the beginning as it was before all this.
dict.seekg(0, std::ios::beg);
return lns;
}
//---------------------------------------------------
unsigned choose_word(unsigned maxnum)
{
unsigned randnum;
std::srand(std::time(0));
randnum= std::rand() % maxnum + 1;
return randnum;
}
//----------------------------------------------------
std::string fetch_word(std::ifstream& dict, unsigned line)
{
std::string buffer;
while( std::getline(dict, buffer) && line != 1)
{
--line;
}
//Do not forget to reset the state of the dictionary file object since it is
//in a error state due to EOF.
dict.clear();
//And let the file pointer point to the beginning as it was before all this.
dict.seekg(0, std::ios::beg);
return buffer;
}
__________________
|
|
|
| Thread Tools |
|
|
| Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -8. The time now is 06:08 AM.
|
Copyright © 2000-2008, Milano Interactive
Web Hosting provided by Portal 360 Web Hosting
|
 |
|