For my assignment, I have to call a function that takes the user input and spits out the number of non-whitespace characters. Inside the program, I have this code:
int GetNumOfNonWSCharacters(const string givenText) {
int counter;
for (int i = 0; i < givenText.length(); i++) {
if (givenText.at(i) != ' ') {
counter++;
}
}
return counter;
}
When I return the counter integer, this is how I output it with the string sampleText being the input:
if (menuInput == 'c' || menuInput == 'C') {
cout << "Number of whitespaces: " << GetNumOfNonWSCharacters(sampleText) << endl;
}
It returns an answer like 1231341235 or something along those lines. Now, when I type this code into a different file, pretty sure it's identical, I get the correct result every time:
int NumNonWhitespaces(const string userInput) {
int counter;
for (int i = 0; i < userInput.length(); i++) {
if (userInput.at(i) != ' ') {
counter++;
}
}
return counter;
}
int main() {
string userString;
cout << "Enter some text" << endl;
getline(cin, userString);
cout << "You entered: " << userString << endl;
cout << NumNonWhitespaces(userString);
return 0;
}
Does anyone have a solution to the problem ?
There is even more simple way to count the number of non white spaces by using the STL count algorithm:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main() {
string userString;
cout << "Enter some text" << endl;
getline(cin, userString);
cout << "You entered: " << userString << endl;
//count the number of white spaces
int numberOfWhiteSpace = count(userString.begin(), userString.end(), ' ');
//substruct that number from the total length of your string
cout << "number of non-whitespace: " << userString.length() - numberOfWhiteSpace;
return 0;
}
But in your solution you have to initialize the variable counter to 0
If you use counter without initializing it first, you'll get whatever junk memory existed at its memory address before your program started using it (C++ does not automatically zero-out the memory when you declare a variable). The fact it works when you copy it into a new file is purely coincidental.
The fix is simply to initialize counter to 0 before using it:
int counter = 0;
In some programming languages if a variable is allocated but not assigned, it is said to have a "garbage value" , that is, some information that was being held any random piece of the computer's memory. So initialize the counter variable to 0
You have to initialise the counter variable otherwise it will contain any old value.
int counter=0;
Related
It's the first time I'm trying something with String Arrays in C++ and yep... I'm stuck.
I'm trying a small programm which will let the user enter max. 10 random Names. If the user enters '.' or has entered 10 nNames the input dialog will end. After he has done this all names will be printed out.
I tried it with a vector, but I guess I be doing something completely wrong...
#include <iostream>
#include <vector>
using namespace std;
int main()
{
char name;
int i, counter;
vector<string> namen_vec;
cout << endl << "Eingabedialog von maximal 10 Namen. " << endl;
cout << "Eingabe kann fruehzeitig mit '.' beendet werden. " << endl;
cout << "--------------------------------------------------" << endl << endl;
counter = 0;
do
{
cout << "Eingabe Name: ";
cin >> name;
namen_vec.push_back(name);
counter++;
} while (name != '.' && counter <= 9);
for (int i = 0; i < namen_vec.size(); i++)
{
cout << namen_vec[i] << endl;
}
return 0;
}
Maybe someone has one or two advices?
First of all, you have declared the variable name as char but your container vector namen_vec accepts a string. Still, the program won't be compiled successfully because the following line
while (name != '.' && counter <= 9);
as name would be a string then you have to change this as
while (name != "." && counter <= 9);
The function is called as: Perm( "xyz", "abc" ); then it would print:
xyzabc xyzacb xyzbac xyzbca xyzcab xyzcba
The xyz is fixed and has all permutations of abc concatenated to it.
I started a for Loop to deal with the general case, and part of the base case but I am having a hard time figuring out where I am going wrong.
#include <string>
#include <iostream>
using namespace std;
void Perm(string fixedPart, string permPart)
{
if (permPart.length() == 1) {
cout << fixedPart << permPart << endl;
}
else {
for (int i = 0; i < permPart.length() - 1; i++) {
Perm(fixedPart + permPart[i] ,
permPart.substr(0, i) + permPart.substr(i + 1,permPart.length()-1));
}
}
}
int main(){
// Don't touch main!!!
string s;
cout << "Enter a String: ";
cin >> s;
cout << s << endl;
cout << "Perms are: " << endl;
Perm("xyz", s);
}
Problem is not with base case, Just change the for loop condition to
i < permPart.length()
last character also should be swapped with other characters in the permutation
This is for an intro c++ class, the prompt reads:
Print the number of words that begin with a certain character. Let the user enter that character.
Although, I'm not sure how to do this.
Do I use parsing strings? I tried this because they inspect string data type but I kept getting errors so I took it out and changed it to characters. I want to learn how to do the "total_num" (total number of words that start with the letter the user chooses) and I also need some help with my for loop.
Example of desired output
user types in: a
outputs: "Found 1270 words that begin with a"
user types in: E
outputs: "Found 16 words that begin with E"
user types in: #
outputs: "Found 0 words that begin with #"
(I think I got this part down for non-alphabetical)
The data is from a file called dict.txt, it's a list of many words.
Here's a small sample of what it contains:
D
d
D.A.
dab
dabble
dachshund
dad
daddy
daffodil
dagger
daily
daintily
dainty
dairy
dairy cattle
dairy farm
daisy
dally
Dalmatian
dam
damage
damages
damaging
dame
My program:
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
const int NUM_WORD = 21880;//amount of words in file
struct dictionary { string word; };
void load_file(dictionary blank_array[])
{
ifstream data_store;
data_store.open("dict.txt");
if (!data_store)
{
cout << "could not open file" << endl;
exit(0);
}
}
int main()
{
dictionary file_array[NUM_WORD];
char user_input;
int total_num = 0;
load_file(file_array);
cout << "Enter a character" << endl;
cin >> user_input;
if (!isalpha(user_input))
{
cout << "Found 0 that begin with " << user_input << endl;
return 0;
}
for (int counter = 0; counter< NUM_WORD; counter++)
{
if (toupper(user_input) == toupper(file_array[counter].word[0]));
//toupper is used to make a case insensitive search
{
cout << "Found " << total_num << " that begin with " << user_input << endl;
//total_num needs to be the total number of words that start with that letter
}
}
}
There are a few things you can do to make your life simpler e.g. using a vector as the comment suggested.
Let's look at your for loop. There are some obvious syntax problems.
int main()
{
dictionary file_array[NUM_WORD];
char user_input;
int total_num = 0;
load_file(file_array);
cout << "Enter a character" << endl;
cin>>user_input;
if(!isalpha(user_input))
{
cout << "Found 0 that begin with " << user_input << endl;
return 0;
}
for(int counter = 0;counter< NUM_WORD; counter++)
{
if (toupper(user_input) == toupper(file_array[counter].word[0]));
// ^no semi-colon here!
//toupper is used to make a case insensitive search
{
cout<< "Found " << total_num << " that begin with "<<
user_input << endl;
//total_num needs to be the total number of words that start with that letter
}
}//<<< needed to end the for loop
}
Let's get the for loop right. You want to count the matches in a loop and then report when you have finished the loop.
int total_num = 0;
//get character and file
for(int counter = 0;counter< NUM_WORD; counter++)
{
if (toupper(user_input) == toupper(file_array[counter].word[0]))
^^^no semi-colon here!
{
++total_num;
}
}
cout<< "Found " << total_num << " that begin with "<< user_input << endl;
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;
}
}
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.
}