Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Search Function

Status
Not open for further replies.

heyrey

Technical User
Dec 18, 2001
8
US
I wrote a program in C++ to enter First Name, Last Name and Telephone Extension into a file. How do I write the code to search for a specific name and return the information? I have not beeb able to found a codes that gives me that example. Can anyone please help!!

Rey
 
Read the file into an array structure, then loop through the array using the CString member function "Find()" or the C function "strstr()" to check the structure fields to see if they contain a match for the portion of the string you're looking for. Here's a very simplified example showing what to do after you have read the file into MyStruct:

Code:
// First:
//   fill MyStructure from the file on disk
//   set iMaxStructureSize to the number of records

CString sNickName;
char sNickNameTwo[80];
int iFoundIndex = -1;
int i;

for (i = 0; i < iMaxStructureSize; i++)
{
  // copied only to simplify the Find() syntax
  sNickName = MyStruct[i].sNickName;

  if (sNickName.Find(&quot;HeyRey&quot;) != -1)
  {
    // you found it.
    iFoundIndex = i;
    break;
  }

// or:

  // copied only to simplify the strstr() syntax
  strcpy(sNickNameTwo, MyStruct[i].sNickName);

  if (strstr(sNickNameTwo, &quot;HeyRey&quot;) != NULL)
  {
    // you found it.
    iFoundIndex = i;
    break;
  }
}

if (iFoundIndex >= 0)
{
  // use MyStruct[iFoundIndex].sNickName or whatever...
}
 
Thanks, I will give it a try. I am new to this so I hope it works.
 
Will this code return random names from my file?

Example:

cout <<&quot;Please enter name of person's information you want: &quot;;

cin << ssearch;

cout <<&quot;That person's telephone extension is &quot; << sextension << endl;

Rey
 
> Will this code return random names from my file?

Two things:

1) Be careful about the direction of your operators: >> and <<

2) you will need to compare one string at a time, either last name, first name, or whatever. So either ask the user to enter the first name and then ask for the last name, or be prepared to parse the single string looking for the space character so you can split it up yourself.

The string(s) they input must match some portion of the field strings EXACTLY or the comparison will fail. Remember that the case (caps/small) may be significant in the search results too (HeyRey may not match HEYREY). You can temporarily convert the text of both the user input and the record's fields to UPPERCASE or lowercase before doing the comparison, if you like.

Anyway, hope this helps.
 
I see what you mean about the operators. I do not see in the code where you prompt the user to enter the information, so they can get what they are looking for from the file
 
Here's the routine showing the user input prompts, skipping the part where you read the file to fill the array, but showing the comparisons. I did a &quot;non-destructive&quot; conversion to upper characters on the record data, since you may want to print these values later and all upper case could look stupid. I hope this works without bugs because I did it in my head and didn't compile it. I know there are opportunities to make function routines in this code, but I put everything &quot;inline&quot; to make it easier for you to follow what's happening. I hope this example answers your questions.

Code:
char sInputString[512];
char sFirstName[512];
char sLastName[512];

int iFoundIndex = -1;
int i;
int j;


/* Ask the user to input any values you want to compare */

cout << &quot;Please enter the person's First name: &quot;;
cin >> sInputString;

/* convert all characters to upper case */
for (j = 0; j < strlen(sInputString); j++) 
{
  sFirstName[j] = toupper(&sInputString[j]);
}

/* append a null character */
sFirstName[j] = '\0';


cout << &quot;Please enter the person's Last name: &quot;;
cin >> sInputString;

/* convert all characters to upper case */
for (j = 0; j < strlen(sInputString); j++) 
{
  sLastName[j] = toupper(&sInputString[j]);
}

/* append a null character */
sLastName[j] = '\0';


/*
 * Fill your structure and set MaxStructureSize
 * before continuing!
 */


/* Now look for the right record */
for (i = 0; i < iMaxStructureSize; i++)
{
  /* convert all characters to upper case */
  for (j = 0; j < strlen(MyStruct[i].sFirstName); j++) 
  {
    sWorkString[j] = toupper(&sMyStruct[i].sFirstName[j]);
  }

  /* append a null character */
  sWorkString[j] = '\0';

  if (strstr(sWorkString, sFirstName) != NULL)
  {
    // you found the first name, now check the last name

    /* convert all characters to upper case */
    for (j = 0; j < strlen(MyStruct[i].sLastName); j++) 
    {
      sWorkString[j] = toupper(&sMyStruct[i].sLastName[j]);
    }

    /* append a null character */
    sWorkString[j] = '\0';

    if (strstr(sWorkString, sLastName) != NULL)
    {
      // you found the last name, set flag and exit loop
      iFoundIndex = i;
      break;
    }
  }
}

if (iFoundIndex >= 0)
{
  // use MyStruct[iFoundIndex].sLastName or whatever...
}
 
One caveat:

This implementation will always find only the *first* record that matches the user's input. For example:

Record data:
---------------
John Smith
Dave Brownstone
Dave Brown
Sue Green

User input:
---------------
First Name: Dave
Last Name: Brown

Search Result:
---------------
First Name: Dave
Last Name: Brownstone

To solve this, you can instead look for an exact match by using the strcmp() function, as follows:

if (!strcmp(sWorkString, sFirstName)) {
// found first name
}

However, by doing this, the user will no longer get a result when they enter only part of a name.

And there's still a problem... what if two people share the same exact name (i.e. Dave Brown)? If that's a possibility, you may need some other identifying field to compare (i.e. employee number).

Anyway, just some things for you to think about...
 
Well, I have tried the code above and I still cannot get my search function to retrieve data. Here it is can anyone give me any suggetions? This is actually the last part of my struct.

void search()
{
//declare variables
phoneBook clients[3];
string search = &quot; &quot;;


{
//create file object and open file
ifstream inFile;
inFile.open(&quot;PhoneNumber.dat&quot;, ios::in);

bool found = false;
int i = 0;

//determine if file opened successfully
if (!inFile.is_open())
cerr <<&quot;Unable to open File.&quot;<< endl;

cout << &quot;Enter First Name for Search: &quot;;
cin >> search;


{
while (!inFile.eof() && i < 3)
{
getline(inFile,clients.fName + ' ');
getline(inFile,clients.lName + &quot;#&quot;);
getline(inFile,clients.exten);
i++;
inFile.ignore(0);
if (search == clients.fName)
{
found = true;
cout << &quot;Search = &quot; << clients.fName << ' ' << clients.lName;
cout << &quot;#&quot; << clients.exten << endl;
}//end while


}

//close file
inFile.close();
}if(found == false) //display message if name not found
cerr << &quot;Client Entered ** NOT FOUND **.&quot;<< endl;

}


}//end search
 
Two things:

1) when posting, to prevent part of your code from being translated into italics or other formatting, enclose your code with these tags:

[
Code:
code]

    // your program code goes here

  [
/code]

(leave the checkbox checked, but click the Process TGML link below the message posting edit window for more guidelines)

2) if your struct members (i.e. fName) are defined as char data types, don't compare using == but use strcmp() instead.
 
My struct members are strings. Actually I got it to work by changing the quotes around the delimiters from double quotes to single quotes. Now I get an error stating &quot;the istructions at &quot;0x00405640&quot; referenced memory at &quot;0x0044ec8d&quot;.&quot; The memory could not be &quot;written&quot;. Do you know what this means?
 
Your program is attempting to use memory locations outside of the memory that you allocated.

As a general rule, when something like this happens, you either can use a debugger to step through the part of your code where the problem may be occurring to see exactly where it is failing, or you can add print statements throughout your code, printing the value of your variables and / or indexes.

In your while() loop, I don't see where your index (i) is used. See my note above about using the [
Code:
code] tag when you post.
 
Actually I did use
Code:
index[i]
between clients and fName, lName, and exten but when I posted the message it removed it from my code.
 
So, it looks like you now know how to use the [
Code:
code] [
/code] tags. Try my suggestion regarding adding print statements when you debug so you know where the program is failing.
 
Thanks for all your help and responding so quickly. I was able to get the program to work fine by reducing the
Code:
 (i <= 3) to (i<=2) and keeping my MAX Length at 3
. The program will cerr any message I want if the user goes over the number of searches I have set.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top