I'm creating a program that takes in a string sentence or a paragraph.
I am not quite familiar with using std::
I'm not asking for someone to do it for me, I am just wanting to see if someone can show me an example of this.
When the 4th choice (“Split Words”) is selected, the words should be put into an array or a structure and each word should be displayed with a loop. After this, duplicate removal should be performed and the program must determine the duplicate words and eliminate them. After this, the word list should be printed again.
Any help with this would be greatly appreciated. Thank you
Code: (I need help with case 'D')
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <string>
#include <algorithm>
#include <cctype>
using namespace std;
int main()
{
string s;
char selection;
string w;
cout << "Enter a paragraph or a sentence : " ;
getline(cin, s);
int sizeOfString = s.length();
//cout << "The paragraph has " << sizeOfString << " characters. " << endl; ***Dummy call to see if size works.
//cout << "You entered " << s << endl; *** Dummy function !!
cout << "" << endl;
cout << " Menu " << endl;
cout <<" ------------------------" << endl;
cout << "" << endl;
cout << "A -- Convert paragraph to all caps " << endl;
cout << "B -- Convert paragraph to all lowercase " << endl;
cout << "C -- Delete whitespaces " << endl;
cout << "D -- Split words & remove duplicates " << endl;
cout << "E -- Search a certain word " << endl;
cout << "" << endl;
cout << "Please select one of the above: " ;
cin >> selection;
cout << "" << endl;
switch (selection) //Switch statement
{
case 'a':
case 'A': cout << "You chose to convert the paragraph to all uppercase" << endl;
cout << "" << endl;
for(int i=0; s[i]!='\0'; i++)
{
s[i]=toupper(s[i]);
}
cout << "This is it: " << s << endl;
break;
case 'b':
case 'B': cout << "You chose to convert the paragragh to all lowercase" << endl;
cout << "" << endl;
for (int i=0; s[i] !='\0'; i++)
{
s[i]=tolower(s[i]);
}
cout << "This is it: " << s << endl;
break;
case 'c':
case 'C': cout << "You chose to delete the whitespaces in the paragraph" << endl;
cout << "" << endl;
for(int i=0; i<s.length(); i++)
if(s[i] == ' ') s.erase(i,1);
cout <<"This is it: " << s << endl;
break;
case 'd':
case 'D': cout << "You chose to split the words & remove the duplicates in the paragraph" << endl;
cout << "" << endl;
case 'e':
case 'E': cout << "You chose to search for a certain word in the paragraph. " << endl;
cout << "" << endl;
cout << "Enter the word you want to search for: ";
cin >> w;
s.find(w);
if ( s.find( w ) != std::string::npos )
{
cout << w << " was found in the paragraph. " << endl;
}
else
{
cout << w << " was not found in the paragraph. " << endl;
}
}
return 0;
}
Write code that parses words out of the string s (Here's one method: Split a string in C++?). Print the words as you parse them and then put them in some sort of set container. A set container does not allow duplicates. Once done parsing words, iterate over the set and print the words out (there won't be duplicates).
If you need to print out the de-duped words in the order they appeared in the string, then you could keep a vector alongside the set. Like before, as you parse the words add them to the set but inspect the returned pair from the set's insert() method (it can tell you whether the inserted item was new to the set or if the insert operation was denied because the set already contained a value that was equal to the one you tried to insert: http://www.cplusplus.com/reference/set/set/insert/).
std:vector<std:string> wordVector; // Assume populated with raw parsed words
std:set<std:string> deDupedSet;
std:vector<std:string> deDupedVector;
for (int i = 0; i < wordVector.size(); i++)
{
if (deDupedSet.insert(wordVector[i]).second())
{
deDupedVector.push_back(wordVector[i]);
{
}
// Print the deDupedVector afterwards
Related
I'm working on a self-imposed practice exercise. The parameters are that I allow the user to enter a name that is stored in a vector. Printing the list of names in the vector gives you the position of each name. You can choose to encrypt a name in the list by providing the name's position. Encryption compares each letter in the name with another string that is the allowed alphabet for names. When it finds the letter in the alphabet, it pulls a corresponding character from another string of random characters and assigns the new character to the same position.
Using a range based for loop I almost got it to work. By adding output statements I can see the code correctly comparing the characters of a name to the allowed alphabet and finding the corresponding value in the encryption key. However when the loop is complete and I print the list of names again, the characters in the name to be encrypted are unchanged.
Trying to troubleshoot the issue, I have commented out the range based for loop and tried to do the same thing with a traditional for loop. With this code I get and error during encryption:
Position 1 A is the same as #
terminate called after throwing an instance of 'std::out_of_range'
what(): vector::_M_range_check: __n (which is 26) >= this->size() (which is 2)
The "Position 1 A is the same as #" line is a debug output that I added to show that the code is able to find the correct string, a letter in the string, and the corresponding letter in they key.
Any help in understanding why I get those errors would be appreciated.
Here's my code:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
// Declare strings for Encryption and Decryption
string alphabet {"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ "};
string key {"mnbvfghytcqwi1234567890`~!##$%^&*()-=_+[]\{}|;':,./<>?"};
//Declare collection of names for the list
vector <string> names {};
//Declare character to hold the user menu selection
char selection {};
string user_input{};
string banner (50, '=');
//Print menu
do
{
cout << "\n" << banner << endl;
cout << "A - Add name to list" << endl;
cout << "P - Print all names in list" << endl;
cout << "E - Encrypt a name in the list" << endl;
cout << "D - Decrypt a name in the list" << endl;
cout << "S - Show details of a name in the list" << endl;
cout << "C - Clear all names in the list" << endl;
cout << "Q - Quit" << endl;
cout << banner << endl;
cout << "Selection: ";
getline(cin, user_input);
if (user_input.size() != 1)
{
cout << "Error 4: Menu selection must be a single character" << endl;
selection = '1';
}
else
{
for (auto c: user_input)
{
if (!isalpha(c))
{
cout << "Error 5: Menu selection must be an alphabetic character" << endl;
selection = '1';
}
else
selection = c;
}
}
// cin >> selection;
// cin.clear();
// cin.sync();
switch (selection)
{
case 'a':
case 'A':
{
string temp_name{};
bool invalid_name {false};
cout << "Enter full name: ";
getline(cin, temp_name);
if (!isalpha(temp_name[0]))
cout << "Error 2: Names must begin with an alphabetic character" << endl << endl;
else
{
for (auto c: temp_name)
{
if (!isalpha(c) && !isspace(c) && c != '-')
{
invalid_name = true;
break;
}
else
invalid_name = false;
}
if (invalid_name)
cout << "Error 3: Name contains invalid characters" << endl << endl;
else
{
temp_name.at(0) = toupper (temp_name.at(0));
for (size_t i {1}; i < temp_name.size(); i++)
{
size_t position{i-1};
if (isspace(temp_name.at(position)) || temp_name.at(position) == '-')
{
temp_name.at(i) = toupper(temp_name.at(i));
}
}
names.push_back(temp_name);
cout << "Added name #" << names.size() << endl;
}
}
break;
}
case 'p':
case 'P':
{
for (size_t i {0}; i < names.size(); i++)
cout << i+1 << ". " << names.at(i) << endl;
break;
}
case 'e':
case 'E':
{
size_t encrypt_input{}, key_position{}, name_position {}, name_size {};
cout << "Enter the position of the name to encrypt: ";
cin >> encrypt_input;
cin.clear();
cin.sync();
if (encrypt_input < 1 || encrypt_input > names.size())
cout << "Error 6: Invalid selection for name to encrypt" << endl << endl;
else
{
name_position = encrypt_input - 1;
name_size = names.at(name_position).size();
cout << "Encrypting name: " << names.at(name_position) << " of size " << name_size << endl << endl;
cout << "Position 1 " << names.at(name_position).at(0) << " is the same as ";
key_position = alphabet.find(names.at(name_position).at(0));
cout << key.at(key_position) << endl;
for (size_t i {0}; i < name_size; i++)
{
key_position = alphabet.find(names.at(name_position).at(i));
cout << "Finding " << names.at(key_position).at(i) << " in key at position " << key_position << endl;
cout << "Found encryption value of " << key.at(key_position) << " at position " << key_position << endl;
cout << "Changing " << names.at(key_position).at(i) << " to " << key.at(key_position) << endl;
names.at(name_position).at(i) = key.at(key_position);
}
/*
for (auto c: names.at(encrypt_input-1))
{
cout << "Converting " << c << " to ";
key_position = alphabet.find(c);
cout << key.at(key_position) << endl;
c = key.at(key_position);
cout << "C is now " << c << endl << endl;
}
*/
}
cout << names.at(encrypt_input-1) << endl;
break;
}
case 'q':
case 'Q':
cout << "Goodbye" << endl << endl;
break;
default:
cout << "Error 1: Invalid menu selection" << endl << endl;
break;
}
} while (selection != 'Q' && selection != 'q');
return 0;
}
Welcome to Stackoverflow! I agree entirely with PaulMcKenzie that such a big function is not the best for a variety of reasons - the immediate reasons are that its hard to read and hard to find problems - but there are more reasons as well.
Having said that you have a bug that I can see in the E case.
for (size_t i {0}; i < name_size; i++)
{
key_position = alphabet.find(names.at(name_position).at(i));
cout << "Finding " << names.at(key_position).at(i) << " in key at position " << key_position << endl;
cout << "Found encryption value of " << key.at(key_position) << " at position " << key_position << endl;
cout << "Changing " << names.at(key_position).at(i) << " to " << key.at(key_position) << endl;
names.at(name_position).at(i) = key.at(key_position);
}
Should be
for (unsigned int i{ 0 }; i < name_size; i++)
{
key_position = alphabet.find(names.at(name_position).at(i));
cout << "Finding " << names.at(name_position).at(i) << " in key at position " << key_position << endl;
cout << "Found encryption value of " << key.at(key_position) << " at position " << key_position << endl;
cout << "Changing " << names.at(name_position).at(i) << " to " << key.at(key_position) << endl;
names.at(name_position).at(i) = key.at(key_position);
}
ie key_position should be name_position in 2 places.
There may be other bugs, but this should stop the crashing and do the encoding right.
EDIT: On request of OP have added a new code fragment.
int i = 0; // position counter
for (auto c: names.at(encrypt_input-1))
{
cout << "Converting " << c << " to ";
key_position = alphabet.find(c);
cout << key.at(key_position) << endl;
c = key.at(key_position);
cout << "C is now " << c << endl << endl;
names.at(name_position).at(i++) = c; // update the names variable.
}
This should solve the problem you mentioned for the auto loop.
You're accessing an invalid location of names vector and the error / exception is showing that.
When you do this:
names.at( key_position ).at( i )
// ^^^
// It should be name_position
in this statement,
cout << "Finding " << names.at( key_position ).at( i ) << " in key at position " << key_position << endl;
you're accessing an invalid index of names whereas it should be:
names.at( name_position ).at( i )
and, that'll work because it access a valid index.
You're making the same mistake in this statement as well:
cout << "Changing " << names.at( key_position ).at( i ) << " to " << key.at( key_position ) << endl;
Correct these and it should work!
Tip:
It's time you read How to debug small programs.
It'll help you figure out what's wrong with your program in a more systematic way.
A few points regarding your code organization in general:
You should divide your program in functions instead of cluttering the main function.
You may write functions corresponding to each of your case in switch statement e.g. addName(), encryptName(), decryptName(), etc.
This modularity will definitely help you and other people to read, debug, maintain and extend your code easily and efficiently. In your case, it would also help you write an Minimal, Complete, and Verifiable example in no time.
Hope that helps!
Best of luck!
Happy coding!
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
Okay I fixed the errors. Thank you guys. But now when I run it, I choose D in the menu but only "You chose to split the words & remove the duplicates in the paragraph" & "This is it:" prints out. It doesn't show anything after that ... Anyone know what it could be? Thank you in advance!!
This is how it should be:
When the 4th choice (“Split Words”) is selected, the words should be put into an array or a structure of your and each word should be displayed with a loop. After this duplicate removal should be performed and the program must determine the duplicate words and eliminate them. After this, the word list should be printed again
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <string>
#include <algorithm>
#include <cctype>
#include <sstream>
#include <set>
using namespace std;
int main()
{
string s;
char selection;
string w;
string buf;
cout << "Enter a paragraph or a sentence : " ;
getline(cin, s);
int sizeOfString = s.length();
//cout << "The paragraph has " << sizeOfString << " characters. " << endl; ***Dummy call to see if size works.
//cout << "You entered " << s << endl; *** Dummy function !!
cout << "" << endl;
cout << " Menu " << endl;
cout <<" ------------------------" << endl;
cout << "" << endl;
cout << "A -- Convert paragraph to all caps " << endl;
cout << "B -- Convert paragraph to all lowercase " << endl;
cout << "C -- Delete whitespaces " << endl;
cout << "D -- Split words & remove duplicates " << endl;
cout << "E -- Search a certain word " << endl;
cout << "" << endl;
cout << "Please select one of the above: " ;
cin >> selection;
cout << "" << endl;
stringstream ss(s);
set<string> tokens;
switch (selection) //Switch statement
{
case 'a':
case 'A': cout << "You chose to convert the paragraph to all uppercase" << endl;
cout << "" << endl;
for(int i=0; s[i]!='\0'; i++)
{
s[i]=toupper(s[i]);
}
cout << "This is it: " << s << endl;
break;
case 'b':
case 'B': cout << "You chose to convert the paragragh to all lowercase" << endl;
cout << "" << endl;
for (int i=0; s[i] !='\0'; i++)
{
s[i]=tolower(s[i]);
}
cout << "This is it: " << s << endl;
break;
case 'c':
case 'C': cout << "You chose to delete the whitespaces in the paragraph" << endl;
cout << "" << endl;
for(int i=0; i<s.length(); i++)
if(s[i] == ' ') s.erase(i,1);
cout <<"This is it: " << s << endl;
break;
case 'd':
case 'D': cout << "You chose to split the words & remove the duplicates in the paragraph" << endl;
cout << "" << endl;
// Insert the string into a stream
// Create vector to hold our words
while (ss >> buf)
tokens.insert(buf);
cout << "This is it: " << endl;
for (set<string>::iterator it = tokens.begin(); it != tokens.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
break;
case 'e':
case 'E': cout << "You chose to search for a certain word in the paragraph. " << endl;
cout << "" << endl;
cout << "Enter the word you want to search for: ";
cin >> w;
s.find(w);
if ( s.find( w ) != std::string::npos )
{
cout << w << " was found in the paragraph. " << endl;
}
else
{
cout << w << " was not found in the paragraph. " << endl;
}
}
return 0;
}
1)
set<s>::iterator
should be
set<string>::iterator
2) Add brackets around the case statements for the local variables.
case 'D':{
}
break;
case 'e':
case 'E':{
}
break;
You are creating stringstream with empty string, which, in turn leads to stream being empty. Consider creating stringstream object after you actually read the string. stringstream doesn't hold a reference to your string object, so any modification to a string the stringstream was based on, doesn't reflect those changes in the stream.
I'm creating a program that takes in a sentence or a paragraph. It then asks the user what they'd like to do.
- Covert to all caps
- Covert to all lowercase
- Delete white spaces
- Split words and remove duplicates
- Search for a word in the string
I got the all of them but I can't figure out how to split the words and remove duplicates..
When the 4th choice (“Split Words”) is selected, the words should be put into an array or a structure and each word should be displayed with a loop. After this, duplicate removal should be performed and the program must determine the duplicate words and eliminate them. After this, the word list should be printed again.
Any help with this would be greatly appreciated. Thank you
This is my code & I need help with case 'D'
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <string>
#include <algorithm>
#include <cctype>
using namespace std;
int main() {
string s;
char selection;
string w;
cout << "Enter a paragraph or a sentence : ";
getline(cin, s);
int sizeOfString = s.length();
//cout << "The paragraph has " << sizeOfString << " characters. " << endl; ***Dummy call to see if size works.
//cout << "You entered " << s << endl; *** Dummy function !!
cout << "" << endl;
cout << " Menu " << endl;
cout << " ------------------------" << endl;
cout << "" << endl;
cout << "A -- Convert paragraph to all caps " << endl;
cout << "B -- Convert paragraph to all lowercase " << endl;
cout << "C -- Delete whitespaces " << endl;
cout << "D -- Split words & remove duplicates " << endl;
cout << "E -- Search a certain word " << endl;
cout << "" << endl;
cout << "Please select one of the above: ";
cin >> selection;
cout << "" << endl;
switch (selection) //Switch statement
{
case 'a':
case 'A':
cout << "You chose to convert the paragraph to all uppercase" << endl;
cout << "" << endl;
for (int i = 0; s[i] != '\0'; i++) {
s[i] = toupper(s[i]);
}
cout << "This is it: " << s << endl;
break;
case 'b':
case 'B':
cout << "You chose to convert the paragragh to all lowercase" << endl;
cout << "" << endl;
for (int i = 0; s[i] != '\0'; i++) {
s[i] = tolower(s[i]);
}
cout << "This is it: " << s << endl;
break;
case 'c':
case 'C':
cout << "You chose to delete the whitespaces in the paragraph" << endl;
cout << "" << endl;
for (int i = 0; i < s.length(); i++) {
if (s[i] == ' ')
s.erase(i, 1);
}
cout << "This is it: " << s << endl;
break;
case 'd':
case 'D':
cout << "You chose to split the words & remove the duplicates in the paragraph" << endl;
cout << "" << endl;
case 'e':
case 'E':
cout << "You chose to search for a certain word in the paragraph. " << endl;
cout << "" << endl;
cout << "Enter the word you want to search for: ";
cin >> w;
s.find(w);
if (s.find(w) != std::string::npos) {
cout << w << " was found in the paragraph. " << endl;
} else {
cout << w << " was not found in the paragraph. " << endl;
}
}
return 0;
}
You can use stringstream to split your string by whitespaces and set<string> to contain only unique words. Then your code should look like:
case 'D':
{
cout << "You chose to split the words & remove the duplicates in the paragraph" << endl;
string buf;
stringstream ss(s); // Insert the string into a stream
set<string> tokens; // Create vector to hold our words
while (ss >> buf)
tokens.insert(buf);
cout << "This is it: " << endl;
for (set<string>::iterator it = tokens.begin(); it != tokens.end(); ++it) {
cout << *it << " ";
}
cout << endl;
break;
}
I am creating a code that lets the user choose what they'd like to perform from a menu. When I run my code I select choice 'E' and I enter the word I want to be searched. The result comes out that the word is not in the sentence even though it is. Any reason why ? Thank you in advance
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <string>
#include <algorithm>
#include <cctype>
using namespace std;
int main()
{
string s;
char selection;
string w;
cout << "Enter a paragraph or a sentence : " ;
getline(cin, s);
int sizeOfString = s.length();
//cout << "The paragraph has " << sizeOfString << " characters. " << endl; ***Dummy call to see if size works.
//cout << "You entered " << s << endl; *** Dummy function !!
cout << "" << endl;
cout << " Menu " << endl;
cout <<" ------------------------" << endl;
cout << "" << endl;
cout << "A -- Convert paragraph to all caps " << endl;
cout << "B -- Convert paragraph to all lowercase " << endl;
cout << "C -- Delete whitespaces " << endl;
cout << "D -- Split words & remove duplicates " << endl;
cout << "E -- Search a certain word " << endl;
cout << "" << endl;
cout << "Please select one of the above: " ;
cin >> selection;
cout << "" << endl;
switch (selection) //Switch statement
{
case 'a':
case 'A': cout << "You chose to convert the paragraph to all uppercase" << endl;
cout << "" << endl;
for(int i=0; s[i]!='\0'; i++)
{
s[i]=toupper(s[i]);
}
cout << "This is it: " << s << endl;
break;
case 'b':
case 'B': cout << "You chose to convert the paragragh to all lowercase" << endl;
cout << "" << endl;
for (int i=0; s[i] !='\0'; i++)
{
s[i]=tolower(s[i]);
}
cout << "This is it: " << s << endl;
break;
case 'c':
case 'C': cout << "You chose to delete the whitespaces in the paragraph" << endl;
cout << "" << endl;
for(int i=0; i<s.length(); i++)
if(s[i] == ' ') s.erase(i,1);
cout <<"This is it: " << s << endl;
break;
case 'd':
case 'D': cout << "You chose to split the words & remove the duplicates in the paragraph" << endl;
cout << "" << endl;
/*char arrayOne[] = s;
for (int i=0; i< s.length; i++)
{
cout << arrayOne[i] << endl;
}*/
case 'e':
case 'E': cout << "You chose to search for a certain word in the paragraph. " << endl;
cout << "" << endl;
cout << "Enter the word you want to search for: ";
cin >> w;
s.find(w);
if (s.find(w) == true)
{
cout << w << " was found in the paragraph. " << endl;
}
else if (s.find(w) != true);
{
cout << w << " was not found in the paragraph. " << endl;
}
}
return 0;
}
std::string::find returns the sub-string position, not a boolean. Check the documentation.
if equal to std::string::npos, instance is not found, else, if (greater or equal to zero) it is found.
So:
if ( s.find( w ) )
Should be:
if ( s.find( w ) != std::string::npos )
And, by the way:
s.find(w);
if (s.find(w) == true)
{
cout << w << " was found in the paragraph. " << endl;
}
else if (s.find(w) != true);
{
cout << w << " was not found in the paragraph. " << endl;
}
Should be:
if ( s.find( w ) != std::string::npos )
cout << w << " was found in the paragraph. " << endl;
else // no need to test again!
cout << w << " was not found in the paragraph. " << endl;
Your problem is with
if (s.find(w) == true)
find() returns the position of the found string not true or false. If you want to check if it finds the word use
if (s.find(w) != std::string::npos)
I want to suggest the following to simplify your development / test effort:
bool DEVELOPEMENT_MODE = true;
int t247(void)
{
std::string s;
char selection;
std::string w;
std::cout << "Enter a paragraph or a sentence : " ;
// instead of ONLY run-time fetch of paragraph or sentence
if(DEVELOPEMENT_MODE)
{
// for developement use:
std::stringstream ss;
// TEST STRING
ss << "the quick brown fox jumped over the lazy dog";
s = ss.str(); // fill in test input
size_t sizeOfString = s.length(); // note: not int
// ***Dummy unit test to see if size works.
std::cout << "The paragraph has " << sizeOfString
<< " characters. " << std::endl;
// ***Dummy unit test
std::cout << "You entered " << s
<< std::endl;
}
else
{
// for final test use run time entry of sentence
getline(std::cin, s);
}
//...
As you get each function working, add more complexity to the test string (using the editor you normally use).
I often use argc or argv[1] (of main) to select which test to run.
Update:
By the way, you will find it difficult to read a paragraph using getline() without a loop.
However, the DEVELOPMENT_MODE code (with stringstream) can trivially create a paragraph.
ss << "the quick brown fox jumped over the lazy dog";
can be easily expanded ... c++ auto-magically concatenates lines into a single line:
ss << "the quick brown fox jumped over the lazy dog"
"quick brown fox jumped over the lazy dog the"
"brown fox jumped over the lazy dog the brown";
But the above is not yet a paragraph.
The following is a 3 line paragraph:
ss << "the quick brown fox jumped over the lazy dog\n"
"quick brown fox jumped over the lazy dog the\n"
"brown fox jumped over the lazy dog the brown\n";
Okay so as the title said its refusing to execute the stuff right under the "do" function even though as far as i can tell all the parameters for a repeat have been fulfilled. So far what i get when i run the program is something along the lines of...
"Would you like to search another name?
Please enter Y for yes and n for no:"
looping over and over when i press y
#include <iostream>
#include <string>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <cstdlib>
using namespace std;
int main()
{
vector <string> vName, vID, vClass;
string sName, sID, sClass, sSearch, cQuestion;
int iSize, iStudent;
// Display initial vector size
iSize = vName.size();
cout << "Student list starts with the size:" << iSize << endl;
// Get size of list from user
cout << "How many students would you like to add?" << endl;
cin >> iStudent;
cin.ignore();
// Get names, ids, and classes
for (int i = 0; i < iStudent; i++)
{
cout << "Student" << i + 1 << ":\n";
cout << "Please enter the student name: ";
getline(cin, sName);
vName.push_back(sName);
cout << "Enter ID number ";
getline(cin, sID);
vID.push_back(sID);
cout << "Enter class name ";
getline(cin, sClass);
vClass.push_back(sClass);
}
// Display header
cout << "The list of students has the size of: " << iStudent << endl;
cout << "The Student List" << endl;
cout << "\n";
cout << "Name:" << setw(30) << "ID:" << setw(38) << "Enrolled Class : " << endl;
cout << "--------------------------------------------------------------------------";
cout << "\n";
// for loop for displying list
for (int x = 0; x < vName.size() && vID.size() && vClass.size(); x++)
{
cout << vName[x] << "\t \t \t" << vID[x] << "\t \t \t" << vClass[x] << endl;
}
// Sorting function
cout << "\n";
cout << "The Student List after Sorting:" << endl;
cout << "\n";
sort(vName.begin(), vName.end());
for (int y = 0; y < vName.size(); y++)
{
cout << vName[y] << endl;
}
cout << "\n";
// Search function
do
{
cout << "Please Enter a name to be searched:" << endl;
getline(cin, sSearch);
if (binary_search(vName.begin(), vName.end(), sSearch))
{
cout << sSearch << " was found." << endl << endl;
}
else
{
cout << sSearch << " was not found." << endl << endl;
}
cout << "Would you like to search another name?" << endl << endl;
cout << "Please enter Y for Yes and N for No:" << endl << endl;
cin >> cQuestion;
} while (cQuestion == "Y" || cQuestion == "y");
cout << "Thank you for using this program!" << endl;
return 0;
}
Edit:
Posted whole program, please excuse any grammatical mistakes, I'm just trying to get the program down before i go in there and make it pretty.
The tail of your loop does this:
cout << "Please enter Y for Yes and N for No:" << endl << endl;
cin >> cQuestion;
which will consume your string if you entered one, but leave the trailing newline in the input stream. Thus when you return to the top of the loop after entering Y or y, and do this:
cout << "Please Enter a name to be searched:" << endl;
getline(cin, sSearch);
the getline will extract an empty line.
How to consume the unread newline from the input stream is up to you. You will likely just end up using .ignore() as you did prior in your program. Or use getline to consume cQuestion. You have options. Pick one that works.
And as a side note, I would strongly advise you check your stream operations for success before assuming they "just worked". That is a hard, but necessary, habit to break. Something like this:
do
{
cout << "Please Enter a name to be searched:" << endl;
if (!getline(cin, sSearch))
break;
if (binary_search(vName.begin(), vName.end(), sSearch))
{
cout << sSearch << " was found." << endl << endl;
}
else
{
cout << sSearch << " was not found." << endl << endl;
}
cout << "Would you like to search another name?" << endl << endl;
cout << "Please enter Y for Yes and N for No:" << endl << endl;
} while (getline(cin,cQuestion) && (cQuestion == "Y" || cQuestion == "y"));
If cQuestion is a char array then you need to use strcmp or stricmp to compare it with another string i.e. "Y" and "y" in this case. If cQuestion is a single char then you need to compare with 'Y' and 'y' (i.e. with a single quote)
Strings in C++ are not first class types therefore they do not have some of the string operation that exist for other basic types like ints and floats. You do have std::string as part of the standard C++ library which almost fulfills the void.
If you just change the type of cQuestion to std::string your code should work but if you want to stick with chars then you will need to change the quote style.