Code Newbie
News     Forums     Search     Members     Sign Up    

My Code Newbie
Username

Password

Articles/Snippets
ASP Classic
ASP.NET
C
C#
C++
HTML / CSS
Java
Javascript
Linux / BSD
Perl
PHP
Python
Ruby
SQL
VB 6
VB.NET

C.N. Friends
  Planet Rome

Link to Us!
Code Newbie
  Code Newbie
    forums
Old 08-17-2005, 10:13 AM   #1 (permalink)
smckittr
Scott
 
Join Date: Aug 2005
Posts: 29
smckittr is on a distinguished road
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.
Code:
word;                      /
word;                      /
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
smckittr is offline   Reply With Quote
Old 08-17-2005, 04:28 PM   #2 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,544
Valmont is on a distinguished road
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.
__________________
Valmont is offline   Reply With Quote
Old 08-17-2005, 05:02 PM   #3 (permalink)
smckittr
Scott
 
Join Date: Aug 2005
Posts: 29
smckittr is on a distinguished road
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.
smckittr is offline   Reply With Quote
Old 08-17-2005, 07:18 PM   #4 (permalink)
smckittr
Scott
 
Join Date: Aug 2005
Posts: 29
smckittr is on a distinguished road
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
smckittr is offline   Reply With Quote
Old 08-17-2005, 08:55 PM   #5 (permalink)
smckittr
Scott
 
Join Date: Aug 2005
Posts: 29
smckittr is on a distinguished road
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
smckittr is offline   Reply With Quote
Old 08-18-2005, 01:08 AM   #6 (permalink)
redhead
Newbie
 
redhead's Avatar
 
Join Date: Jun 2002
Location: Denmark
Posts: 1,726
redhead is on a distinguished road
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);
__________________
Don't worry Ma'am, We're university students, We know what We're doing.
-----
If you pull the pin, Mr.Grenade would no longer be your friend.
-----
01000111 01101111 00100000 01000011 00100000 00100001
redhead is offline   Reply With Quote
Old 08-18-2005, 11:16 AM   #7 (permalink)
redhead
Newbie
 
redhead's Avatar
 
Join Date: Jun 2002
Location: Denmark
Posts: 1,726
redhead is on a distinguished road
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.
__________________
Don't worry Ma'am, We're university students, We know what We're doing.
-----
If you pull the pin, Mr.Grenade would no longer be your friend.
-----
01000111 01101111 00100000 01000011 00100000 00100001

Last edited by redhead; 08-18-2005 at 12:10 PM.
redhead is offline   Reply With Quote
Old 08-19-2005, 05:15 PM   #8 (permalink)
smckittr
Scott
 
Join Date: Aug 2005
Posts: 29
smckittr is on a distinguished road
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
smckittr is offline   Reply With Quote
Old 08-22-2005, 10:01 PM   #9 (permalink)
smckittr
Scott
 
Join Date: Aug 2005
Posts: 29
smckittr is on a distinguished road
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
smckittr is offline   Reply With Quote
Old 08-23-2005, 01:44 PM   #10 (permalink)
redhead
Newbie
 
redhead's Avatar
 
Join Date: Jun 2002
Location: Denmark
Posts: 1,726
redhead is on a distinguished road
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.
__________________
Don't worry Ma'am, We're university students, We know what We're doing.
-----
If you pull the pin, Mr.Grenade would no longer be your friend.
-----
01000111 01101111 00100000 01000011 00100000 00100001
redhead is offline   Reply With Quote
Old 08-24-2005, 07:02 PM   #11 (permalink)
smckittr
Scott
 
Join Date: Aug 2005
Posts: 29
smckittr is on a distinguished road
I see.
THanks
Scott
smckittr is offline   Reply With Quote
Old 08-24-2005, 08:00 PM   #12 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,544
Valmont is on a distinguished road
Some unusual code goes on in here. Can you post the complete code as you have it so far?
__________________
Valmont is offline   Reply With Quote
Old 08-24-2005, 08:18 PM   #13 (permalink)
smckittr
Scott
 
Join Date: Aug 2005
Posts: 29
smckittr is on a distinguished road
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
smckittr is offline   Reply With Quote
Old 08-24-2005, 10:23 PM   #14 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,544
Valmont is on a distinguished road
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.
__________________
Valmont is offline   Reply With Quote
Old 08-24-2005, 11:33 PM   #15 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,544
Valmont is on a distinguished road
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;
}
__________________
Valmont is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
c compiling simple question if13121 Standard C, C++ 1 11-12-2004 06:34 AM
simple question 'bout compiling c program if13121 Platform/API C++ 0 11-09-2004 11:36 PM
c simple question problem with switch case if13121 Standard C, C++ 1 10-24-2004 10:43 PM
simple c question if13121 Standard C, C++ 3 10-18-2004 11:20 PM


All times are GMT -8. The time now is 06:08 AM.


Powered by vBulletin® Version 3.7.0
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.0.0 RC8





Copyright © 2000-2008, Milano Interactive
Web Hosting provided by Portal 360 Web Hosting