1

I am having some trouble with this program that needs to search an array for a string that the user inputs, and then print the entire line with the matching string. At the moment, this is only partially working as is only prints out the string if there is a match and not the entire line that string is on. Here is the text file with the data.

Murray Jones, 555-1212
Christal Delamater, 555-4587
Zetta Smith, 555-6358
Elia Roy, 555-5841
Delmer Bibb, 555-7444
Smith Nevers, 555-7855
Roselle Gose, 555-3211
Jonathan Basnett, 555-5422
Marcel Earwood, 555-4112
Marina Newton, 555-1212
Magdalen Stephan, 555-3255
Deane Newton, 555-6988
Mariana Smith, 555-7855
Darby Froman, 555-2222
Shonda Kyzer, 555-3333
Jones Netto, 555-1477
Bibone Magnani, 555-4521
Laurena Stiverson, 555-7811
Elouise Muir, 555-9633
Rene Bibb, 555-3255

And here is the code that I have so far. If you could help me out I would appreciate it!

void searchArray(string array[], int size)
{
    string userInput;
    bool found = false;

    cout << "Enter a name to search the data: " << endl;
    cin >> userInput;

    for (int i = 0; i < size; i++)
    {
        if (userInput == array[i])
        {
            found = true;
            cout << endl;
            cout << "Matching Names: " << endl;
            cout << array[i] << endl;
        }
    }
}

Here is the main() that reads the file and puts each line into an array.

int main()
{

    ifstream infile;
    infile.open("Data.txt");

    int numOfEntries = 0;
    string nameAndNumber, line;

    string *namesAndNumbers = nullptr;

    if (!infile)
    {
        cout << "Error opening file.";

        return 0;
    }
    else
    {
        while (getline(infile, line))
        {
            numOfEntries++;
        }

        namesAndNumbers = new string[numOfEntries];

        infile.clear();
        infile.seekg(0, ios::beg);

        int i = 0;

        while (getline(infile, line))
        {
            stringstream ss(line);
            ss >> nameAndNumber;
            namesAndNumbers[i] = nameAndNumber;
            i++;
        }
    }

    cout << "The number of entries in the file is: " << numOfEntries << endl << endl;

    searchArray(namesAndNumbers, numOfEntries);

    delete[] namesAndNumbers;

    return 0;
}
  • Please update your post with the code that reads the input file. – Thomas Matthews Feb 27 '18 at 00:46
  • Okay I've updated the original post. – Corey Shouse Feb 27 '18 at 00:51
  • ss >> nameAndNumber;stringstream delimter is space. In the input file there is a space after the comma in every entry. So it would have tokenized the input wrongly. – mman Feb 27 '18 at 00:56
  • Interesting. What would be the best way to fix this? Just not use the stringstream or something else? – Corey Shouse Feb 27 '18 at 01:00
  • Not sure about your intent here. If you are after a name to number mapping, you could use a stringstream to get the tokens out and store it in a map (or multimap or a similiar structure). [Note: You will get two tokens per line.]. https://stackoverflow.com/questions/236129/the-most-elegant-way-to-iterate-the-words-of-a-string – mman Feb 27 '18 at 01:08
  • Also consider using a vector or other data structure to add elements as they come in, rather than looping through the file twice. – Nick Feb 27 '18 at 01:13
  • I just need the entire line to be stored in a string so when the user searches for a name, the entire line will be printed out. – Corey Shouse Feb 27 '18 at 01:14
  • And thanks Nick, but we are supposed to use arrays only for this. – Corey Shouse Feb 27 '18 at 01:14
  • @CoreyShouse *but we are supposed to use arrays only for this* -- So no curious person raised their hand in the class and asked " what if there are 100,000 names? Read the file twice? What a waste". – PaulMcKenzie Feb 27 '18 at 01:23
  • I agree with you that a vector would be a better way to do this, but the instructors specifications say to use arrays, as we haven't actually gone over vectors yet. – Corey Shouse Feb 27 '18 at 01:27

2 Answers2

0

I recommend you model the input. Treat each line as a record or structure:

struct Record
{
  std::string name;
  std::string phone;
};

The next step is to overload operator>> to read in a record:

struct Record
{
  friend std::istream& operator>>(std::istream& input, Record& r);
  std::string name;
  std::string phone;
};
std::istream& operator>>(std::istream& input, Record& r)
{
  std::getline(input, name, ','); // The ',' is not put in the string.
  std::getline(input, phone);
  return input;
}

The above code allows you to have a simple input loop:

std::vector<Record> database;
Record r;
while (input_file >> r)
{
  database.push_back(r);
}

To find the phone number associated with a name you can search the database:

size_t db_index = 0;
const size_t quantity = database.size();
for (db_index = 0; db_index < quantity; ++db_index)
{
  if (database[index].person == name_to_search)
  {
     Do_Something(index);
     break;
  }
}

There are other alternatives, depending on how you are using the database. For example, you could use std::map if you are only going to search by name or phone. You could also create index tables for name and phone so you don't have to sort the database prior to each search.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
-1

I don't know C++ so sadly I cannot give you a working example of the code, however I can try to point you in the right direction.

I would use something like a StringBuilder (Java) (see C++ equivalent of StringBuffer/StringBuilder?)

Using the StringBuilder, I would read each line of your input text (until a new line character is reached).

Then I would search that line of text for your search query (in this case, the name), and if it finds a match, return the whole line.

V. Kuo
  • 78
  • 2
  • 6