Why am I getting an extra space on my parsing string code? - c++

I am having problems with my code for this homework assignment. Everything is outputting correctly except I am getting an extra space after my "first" output. My code is shown below please help me to fix the extra space.
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main() {
string userStr;
bool inputDone = false;
while(!inputDone)
{
bool commaCheck = false;
do
{
cout << "Enter input string:" << endl;
getline(cin, userStr);
if (userStr == "q")
{
inputDone = true;
break;
}
else{
for (unsigned int i = 0; i < userStr.length(); i++)
{
if (userStr[i] == ',')
commaCheck = true;
}
if (!commaCheck)
{
cout << "Error: No comma in string." << endl << endl;
}
}
} while (!commaCheck);
if(!inputDone)
{
string first, second;
istringstream stream(userStr);
getline(stream, first, ',');
stream >> second;
cout << "First word: " << first << endl;
cout << "Second word: " << second << endl;
cout << endl;
}
}
return 0;
}

If you use std::getline(stream, first, ','); and there is a space between your word and the comma then it will be of course in first. Because you told std::getline: Get me everything until you see a comma.
If somebody inputs " a ,b", then you have leading and trailing spaces in first.
You need to "trim" your string, meaning remove leading and trailing spaces.
There are many trim functions published here on SO. Please see for example here
If you see an additional problem, then please inform

Related

Check letters against the word of an arbitrary size in a Hangman game

Currently I am working on a hangman game, I had previously coded it to only work for a 5 letter word, but now would like to make it handle any length of word, how could I change this code to make it work how I want it to?
#include "stdafx.h"
#include <iostream>
#include <string>
#include <stdlib.h>
#include <cstdlib>
using namespace std;
int main()
{
string word;
int tries;
string guess;
string wordguess;
string output;
cout << "Enter a word for player two to guess: ";
cin >> word;
system("CLS");
cout.flush();
cout << "Guess the word!" << endl;
for (int i = 0; i < word.length(); i++)
{
cout << "_ ";
}
cout << "Enter a letter: ";
cin >> guess;
for (int tries = 5; tries > 0; tries--)
{
if (guess[0] == word[0]) {
output[0] = word[0];
cout << "You guessed the first letter! Good job!" << endl;
}
if (guess[0] == word[1]) {
output[2] = word[1];
cout << "You guessed the second letter! Good job!" << endl;
}
if (guess[0] == word[2]) {
output[4] = word[2];
cout << "You guessed the third letter! Good job!" << endl;
}
if (guess[0] == word[3]) {
output[6] = word[3];
cout << "You guessed the fourth letter! Good job!" << endl;
}
if (guess[0] == word[4]) {
output[8] = word[4];
cout << "You guessed the fifth letter! Good job!" << endl;
}
cout << output << endl;
cout << "You have " << tries << " tries left. Take a guess at the word: " << endl;
cin >> wordguess;
if (wordguess == word)
{
cout << "Congratulations, you guessed the word correctly!" << endl;
break;
}
}
system("pause");
return 0;
}
As you can tell I was checking each position from 0 to 4 (first through fifth letter). I know there are plenty of ways that I could have coded this better but as you can guess, I am new to coding and this is the way I thought of it. Please note this is still a work in progress so it is not fully complete. Any help would be great!
When designing an algorithm, think of how you would do this by hand, without a computer. Then let the code do the same.
If you were checking your friend's guess against a word written on sand, you would probably go about it like this:
go through the written pattern character by character, pronouncing your word in memory
for each letter, check if it is equal to the guess
if it is
replace the placeholder with it
memorize that your friend guessed right.
Also note if there are any placeholders left
if there aren't, your friend wins
finally, if your friend didn't guess right, score them a penalty point and check if they lose
Now, all that leaves is to put this down in C++. The language provides all sorts of entities - let's check which ones fit ours needs the best:
the word and the current pattern - strings of a fixed size
bits to memorize:
whether the current guess is right - bool
placeholders left - int
penalty points (or, equivalently, attempts left) - int
parts of the algorithm:
looping over a string - for loop of one of a few kinds
we need to replace the character in the pattern at the same index as the guessed letter in the word. So, we need to have the index when looping. Thus the flavor with the index variable, for(std::string::size_type i = 0; i < str.size(); ++i) probably fits the best.
// Example program
#include <iostream>
#include <string>
using namespace std;
class my_game
{
private:
string congrats_array[15] = {"first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eighth", "nineth", "tenth", "eleventh", "twelfth", "thirteenth", "fourteenth", "fifteenth"};
string word_to_guess;
int tries_left;
int word_length;
int letters_guessed_count;
string guessed_letters;
void check_letter(char letter);
void print_current_word_state();
public:
my_game();
void begin_the_game();
void play_the_game();
};
my_game::my_game()
{
}
void my_game::begin_the_game()
{
cout << "Enter a word for player to guess: " << endl;
cin >> word_to_guess;
system("CLS");
cout.flush();
cout << "Enter the tries amount!\n" << endl;
cin >> tries_left;
word_length = word_to_guess.size();
guessed_letters = "_";
letters_guessed_count = 0;
for(int i = 0; i < word_length - 1; i++){
guessed_letters += "_";
}
}
void my_game::play_the_game()
{
cout << "Guess the word!" << endl;
char letter;
for(int i = 0; i < tries_left; i++)
{
cout << guessed_letters << endl;
cout << "Enter a letter: " << endl;
cin >> letter;
check_letter(letter);
if(letters_guessed_count == word_length){
cout << "Congrats! You won!" << endl;
return;
}
}
cout << "You lose" << endl;
}
void my_game::check_letter(char letter)
{
for(int i = 0; i < word_length; i++)
{
if(word_to_guess[i] == letter && guessed_letters[i] != letter)
{
guessed_letters[i] = letter;
letters_guessed_count++;
cout << "You guessed the" << congrats_array[i] <<"letter! Good job!" << endl;
}
}
}
int main()
{
my_game game;
game.begin_the_game();
game.play_the_game();
}
So, in short what you need to do this with words of any arbitrary length is to use string's .substr() function and the stringstream library's .str() and << and >> operators. This version of your code uses a function that inserts a correctly guessed character at the appropriate indexed location. This will gradually replace the "_________" with letters at the correct places. This is much easier to do in Java, but stringstream is a good library I would highly recommend getting familiar with it. I'll leave the problem of how to handle multiple instances of a guessed character up to you (ie 'i' in "bibliography")
#include <string>
using std::string;
#include <sstream>
using std::stringstream;
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
string newString(string, int, string);
int main()
{
string word;
string guess;
int tries;
string output;
string input;
cout << "Enter word for player 2 to guess: ";
cin >> word;
stringstream ss;
//---------- fills the stream with "_"s matching the length of word
for(int i = 0; i < word.length(); i++)
ss << "_";
//----------- assigns the initial value of "___..." to output
ss >> output;
//----------- sets up the loop
tries = 5;
bool found = false;
for(int i = 0; i < 5; i++)
{
cout << "\nTry " << i << " of 5: Enter a letter or guess the word: ";
cin >> input;
if(input == word)
{
cout << "Congratulations, you guessed the word correctly!" << endl;
break;
}
//------------------ else, proceed with replacing letters
if(word.find(input) != std::string::npos)
{
size_t position = word.find(input); // finds index of first instance of the guessed letter
cout << "You guessed the " << position+1 << " letter! Good job!" << endl; // since strings start at index 0, position+1
//------- replaces appropriate "_" with the guessed letter
output = newString(input, position, output);
cout << "\n" << output;
// Around here you'll want to set up a way to deal with multiple instances
// of the same letter
}
else
cout << "Incorrect guess" << endl;
}
return 0;
}
//---------------------------------------------------
string newString(string guess, int index, string word)
{
string NewString;
stringstream temp;
//---------- hack up the string into sections before and after the index
string before = word.substr(0, index);
string after = word.substr(index+1, word.length() - index+1);
//---------------- populates the new stringstream and assigns it to the result
temp << before << guess << after;
NewString = temp.str();
return NewString;
}

First word of a phrase is dropped when I try and put it in a vector?

Sorry for the vague header. Difficult to describe. I am trying to get a phrase from the user and put that phrase into a vector, word by word, separated by spaces. For some reason when the vector is printed it completely leaves out the first word of the phrase, if that makes sense. Here's the code I have so far:
void printVector(vector<string>& words){
cout << "Print words: " << endl;
for (int i = 0; i < words.size(); i++){
if (i < words.size()){
cout << words[i] << ", ";
}
else
cout << words[i];
}
cout << endl;
}
int main(){
string phraseInput;
string stop = "done";
do{
cin >> phraseInput;
if(phraseInput == stop){
cout << "Program finished." << endl;
return 0;
}
else {
getline(cin, phraseInput);
istringstream iss(phraseInput);
vector<string> words;
copy(istream_iterator<string>(iss),
istream_iterator<string>(),
back_inserter(words));
printVector(words);
}
}while(phraseInput != stop);
}
Here you have taken input for two times only first one skipped
Now you should change this
else{ string temp;
getline(cin, temp);
phraseInput+=temp;
istringstream iss(phraseInput);
//.....
I think I found your answer
I tested your code with the phrase "this is line."
Your variable "phraseInput" first take "this" string.
After getline(cin, phraseInput) line.
Your variable "phraseInput" take "is line" string.
Therefore when it prints, it simply skips the first keyword.
Result is: the first string "this" is missing
I think in this way: You take two input from user.
Therefore I thought " What happens if I commented first cin? "
After commented on your first cin. I got all the string in variable "phraseInput"
Result is:
Then I thought "do while" loop also unnecessary, since it prints any word it took from user.
I also commented your "do while" loop
Here is the final version of your code.
#include <vector>
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
void printVector(vector<string>& words){
cout << "Print words: " << endl;
for (int i = 0; i < words.size(); i++){
if (i < words.size()){
cout << words[i] << ", ";
}
else
cout << words[i];
}
cout << endl;
}
int main(){
string phraseInput;
string stop = "done";
/*do{
cin >> phraseInput;
if (phraseInput == stop){
cout << "Program finished." << endl;
return 0;
}
else {*/
getline(cin, phraseInput);
istringstream iss(phraseInput);
vector<string> words;
copy(istream_iterator<string>(iss),
istream_iterator<string>(),
back_inserter(words));
printVector(words);
//}
system("pause");
//} while (phraseInput != stop);
}

Validate case pattern (isupper/islower) on user input string

I need to write a program that checks if the user-provided first and last names are correctly typed. The program needs to validate that only the first letter of each name part is uppercase.
I managed to write code that checks the first character of the input. So I have a problem when for example "JOHN" is entered.
A correct input would be for example "John Smith".
Here's the code:
#include <iostream>
#include <string>
using namespace std;
int main ()
{
std::string str;
cout << "Type First Name: ";
cin >> str;
if(isupper(str[0]))
{
cout << "Correct!" <<endl;
}
else
{
cout << "Incorrect!" <<endl;
}
system("pause");
return 0;
}
The simplest thing you can do is to use a for/while loop. A loop will basically repeat the same instruction for a number of n steps or until a certain condition is matched.
The solution provided is pretty dummy, if you want to read the first name and last name at the same time you will have to spit the string via " " delimiter. You can achieve this result using strtok() in C/C++ or with the help of find in C++. You can see some examples of how to split here.
You can easily modify your code to look like this:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
std::string str;
std::vector<std::string> data = { "First", "Last" };
int j;
for (int i = 0; i < 2; i++) {
cout << "Type " << data[i] << " Name: ";
cin >> str;
if (isupper(str[0])) {
for (j = 1; j < str.size(); j++) {
if (!islower(str[j]))
{
cout << "InCorrect!" << endl;
break; // Exit the loow
}
}
if(j==str.size())
cout << "Correct!" << endl;
}
else {
cout << "InCorrect!" << endl;
}
}
system("pause");
return 0;
}

Write a name in a diagonal line representation

I'm trying to write a program that will show a name in a diagonal line.
I know I should add a variable with space, like \t, and increment it in each loop.
I have tried to do this with no success. Any suggestions?
int main()
{
string space = "\t";
string firstName;
cout << "Enter your first name:";
cin >> firstName;
for (int posChar = 0;
posChar < firstName.length( );
posChar++)
cout << space << firstName.at(posChar) << endl;
space=space + "\t"; // this is what I've tried, it's a long shot.
return 0;
}
output:
Enter your first name:Alexander
A
l
e
x
a
n
d
e
r
If you would indent you code properly, you would see that space=space + "\t"; is not part of the for.
Also, you should use a space instead of a tab.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string space;
string firstName;
cout << "Enter your first name:";
cin >> firstName;
for (int posChar = 0; posChar < firstName.length( ); posChar++)
{
cout << space << firstName.at(posChar) << endl;
space = space + " ";
}
return 0;
}
You could submit some of your code (not necessarily this one) to code review. You have some bad practices when it comes to formatting and (lack of) indenting.
Need { } on your for loop. Without it you are not adding the tab for each character but instead add it when the loop is complete.
If you do a for loop without a block then only the command following the loop is executed.
Did you forget the opening and closing brackets for the code block?
The loop you wrote only does
cout << space << firstName.at(posChar) << endl;
and after it has finished it does once
space=space + "\t"; // this is what I've tried, it's a long shot.
It should look like this:
for (int posChar = 0;
posChar < firstName.length( );
posChar++)
{
cout << space << firstName.at(posChar) << endl;
space=space + "\t"; // this is what I've tried, it's a long shot.
}

Search word not found in a vector?

I'm implementing a function where the user can search for a word in a vector. The only problem is, my search function is only finding certain words and I'm not sure why.
ifstream in("testdata.txt");
string word1;
vector<string> individual_words;
while (in >> word1)
{
individual_words.push_back(word1);
}
Inside the file testdata.txt is:
Hello how are you
Good are you well?
Snazzy piece of toast
Here is the code where I compare the two words.
string search_word;
while (cin >> search_word)
{
for (int f=0; f < individual_words.size(); f ++)
{
cout << "individual words: " << individual_words[f] <<endl;
cout << "search word: " << search_word;
if (search_word == individual_words[f])
{
cout << " FOUND THE SAME WORD\n!";
break;
}
}
}
For some reason it's only catching certain words in a .txt file and I'm not exactly sure why. I've looked at it and it looks like it ignores the first word and it ignores every last word on each sentence.
Your vector will have duplicates, so it will only find the first occurrences of the words "are" and "you" before your loop breaks. Logically, there is nothing else wrong in this section of code, though it would be better written as:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
int main()
{
// simplified for demonstration purposes
string test = "Hello how are you\nGood are you well?\nSnazzy piece of toast";
istringstream iss(test);
vector<string> words;
copy(istream_iterator<string>(iss), istream_iterator<string>(), back_inserter(words));
string search_word;
while (cin >> search_word)
{
// this works, but is unnecessary
/*for (int f=0; f < words.size(); f ++)
{
cout << "individual words: " << words[f] <<endl;
cout << "search word: " << search_word;
if (search_word == words[f])
{
cout << " FOUND THE SAME WORD\n!";
break;
}
}*/
// this is a better approach
vector<string>::iterator it = find(words.begin(), words.end(), search_word);
if (it != words.end())
{
cout << "Found the word: " << *it << endl;
}
else
{
cout << "Not found!" << endl;
}
}
return 0;
}