Register FAQ / Rules Forum Spy Search Today's Posts Mark Forums Read
Go Back   MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Reply
 
Thread Tools Search this Thread Display Modes
Old Apr 18, 2011, 10:53 AM   #1
chunhohuen
macrumors newbie
 
Join Date: Apr 2011
C++ new hand problem please help

Dear alls
I am a extremely new hand of c++ user.
Thus, I wish I can get some help in here.


I am writing a program to input a name and save in a file.
However, my problem is I want to write a function to find the worlds and show it inside the file.

For example:
I input some data like Peter, May and Joe.
Then after write and read, when the user input Peter and run the function find(), it can search the file and show Peter if Peter is existed, else run the function setuser() and let the user input the name.

My problem is I do not know how to write the function find() by using if else.....

Thank you for all the attentions!

Here is my program:
Code:
#include <iostream>
#include <fstream>
#include <string.h>
using namespace std;


char inputusername[99];// let the user to input the user name

void find();


void setuser() //function of set the username
{
	cout<<"Enter the username: "<<endl;
	cin>>inputusername;
	int score=0;
}


void read() //read the file and show the details
{
	cout<<endl;
	ifstream fin("file.cpp");
	char ch;
	while (fin.get(ch))
		cout<<ch;
	fin.close();
}



void write() //read the input to the file
{
	ofstream fout ("file.cpp",ios::app);
	fout<<inputusername<<endl;
	fout.close();
}



void find()// find the input either is match the file
	       // if yes, cout the data
		   // if not, run the function setuser()
{
	ifstream fin("file.cpp");
	char *search;

}


int main()
{

int choice=0, number=0;

bool entered=false;
do {
cout <<endl;
cout << "Please choose an option below:\n\n";
cout << "1. input\n";
cout << "2. write\n";
cout << "3. read\n";
cout << "4. find\n";
cout << "5. Quit\n";
cin >> choice;


switch(choice) {
case (1) : { setuser();break;}


case (2) : {write(); break; }


case (3) : { read(); break; }


case (4) : { find(); break; }


case (5) : { break; }




}
}
while(choice != 5);

return 0;
}

Last edited by kainjow; Apr 18, 2011 at 10:44 PM. Reason: code tags
chunhohuen is offline   0 Reply With Quote
Old Apr 18, 2011, 11:24 AM   #2
subsonix
macrumors 68030
 
Join Date: Feb 2008
Although it is possible to search "on the disk" what you want is to read in all data in memory and do the search there because disk i/o is slow and hard to manage. So, read in all data into a data structure like a vector. Then you can iterate through the vector linearly and compare each index to the search term, if it's found return, else report not found.

Hope I got the question BTW, not sure.
subsonix is offline   0 Reply With Quote
Old Apr 19, 2011, 05:30 AM   #3
chunhohuen
Thread Starter
macrumors newbie
 
Join Date: Apr 2011
Quote:
Originally Posted by subsonix View Post
Although it is possible to search "on the disk" what you want is to read in all data in memory and do the search there because disk i/o is slow and hard to manage. So, read in all data into a data structure like a vector. Then you can iterate through the vector linearly and compare each index to the search term, if it's found return, else report not found.

Hope I got the question BTW, not sure.
Thank you for answering me
I am sorry, I dont' know how to compare each index to the search term.........
chunhohuen is offline   0 Reply With Quote
Old Apr 19, 2011, 06:35 AM   #4
Sander
macrumors 6502
 
Join Date: Apr 2008
Don't call your data file "file.cpp" - it's not a C++ file. From the fact you mention "score" in your code, I think you're trying to make a high-score list? Subsonix is right; unless your data is really big, just load the entire thing in memory and perform the search there.

If it is indeed a high score list, look into the std::map data structure, which you could use to store the name-score pairs. It's really simple to look things up in there as well.

Not spelling out the solution for you in case this is a homework assignment
Sander is offline   0 Reply With Quote
Old Apr 19, 2011, 08:08 AM   #5
ehoui
macrumors regular
 
Join Date: Jan 2011
Quote:
Originally Posted by subsonix View Post
Although it is possible to search "on the disk" what you want is to read in all data in memory and do the search there because disk i/o is slow and hard to manage. So, read in all data into a data structure like a vector. Then you can iterate through the vector linearly and compare each index to the search term, if it's found return, else report not found.

Hope I got the question BTW, not sure.
While that may be true, that approach doesn't scale for large files, but in any event, I think your recommended approach may not be the simplest method which the OP should try first before moving onto more advanced concepts like indices.

OP: based on your write() command, your file structure is essentially user names appearing on a single line in a text file. E.g.,
Code:
John
Mark
Amy
...
Mark
Mark
A couple of problems with your write(), as illustrated by the last two lines above, is that it appears possible to write the same user name multiple times in your file. I don't know if that is unintentional or not. In any case, your find will need to do this:

Code:
while file still has unread lines:
   read a line
   compare the read line with the inputted line
   if they are the same, print it
I didn't write the code, because I assume you'd be interested in learning how to do each of those above. You'll find plenty of examples online on how to read a text file in line-by-line and you'll find plenty of examples on how to compare strings. I think you'll be able to construct your find() command by referring to those examples, writing the code, and debugging it until it works.
ehoui is offline   0 Reply With Quote
Old Apr 19, 2011, 08:21 AM   #6
subsonix
macrumors 68030
 
Join Date: Feb 2008
Quote:
Originally Posted by ehoui View Post
While that may be true, that approach doesn't scale for large files, but in any event, I think your recommended approach may not be the simplest method which the OP should try first before moving onto more advanced concepts like indices.
I does if you read in data in chunks: "if not found in current chunk" move on to the next etc.

Although, one could say that even if you are reading "one line at a time" from the file, your reading from a buffer, so in effect you are searching in memory but in a harder to manage way.

What I mean is, you need to consider things like flush, sync and rewind operations, not to mention if you want to add functionality like the ability to remove items from the file, sort it etc.

BTW, one benefit of using a map that was mentioned, is that it has a find function.
subsonix is offline   0 Reply With Quote
Old Apr 19, 2011, 11:15 AM   #7
ehoui
macrumors regular
 
Join Date: Jan 2011
Quote:
Originally Posted by subsonix View Post
BTW, one benefit of using a map that was mentioned, is that it has a find function.
How about the OP first try to read and compare one line at a time and then progress to a map if s/he is successful?
ehoui is offline   0 Reply With Quote
Old Apr 19, 2011, 11:29 AM   #8
subsonix
macrumors 68030
 
Join Date: Feb 2008
Quote:
Originally Posted by ehoui View Post
How about the OP first try to read and compare one line at a time and then progress to a map if s/he is successful?
What is the most simple depends on if this is just names or key/value pairs like in a high score list that was mentioned. Doing this by hand, parsing strings, validating them, search a data structure manually, seems harder than using a pre-defined function in STL.

I agree that reading a line at a time from a file is the most simple if that is all. But here there seems to be a menu involved, with ability to add, and search for items. So, open the file in append mode, add item, flush the buffer to disk, rewind, or (file.seekg(0, ios::beg) before searching.
subsonix is offline   0 Reply With Quote
Old Apr 19, 2011, 11:39 AM   #9
ehoui
macrumors regular
 
Join Date: Jan 2011
Quote:
Originally Posted by subsonix View Post
What is the most simple depends on if this is just names or key/value pairs like in a high score list that was mentioned. Doing this by hand, parsing strings, validating them, search a data structure manually, seems harder than using a pre-defined function in STL.

I agree that reading a line at a time from a file is the most simple if that is all. But here there seems to be a menu involved, with ability to add, and search for items. So, open the file in append mode, add item, flush the buffer to disk, rewind, or (file.seekg(0, ios::beg) before searching.
Look at the OP's code. The OP needs to start simple. I'm not going to debate you with your suggested improvements. But if the OP can't read a file one line at a time and compare, s/he can't read a file into a map and use the find method.

Why not have the OP link in a btree library or store and retrieve info from a DB (e.g., sqlite) and use that...? Because s/he probably can't at this stage and leading them down this path will result in frustration and further confusion.
ehoui is offline   0 Reply With Quote
Old Apr 19, 2011, 11:52 AM   #10
subsonix
macrumors 68030
 
Join Date: Feb 2008
Ok it's a valid and good point. Then store the search term in a string, read one line at a time into a temporary string and compare them.

The string class has a compare() function which returns 0 on a match.

http://www.cplusplus.com/reference/s...tring/compare/

And a fstream object can be used like this:

Code:
while( file >> string ) {
     // compare here, break if found
}
Which will effectively read from the file one line at the time, until there is nothing more to read.
subsonix is offline   0 Reply With Quote
Old Apr 21, 2011, 10:43 AM   #11
chunhohuen
Thread Starter
macrumors newbie
 
Join Date: Apr 2011
THX all the reply!

Now
I write the find function as:

void find()
{
string str1 (file.txt);
string str2 (inputusername);

if (str1.compare(str2) != 0)
cout << str1;
}

However, it can not run.....

What I want to do are:

1.Set str1 as the file.txt
2.Set str2 as inputusername
3. Use a if statement to find the inputerusername information in the file.txt
4.cout the match content of file.txt
chunhohuen is offline   0 Reply With Quote
Old Apr 21, 2011, 11:02 AM   #12
subsonix
macrumors 68030
 
Join Date: Feb 2008
Just like in your first version of find() in your first post, you need to open the file for reading. That is, the file.txt should be opened for reading.

You then need to ask for a search term (in your case a user name).

Code:
ifstream file;
file.open("file.txt);

string inputusername;
string input_line;

cout << "What name do you want to search for? ";
cin >> inputusername;

while( file >> input_line ) {
    if( input_line.compare(inputusername) == 0 ) {
        cout << "The name " << input_line << " was found in file.\n";
        break;
    }
}

file.close();
subsonix is offline   0 Reply With Quote
Old Apr 21, 2011, 12:13 PM   #13
chunhohuen
Thread Starter
macrumors newbie
 
Join Date: Apr 2011
Quote:
Originally Posted by subsonix View Post
Just like in your first version of find() in your first post, you need to open the file for reading. That is, the file.txt should be opened for reading.

You then need to ask for a search term (in your case a user name).

Code:
ifstream file;
file.open("file.txt);

string inputusername;
string input_line;

cout << "What name do you want to search for? ";
cin >> inputusername;

while( file >> input_line ) {
    if( input_line.compare(inputusername) == 0 ) {
        cout << "The name " << input_line << " was found in file.\n";
        break;
    }
}

file.close();
Thank you very much!

I can do the search now and learn a lot but I rewrite the function and there is a problem.

for example the txt file is included:
peter
may
joe


1.The user selects 1.setuser() and input peter. Then select 4.find(), it can show peter on the screen.

2.When the user selects 1 again and input may.

3.Use find() cannot show may but the not found message (I write else statement to test the function.

The problem is :How to search all the content in the txt file?


The code:

Code:
void find()

{

ifstream file;
file.open("file.txt");

string input=inputusername;
string input_line;

while( file >> input_line ) {
    if( input_line.compare(input) == 0 ) {
        cout << "The name " << input_line << " was found in file.\n";
        break;
    }

	else // Testing the name is existed or not.
	cout<<"The name cannot found"<<endl;
	break;

}

Last edited by kainjow; Apr 22, 2011 at 12:27 AM. Reason: code tags
chunhohuen is offline   0 Reply With Quote
Old Apr 21, 2011, 12:38 PM   #14
subsonix
macrumors 68030
 
Join Date: Feb 2008
Quote:
Originally Posted by chunhohuen View Post
1.The user selects 1.setuser() and input peter. Then select 4.find(), it can show peter on the screen.

2.When the user selects 1 again and input may.

3.Use find() cannot show may but the not found message (I write else statement to test the function.

The problem is :How to search all the content in the txt file?


The code:
Code:
void find()

{

ifstream file;
file.open("file.txt");

string input=inputusername;
string input_line;

while( file >> input_line ) {
    if( input_line.compare(input) == 0 ) {
        cout << "The name " << input_line << " was found in file.\n";
        break;
    }
    else { // Testing the name is existed or not.
	cout<<"The name cannot found"<<endl;
	break;
    }
}
That will not work, as that part will be executed every time the lines doesn't match. So, all lines that doesn't match will trigger the else part. (I added braces { } BTW)

What you need to do is to use a flag, that you set to true if found, then after the loop, test if found == false, if so print the message.

Code:
ifstream file;
file.open("file.txt");

string input=inputusername;
string input_line;
bool found = false;

while( file >> input_line ) {
    if( input_line.compare(input) == 0 ) {
        cout << "The name " << input_line << " was found in file.\n";
        found = true;
        break;
    }
}

if( found == false ) {
    cout << "The name " << inputusername << " wasn't found in file.\n";
}

file.close();

Edit:

BTW I see that inputusername is a global variable, that is also a char array. It's better to declare it as string, as it's supported by C++. And preferably it shouldn't be a global variable. Now your find() function takes no arguments, it's better to take a string as argument, (the search term) so you would declare it like this:

Code:
void find(string search_term) {
    // use the search_term that you supply when calling find.
}

// Then in main when you use your function you can call it like this

find("John");

// Or use a variable like userinputname or something else.

Last edited by subsonix; Apr 21, 2011 at 12:49 PM.
subsonix is offline   0 Reply With Quote
Old Apr 22, 2011, 01:43 AM   #15
chunhohuen
Thread Starter
macrumors newbie
 
Join Date: Apr 2011
Quote:
Originally Posted by subsonix View Post
That will not work, as that part will be executed every time the lines doesn't match. So, all lines that doesn't match will trigger the else part. (I added braces { } BTW)

What you need to do is to use a flag, that you set to true if found, then after the loop, test if found == false, if so print the message.

Code:
ifstream file;
file.open("file.txt");

string input=inputusername;
string input_line;
bool found = false;

while( file >> input_line ) {
    if( input_line.compare(input) == 0 ) {
        cout << "The name " << input_line << " was found in file.\n";
        found = true;
        break;
    }
}

if( found == false ) {
    cout << "The name " << inputusername << " wasn't found in file.\n";
}

file.close();

Edit:

BTW I see that inputusername is a global variable, that is also a char array. It's better to declare it as string, as it's supported by C++. And preferably it shouldn't be a global variable. Now your find() function takes no arguments, it's better to take a string as argument, (the search term) so you would declare it like this:

Code:
void find(string search_term) {
    // use the search_term that you supply when calling find.
}

// Then in main when you use your function you can call it like this

find("John");

// Or use a variable like userinputname or something else.
Thankyou very much!
I learn a lot and I can use the function now.
chunhohuen is offline   0 Reply With Quote

Reply
MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Similar Threads
thread Thread Starter Forum Replies Last Post
5s in hand joshs2000ss iPhone 0 Sep 20, 2013 10:32 AM
Second hand Macbook aluminum ML problem LimeLizard MacBook 7 Apr 27, 2013 12:25 PM

Forum Jump

All times are GMT -5. The time now is 09:19 AM.

Mac Rumors | Mac | iPhone | iPhone Game Reviews | iPhone Apps

Mobile Version | Fixed | Fluid | Fluid HD
Copyright 2002-2013, MacRumors.com, LLC