c++ reading user inputted char one by one symbol - c++

So I have been searching, but couldn't exactly find a solution for the thing I want to do. Basically User input's a char like "asdasdasd" and I need to go thru each symbol to check if it's 'a', and need to stop the loop after it has reached the end of char. I got this far and it works, it output's the char symbols one by one, but in this case I can't stop the loop, I tried adding another char at the end and make it something specific like "." and use that to stop the loop but then I need to use char o[] which brakes the symbol by symbol thing going on there. Need help.. any input would be appreciated.
#include <iostream>
using namespace std;
int main(){
char o;
cout<<"input: "; cin>>o;
while(o!= '\0'){
cout<<o<<"\n";
cin >> o;
}
return 0;
}

When I understand your question correct you will input a string like "ahobansodfb" and search in there after a specific char? If yes, this is a little example:
#include <iostream>
using namespace std;
int main() {
string input;
char search;
int findPos = 0, countOfSearchedChars = 0;
cout << "input searched char: ";
cin >> search;
cout << "input string: ";
cin >> input;
while((findPos = input.find_first_of(search, findPos)) != string::npos){
cout << "Find searched char on pos: " << findPos << endl;
++findPos;
++countOfSearchedChars;
}
if(countOfSearchedChars == 0)
cout << "Char: " << search << " not found in: " << input << endl;
else
cout << "Char: " << search << " found: " << countOfSearchedChars << " time/s in string: " << input << endl;
}
Explanation for: while((findPos = input.find_first_of(search, findPos)) != string::npos)
input.find_first_of(search, findPos) find the first place where the searched char lies. When the char doesn't found it returns string::npos (18446744073709551615)
So we loop so long the return value is not string::npos: != string::npos
Edit to answer comment question:
Possibilities to iterate through a string:
std::string str = "aabaaba";
for(char& c : str) {
if(c == 'a'){
//it's a
} else if(c == 'b') {
//it's b
}
}
std::string str = "abaaba;
for(std::string::iterator it = str.begin(); it != str.end(); ++it) {
if(*it == 'a'){
//it's a
} else if(*it == 'b') {
//it's b
}
}
For every character in string

THANKS for all the answers!, you were big help, this code will do for me, going to go research what it does x.x
std::string str = "abaaba;
for(std::string::iterator it = str.begin(); it != str.end(); ++it) {
if(*it == 'a'){
//it's a
} else if(*it == 'b') {
//it's b
}
}

Related

How to avoid using Backspace character with push_back?

I'm making a software as an ATM, so when the user try to enter the password the user only sees *******, but when trying to delete it doesn't delete a character. It just adds a new one. Here's my code:
string password2 = "";
cout << "PASSWORD: ";
ch = _getch();
while(ch != 13) //character 13 is enter
{
password2.push_back(ch);
cout << '*';
ch = _getch();
}
And also, I try to use pop_back(); but it doesn't work either. Can anybody help me please?
Just did a little magic and created this:
I must admit, I don't like the style... But it "works" !
#include<iostream>
#include<string>
#include <conio.h>
bool verify_pass(const std::string& pass)
{
std::string input = "";
char ch = '0';
while(true)
{
ch = getch();
if(ch == '\b')
{
if(input.size() > 0)
{
input.erase(input.begin() + input.size() - 1); // erase last char
std::cout << "\b \b";
}
}
else if(ch != '\r\n' && ch != '\n' && ch != '\r')
{
input += ch;
std::cout << '*';
}
else
break;
}
return input == pass;
}
int main()
{
std::string insecurePass = "1234";
std::cout << "Enter Password: ";
if(verify_pass(insecurePass))
std::cout << "\nCorrect!\n";
else
std::cout << "\nFalse!\n";
}
By the way, you can use the vector like I used the string, but use push_back instead of += and pop_back() should work too instead of my method with erase.

How to count unique words in string and output line where they occur? C++

So I'm working on this homework assignment and I'm really having trouble. I'm supposed to count the number of words more than two characters(have to contain one letter), unique words, and the number of times each unique word appears in the Programming Execution Environment. I'm also supposed to get input to search for in the PEE and output the number of times it appears and the line where it appears. I have some of it working, but I'm really struggling with counting how many times each word appears. I know my code is really bad right now, but that's why I'm here. I'm really struggling with these string functions for some reason. Any help is really appreciated!
#include <iostream>
#include <cstring>
#include <string>
#include <cctype>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;
//PEE string
string envstr("");
bool checkChar(unsigned c)
{
return (ispunct(c) || isspace(c) || isblank(c) || isdigit(c) || c == '\n');
}
void searchWord(unsigned c, size_t length)
{
multiset<string> words;
vector<string> vwrds; //this was something i was trying out
string tempword;
while (!checkChar(envstr[c]) && c < length)
{
tempword = tempword + envstr[c]; //problem here
c++;
}
tempword = tempword + " ";
vwrds.push_back(tempword);
words.insert(tempword); //this is just a bunch of random letters
tempword.clear();
//for (multiset<string>::const_iterator i(words.begin()), end(words.end()); i != end; i++)
//cout << *i;
}
bool checkIfWord(char c)
{
bool valid = false;
int i;
for (i = c; i > c - 2; i--)
{
if (!checkChar(envstr[i]))
valid = true;
}
if (valid)
searchWord(i, envstr.length());
return valid;
}
int main()
{
//this code given by my instructor
extern char **environ; // needed to access your execution environment
int k = 0;
size_t wordCount = 0;
while (environ[k] != NULL)
{
cout << environ[k] << endl;
string str(environ[k]);
envstr = envstr + str;
k++;
}
//iterator to count words
wordCount = count_if(envstr.begin(), envstr.end(), checkIfWord);
cout << "\nThe PEE contains " << wordCount << " words. \n";
//transform environment string to lowercase
transform(envstr.begin(), envstr.end(), envstr.begin(), tolower);
string input;
do
{
cout << "Enter your search item: \n";
cin >> input;
//string can only be forty characters
if (input.length() > 40 || input == "\n")
{
cout << "That search query is too long. \n";
continue;
}
//change the search string to lowercase, like the envstr
transform(input.begin(), input.end(), input.begin(), tolower);
int j = 0;
int searchCount = 0;
vector<size_t> positions;
size_t pos = envstr.find(input, 0);
//search for that string
while (pos != string::npos)
{
positions.push_back(pos);
pos = envstr.find(input, pos + 1);
searchCount++;
}
cout << "\nThat phrase occurs a total of " << searchCount << " times.\n";
cout << "It occurs in the following lines: \n";
//output where that string occurs
for (vector<size_t>::iterator it = positions.begin(); it != positions.end(); ++it)
{
for (int i = *it; i < envstr.length() - 1 && checkChar(envstr[i]); i++)
{
cout << envstr[i];
}
cout << endl;
}
positions.clear();
} while (input != "END");
cin.get();
return 0;
}
First, your function checkChar() returns false when the parameter is a char, so if you want to print where that string occurs, it should be:
for (int i = *it; (i < envstr.length() - 1) && !checkChar(envstr[i]); i++)
{
cout << envstr[i];
}
Second, the code for counting words makes no sense and there is a potential out-of-bounds here: if (!checkChar(envstr[i])), I would suggest you to split the string using delimter '\', then do something.

C++ - Replacing "_" with a character

Using C++, I'm trying to make a hangman game to become better at using C++ and programming in general. Anyways, the issue I'm facing is that I'm not sure how to replace the dashes within a string with the letter the user has guessed.
I think my problem is with the fact the word chosen is randomly chosen from an array and I'm not sure how to go about finding the positions within the randomly chosen string which consists of the guessed character.
I have commented out the area that's causing the issue.
#include <iostream>
#include <array>
#include <string>
#include <stdlib.h>
#include <time.h>
#include <cstddef>
#include <algorithm>
using namespace std;
int main()
{
string words[3] = {"stack", "visual", "windows"};
string guess;
cout << "Welcome to hangman.\n";
cout << "\n";
srand(time(NULL));
int RandIndex = rand() % 3;
string selected = words[RandIndex];
for (int i = 1; i <= selected.size(); i++) {
cout << "_ ";
}
cout << "\n";
cout << "\nType in a letter: ";
cin >> guess;
cout << "\n";
if (selected.find(guess) != string::npos) {
/*for (int i = 1; i <= selected.size(); i++) {
if (selected.find(guess) != string::npos) {
cout << "_ ";
} else {
cout << guess << " ";
}
}*/
} else {
cout << "\nNay!\n";
cout << "\n";
}
cout << "\n";
cout << "\n";
system("PAUSE");
return 0;
}
I was thinking about using the replace() function but the problem I face here is that I'm not replacing the string within selected variable but sort of iterating through the word itself, if that made any sense whatsoever?
Use a second string, that is initialized with the underscores. If the find function doesn't return string::npos it returns the position in the string, and this is the same position you should change in the string with the underscores as well.
You actually need to use a second string to store the "guessed" string; this is because you need to keep track of all the guessed letters and display them.
something like :
string s ="test";
string t=""; //empty string
for(int i=0;i<s.size();i++)
t.append("_"); //initialize the guess string
cout<<t<<'\n';
char c;
cin >> c;
int pos = s.find(c); //get the first occurrence of the entered char
while(pos!=-1) //look for all occurrences and replaced them in the guess string
{
t.replace(pos,1,1,c);
pos = s.find(c, pos+1);
}
I think you need to maintain some extra state while looping - to keep track of which letters have / haven't been guessed.
You could add a new string current_state which is initially set to the same length as the word but all underscores. Then, when the player guesses a letter, you find all instances of that letter in the original word, and replace the underscore with the letter guessed, at all the positions found but in current_state.
First i would initialize a new string to show the hidden word:
string stringToDisplay = string( selected.length(), '_');
Then For each letter given by the user i would loop like this:
(assuming guess is letter)
size_t searchInitPos = 0;
size_t found = selected.find(guess, searchInitPos));
if (found == string::npos)
{
cout << "\nNay!\n";
cout << "\n";
}
while( found != string::npos)
{
stringToDisplay[found] = guess;
searchInitPos = found+1;
found = selected.find(guess, searchInitPos));
}
cout << stringToDisplay;
Hope this will help
I think it should be that:
string words[3] = {"stack", "visual", "windows"};
char guess;
string display;
cout << "Welcome to hangman.\n";
cout << "\n";
srand(time(NULL));
int RandIndex = rand() % 3;
string selected = words[RandIndex];
for (int i = 0; i < selected.size(); i++) {
display.insert(0, "_ ");
}
cout << display;
while(display.find("_ ") != string::npos) {
cout << "\n";
cout << "\nType in a letter: ";
cin >> guess;
cout << "\n";
bool flag = false;
for (int i = 0; i < selected.size(); i++) {
if (selected[i] == guess) {
display.replace(i*2, 1, 1, guess);
flag = true;
}
}
if (!flag) {
cout << "\nNay!\n";
cout << "\n";
} else {
cout << display;
}
}

How to form a string out of multiple chars in a for loop

The first part of my code is used to receive a single string input from the user and replace certain characters in that word using string class member functions. This part was easy for me to figure out, but I can't seem to figure out how to form a new string out of these changed characters since I will need to use this string for further manipulation later on in my code.
This is problematic since the for loop outputs single char variables that can't be manipulated as a single string.
#include <iostream>
#include <string>
using namespace std;
int main(){
string word;
char letter;
int i;
cout << "Enter a word: ";
cin >> word;
cout << "\n";
for ( i = 0; i < word.size(); i++)
{
if ( word.at(i) == 'e')
{
word.at(i) = '3';
}
if ( word.at(i) == 'i' )
{
word.at(i) = '1';
}
if ( word.at(i) == 'x' )
{
word.at(i) = '*';
}
cout << word.at(i);
}
cout << "\n";
}
As my code currently stands, a user might, for example, input the string "cheese" and receive the output ch33s3. However this output is not a string; it is an assortment of chars without a space to separate them. I can't continue my code any further with my for loop output remaining as it currently is.
Edit: I realize now that I already have what I need, but confused myself into thinking the scope wouldn't apply outside my for loop. Thanks for the quick and easy answers.
You were pretty much done already:
#include <iostream>
#include <string>
using namespace std;
int main(){
string word;
char letter;
int i;
cout << "Enter a word: ";
cin >> word;
cout << "\n";
for ( i = 0; i < word.size(); i++)
{
if ( word.at(i) == 'e')
{
word.at(i) = '3';
}
if ( word.at(i) == 'i' )
{
word.at(i) = '1';
}
if ( word.at(i) == 'x' )
{
word.at(i) = '*';
}
}
cout << word << "\n";
}
As it turns out, your work is already done for you. Your variable "word" would hold the value "ch33s3" after the loop ends.
The variable word contains the altered string and can be manipulated as such. It appears that you already have what you need.
Also - you may already know this - but you don't need the "at" function to accomplish what you're doing here. You can index the string like an array. For example:
word[i] = 'e';
cout << word[i];
However this output is not a string
Did you mean to use std::ostringstream instead of std::cout to receive the results?
The word.at(i) = xxx; statements already manipulated the word string, and you have it.
Here's a sample to show how to get a std:string result, without manipulating word directly:
#include <iostream>
#include <string>
#include <sstream>
int main() {
std::string word;
char letter;
int i;
std::cout << "Enter a word: ";
std::cin >> word;
std::ostringstream leetWord;
for ( i = 0; i < word.size(); i++) {
if ( word[i] == 'e') {
leetWord << '3';
}
else if ( word[i] == 'i' ) {
leetWord << '1';
}
else if ( word[i] == 'x' ) {
leetWord << '*';
}
else {
leetWord << word[i];
}
}
// Here you can refer to the ostringstream::str() function to
// get a string
std::string theWantedString = leetWord.str();
std::cout << word << " => " << theWantedString << std::endl;
}
See the working sample.

C++ can't get user input for strtok

I keep running into an issue with this code in C++:
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string words[25];
int i = 0;
char * word;
cout << "Input a phrase, no capital letters please.";
char phrase[100] = "this is a phrase";
word = strtok (phrase, " ,.");
while (word != NULL)
{
i++;
words[i] = word;
cout << words[i] << " ";
word = strtok (NULL, " ,.-");
int g = 0;
}
cout << endl << endl;
int g = 0;
while (g < i)
{
g++;
char f = words[g].at(0);
if ((f == 'a') || (f == 'e') || (f == 'i') || (f == 'o') || (f == 'u') || (f == 'y'))
{
words[g].append("way");
cout << words[g] << " ";
}
else
{
words[g].erase (0,1);
cout << words[g] << f << "ay" << " ";
}
}
cout << endl;
system("PAUSE");
}
I actually want my program user to generate the phrase to be put in char phrase[100] but I can't figure out the proper syntax to initiate input on it without screwing up the translation.
This is a program that translates phrases into pig latin BTW.
What you want is:
char phrase[100];
fgets(phrase, 100, stdin);
Though, as stated in the comments and other answer, you're using C string functions in C++ and this is very odd. You should not do so unless you are required by an assignment or something.
Instead use:
string input;
getline(cin, input);
To tokenize you can do the following:
string token;
size_t spacePos;
...
while(input.size() != 0)
{
spacePos = input.find(" ");
if(spacePos != npos)
{
token = input.substr(0, spacePos );
input = input.substr(spacePos + 1);
}
else
{
token = input;
input = "";
}
// do token stuff
}
Or, to skip all of that jazz:
string token;
while(cin >> token)
{
// Do stuff to token
// User exits by pressing ctrl + d, or you add something to break (like if(token == "quit") or if(token == "."))
}
The preferred way of doing terminal I/O in C++ are streams. Use std::cin and the std::getline function to read strings from input output.
std::string input;
std::getline(std::cin, input);
After that you probably want to get rid of strtok and look at this question to understand how to do string tokenization in C++.