Compare char with char[i] not working in hangman game - c++

I was trying to do a hangman game, my idea was that you give the number of letters and the word, then the program fills a char with _ as letters the word has. Then it asks you a letter and it compares if the letter matches any letter in the word given. Then it replaces the respective _ with the letter, but it doesn't replace it...
What am I doing wrong?
#include <iostream>
#include <conio.h>
#include <cstdlib>
using namespace std;
int main()
{
int game = 0;
int n = 0;
char blank[n - 1];
char palabra[n - 1];
char letra;
cout << "Input the number of letters of the word\n";
cin >> n;
cout << "Input the word\n";
cin >> palabra;
for (int i = 0; i < n; i++) {
blank[i] = '_';
}
while (game != 1) {
for (int i = 0; i < n; i++) {
if (letra == palabra[i]) {
blank[i] = letra;
}
else {
if (blank[i] != '_') {
blank[i] = blank[i];
}
else {
blank[i] = '_';
}
}
}
system("cls");
cout << "\n";
for (int i = 0; i < n; i++) {
cout << blank[i] << " ";
}
cout << "Input a letter" << endl;
cin >> letra;
}
getch();
return 0;
}

int n = 0;
char blank[n - 1];
There are three things wrong with this:
The n is initialized to 0, but then the array will have 0 - 1 length.
The value of n isn't really known until it is input by the user, but you went ahead and declared blank with n-1 entries.
Even if n were initialized to something reasonable, the declaration of
char blank[n - 1];
is not legal C++ syntax. Arrays in C++ must have their size denoted by a compile-time constant, not a runtime variable.
To get rid of these issues, use std::string instead of char arrays.
If you did that, the code would look similar to this:
#include <string>
#include <iostream>
int main()
{
int game = 0;
int n = 0;
std::string palabra;
char letra;
std::cout << "Input the number of letters of the word\n";
std::cin >> n;
std::cout << "Input the word\n";
std::cin >> palabra;
std::string blank(n, '_'); // create a string with n underscores
//...
}
The rest of the code should stay the same. Whether the overall logic of the program is correct, that would be another issue, but at least you do not have the issue with the character arrays.

Related

Check for duplicate characters in C++ Array

I'm trying to create a program where you input 20 characters into an array. Each time you enter a new character, the program should check if that character is already in the array, if it is, print duplicate (but still add the duplicate to the array)
For example, if user types 'a', program should check if 'a' is inside the array.
This is my code:
#include <iostream>
using namespace std;
int main() {
char myAlpha[20];
char input;
cout << "Enter a letter" << endl;
for (int i= 0; i <= 20; i++) {
cin >> input;
for (int k = 0; k <= 20; k++) {
if (myAlpha[k] == input)
cout << "Duplicate" << endl;
}
myAlpha[i] = input;
}
}
I just can't figure out how to make it work, I'm probably missing something stupid. The solution must use something like the code above, no fancy functions or anything.
EDIT: Fixed Code:
#include <iostream>
using namespace std;
int main() {
char myAlpha[20];
char input;
cout << "Enter a letter" << endl;
for (int i= 0; i < 20; i++) {
cin >> input;
for (int k = 0; k < i; k++) {
if (myAlpha[k] == input)
cout << "Duplicate" << endl;
}
myAlpha[i] = input;
}
}
Only problem is that "duplicate" is printed a extra time for each duplication of a letter. For example, if 'a' is entered 3 times, on the 3rd time, "duplicate" is printed 2 times. And so on. But not a big deal.
try this:
#include <iostream>
using namespace std;
int main() {
char myAlpha[20];
char input;
cout << "Enter a letter" << endl;
for (int i = 0; i < 20; i++) {
cin >> input;
myAlpha[i] = input;
for (int k = 0; k < i; k++) {
if (myAlpha[k] == input)
cout << "Duplicate" << endl;
}
}
}
With this line:
char myAlpha[20];
The valid indices of that array are from 0 to 19. However, this line:
for (int i= 0; i <= 20; i++) {
Already implies a bug. Change it to this:
for (int i= 0; i < 20; i++) {
Do the same treatment for the inner for loop line: for (int k = 0; k <= 20; k++) {
But... you'll also need to keep track of how many characters have been inserted instead of looping up to 20 again.
So this is closer to what you want:
int main() {
char myAlpha[20];
char input;
cout << "Enter a letter" << endl;
int inserted = 0;
while (inserted < 20) {
cin >> input;
bool duplicate = false;
for (int k = 0; k < inserted; k++) {
if (myAlpha[k] == input) {
cout << "Duplicate" << endl;
duplicate = true;
break; // no point in continuing to look for duplicates once the first one is found
}
}
if (!duplicate) {
myAlpha[inserted] = input;
inserted++;
}
}
}
Even faster and you can avoid the inner for-loop:
int main() {
bool duplicates[256] = {};
char myAlpha[20] = {};
char input;
cout << "Enter a letter" << endl;
int inserted = 0;
while (inserted < 20) {
cin >> input;
bool duplicate = duplicates[(unsigned char)input];
if (duplicate) {
cout << "Duplicate" << endl;
}
else {
myAlpha[inserted] = input;
inserted++;
duplicates[(unsigned char)input] = true;
}
}
}

How to move word in a circular motion in a string?

I have a string that contains X words (between each word there is a space) I have to move the words in a circular motion to the left according to the number that the user inserts. For example:
"hi my name is aviv and",
the user entered 2. "name is aviv and hi my" I'm looking for legality that repeats itself but I can not find.
Thanks for the guidance. Most importantly, I can not use built-in libraries
Update:
I see there are examples with libraries, I can not use any library.
So what I've done so far.
I wrote a function that gets a string and a number from the user, to move left.
Before sending the string to the function I try to calculate the number of characters I need to move.
My output is - "name is avivhi my"
Regarding the function:
When it gets a string without spaces it works great.
This is my code:
int main()
{
char str[] = "hi my name is aviv";
char str2[] = "hi my name is aviv";
int CountSpace = 0, CountWord = 0;
int Size = 18, flag = 0;
int MoveLeft, Index = 0;
for (int i = 0; str[i] != '\0'; i++)
{
if (str[i] == ' ')
{
CountSpace++;
}
}
CountWord = CountSpace + 1;//Understand how many words there are in a string.
cin >> MoveLeft;
if (MoveLeft >= CountWord)//
{
MoveLeft = (MoveLeft - ((MoveLeft / CountWord) * CountWord));//the size of movment;//To reduce the amount of moves if there is such a possibility
}
for (int i = Size - 1; i >= 0; i--)
{
if (str[i] == ' ')
{
flag++;
}
if (flag == MoveLeft)
{
Index = Size - 1 - (i + 1);//That's the amount of characters I have to move
break;
}
}
MoveLeft = Index;
//This code belongs to the function that accepts a string and the amount to move the characters
for (int i = 0; i < Size; i++)
{
if (i + MoveLeft < Size)
{
str[i] = str2[i + MoveLeft];
}
else
{
str[i] = str2[(i + MoveLeft) - Size];
}
}
cout << "Move Left: " << MoveLeft << endl << str << endl << str2 << endl;
return 0;
}
Here's a hint:
vector<string> words = Your_Code_To_Split_Input_Into_Words();
int count = words.size();
int shift = Your_Code_To_Read_Users_Input();
// print the sentence with the rotation specified by shift
for (int i = 0; i < count; i++)
{
int shifted_index = (i + shift) % count; // modulo math implements circular rotation
string spacing = (i == 0) ? "" : " "; // add a space before each word, except first word
cout << spacing << words[shifted_index];
}
cout << endl;
One possible answer, i highly recommend using vectors instead of regular arrays, it's easy and more dynamic, but i didn't use it because you said you can't use built-in libraries.
#include <iostream>
#include<string>
using namespace std;
int main() {
string a[10000];
int counter = 0;
string b = "hi my name is aviv and";
string temp = "";
int userNum = 2;
for(int i=0;i<b.length() ; i++){
if(b[i]!=' '){
temp+=b[i];
}
else if(b[i]==' ' && temp.length()){
a[counter]= temp;
temp = "";
counter++;
}
}
if(temp.length()){
a[counter] = temp;
}
for(int i=userNum;i<=counter+userNum;i++){
cout<<a[i%(counter+1)]<<endl;
}
}
If you can make use of std::rotate() from <algorithm>, this is much easy to do with that. Parse the words using std::stringstream and store to std::vector. Then apply the shif directly to the vector.
Sample Output: https://www.ideone.com/rSPhPR
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <sstream>
int main()
{
std::vector<std::string> vec;
std::string str = "hi my name is aviv and";
std::string word;
std::stringstream sstr(str);
while(std::getline(sstr, word,' '))
vec.emplace_back(word);
int shift;
std::cout << "Enter the Shift: ";
std::cin >> shift;
std::rotate(vec.begin(), vec.begin() + shift, vec.end());
for(const auto& it: vec)
std::cout << it << " ";
return 0;
}
Here's a snippet :
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
#define MaxWords 10
int main()
{
stringstream ss;
ss.str("hi my name is aviv and");
string str[MaxWords];
int i;
for (i =0; std::getline(ss, str[i],' ');i++ )
{
cout << str[i] << " ";
}
int n;
cout << "\nEnter pos to split : ";
cin >> n;
for (int j = n; j <= i; j++)
{
cout << str[j] << " ";
}
for (int j = 0; j < n; j++)
{
cout << str[j] << " ";
}
cout << endl;
return 0;
}
Output:

why does my counter increase according to the lens of char input in C++

I'm picking up on C++ recently and is trying to code a program which prompts for names for a defined no. of times and inserts each of the input into an array of size-5. The problem happened when I tried to run the following code, my counter, i increases according to the no of len the user input. Why is that so?
#include <iostream>
using namespace std;
int main(){
const int SIZE = 5;
char name[SIZE];
int i;
for (i = 0; i < SIZE; i++){
if (strlen(name) <= 50) {
cout << "Enter a name: \n";
cin >> name[i];
}
}
for (i = 0; i < SIZE; i++){
cout << name[i] << endl;
}
return 0;
}
Output:
if (strlen(name) <= 50) {
You should not call strlen on array which is not initialized.
Use array of strings otherwise
cout << name[i] << endl;
refers to i-th character, not entire string. Or if you want to go with char arrays, you'd need a two dimensional array.
I thing what you indended to do was :
#include <iostream>
using namespace std;
int main(){
const int SIZE = 5;
string names[SIZE];
int i;
for (i = 0; i < SIZE; i++){
cout << "Enter a name: \n";
string name;
cin>>name;
if (strlen(name) <= 50) {
cin >> names[i];
}
}
for (i = 0; i < SIZE; i++){
cout << name[i] << endl;
}
return 0;
}
UNTESTED
The second for loop, which does the output, does this in single characters, incrementing i each time.
To output the string all at once assign a string pointer to name[0] and send that to cout.

printing a char array backwards c++ using loops

i am trying to print an array of unknown length backwards so wrote that the loop should start at the terminator and go to the first letter printing each letter but it keeps printing only the first
#include <iostream>
using namespace std;
int main()
{
char word[10];
int i;
cout << "Enter a word: " ;
cin >> word;
for ( word[i]= '\0'; word[1] <0; word[i] --)
{
cout << word[i] << endl;
}
return 0;
}
You can print you C-style string backwards whith this one-liner:
reverse_copy(word,word+strlen(word),ostream_iterator<char>(cout));
Also please consider using std::string:
string word;
cin >> word;
copy(word.rbegin(),word.rend(),ostream_iterator<char>(cout));
You will need to #include the following headers for the above examples to work:
<algorithm>, <iostream>, <iterator>, <string> and <cstring>
Replace your loop it does nothing:
for (i= strlen(word); i >=0; i--)
{
cout << word[i] << endl; //endl is optional
}
Also for in case of long strings you may have to increase size of char array or its better to use
string word;
for (i= word.size(); i >=0; i--)
{
cout << word[i] << endl; //endl is optional
}
Here is a simple way to print a C-style string backwards.
for (size_t i = 0, i_end = std::strlen(word); i != i_end; ++i)
{
std::cout << word[i_end - i - 1];
}
std::cout << "\n";
Note that I save the result of strlen so that it is not called every time.
To get the result you want, you might want to use this code...
char word[10];
int sz;
do {
cout << "Enter a word: ";
cin >> word;
sz = strlen(word);
} while (sz > 10);
for (int i = sz; i >= 0; i--)
{
cout << word[i];
}

Unexpected cin behavior

I am writing a function int count_words(string str) that returns a count of all of the words in the string.
The issue is that regardless of the input, the result is 1. Can anyone help?
#include <iostream>
#include <string>
using namespace std;
int count_words(string str)
{
int i,j;
j = 1;
int l = str.length();
for(i = 0; i < l; i++)
{
string c = str.substr(i,1);
if(c == " ")
{
j++;
}
}
cout << "The total word in the string: " << j << endl;
return j;
}
int main()
{
string str;
cout << "Please enter a string: ";
cin >> str;
int result = count_words(str);
return 0;
}
You should use cin.getline if your string contains spaces, as using the >> operator with cin only reads up to the next whitespace
See std::cin input with spaces?
Consider iterating over the string:
auto cstyle= str.c_str();
for (int i = 0; i < str.length(); ++i)
{
if (cstyle[i]==' ')//assumes words are delimited by a single space
{
j++;
}
}
You should use: cin.getline, for example:
int main()
{
cout << "Please enter a string: ";
unsigned size=10;
char*chr=new char[size];
cin.getline(chr,size);
string str(chr);
//cin >> str;
int result = count_words(str);
return 0;
}