Letter guessing game in C using if else statements - c

I'm new to programming and am trying to do this guessing game by a simple C program below. When I input letters from the word "apple", every letter (p,l,e) executes the wrong guess try again statement except for the letter 'a'. I can't seem to understand what I'm doing wrong here. Any insights is highly appreciated.
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#define size 10
int main() {
// initialize variables
char word[size] = "apple";
char guess;
char arrayofdashes[size] = "_____";
printf("guess a letter \n");
// input loop
for (int i = 0; i < strlen(word); i++)
{
scanf(" %c", &guess);
for (int j = 0; j< strlen(word); j++ )
{
if (guess == word[j])
{
arrayofdashes[j] = guess;
printf("%s \n", arrayofdashes);
}
else
{
printf("wrong guess. Try again \n");
break;
}
}
}
}

Remove the break and add a flag variable to check the correctness of the input letter. And you need a better way to check if the word spelling is complete.
char flag;
int count = 0;
// input loop
while (count < strlen(word))
{
scanf(" %c", &guess);
flag = 0;
for (int j = 0; j< strlen(word); j++ )
{
if (guess == word[j] && guess != arrayofdashes[j])
{
arrayofdashes[j] = guess;
count++;
flag = 1;
}
}
if (flag)
printf("%s \n", arrayofdashes);
else
printf("wrong guess. Try again \n");
}

the problem is that you're using break - this drops out of your inner for-loop after comparing your input against the first character, and prevents it from being compared with subsequent characters.
What strategies have you tried for debugging this yourself? You'll have a few more changes to make aside from removing break, but figuring them out is part of the fun

for (int j = 0; j < strlen(word); j++)//no two loop
{
scanf(" %c", &guess);
if (guess == word[j])
{
arrayofdashes[j] = guess;
printf("%s \n", arrayofdashes);
}
else
{
printf("wrong guess. Try again \n");
j--;
}
}
You don't need the input loop. And if the answer is not correct you should subtract one from j.

Related

String Sort and remove Duplicates

First I apologize for any mistype, for I am Brazilian and English is not my native language.
I am a freshman at my college and I got this algorithm to solve, from my teacher:
Make a program that creates a vector of n words, n being a size entered by the user (maximum 100). Your program should remove all duplicate words from the input vector and sort the words. Print the final vector without repeated and ordered words.
E.g. with 7 words to sort:
Input: 7 [enter]
hand ear leg hand hand leg foot
Output: ear foot hand leg
Note: Comment the program prints so that the output of the program is as shown in the example above (the numbers are separated by a spacebar, without space after last digit).
Note2: In case of invalid entry the program should print: "invalid entry" (all lower case).
Ok, I got it working but the I got confused with the notes and I can't find a way to fix the possible bugs, here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char word[100][100], aux[100];
int i, j, num;
printf("Type how many words you want to order: ");
do
{
scanf("%d", &num);
}while (num>100 || num<=0);
for(i=0; i<num; i++)
scanf("%s",&word[i]);
for (i = 0; i < num; i++) //loop to sort alphabetically
{
for (j = i+1; j < num; j++)
{
if ((strcasecmp(word[i], word[j]) > 0)) //swapping words
{
strcpy(aux, word[j]);
strcpy(word[j], word[i]);
strcpy(word[i], aux);
}
}
}
for (i = 0; i < num; i++) //loop to remove duplicates
{
if ((strcasecmp(word[i], word[i+1]) == 0)) //finding the duplicates
{
for (j = i+1; j < num; j++) //loop to delete it
strcpy(word[j], word[j+1]);
num--;
i--;
}
}
printf("\nWords sorted and without duplicates:\n");
for(i=0; i<num-1; i++)
printf("%s ", word[i]); //output with spacebar
printf("%s", word[num-1]); //last output without spacebar
return 0;
}
When I type a word with more than 100 characters, the Code::Blocks closes with an error, else it works fine. What do you think I should change?
The teacher uses a Online Judge (Sharif Judge) to evaluate if the code is right, and I got error in 3 of the tests (that are not specified), all of them were "Time Limit Exceeded". Maybe it has do to with the size of the matrix, or the problem with words >100.
Thanks in advance, Vinicius.
I guess you input sanity check is causing the issue.
As mentioned in the comment section.
If n is always < 100. Definitely your sorting is not causing any time limit exceeded.
Looks like the n is given something greater than 100 and your scanf is waiting and causing the issue. Also, make sure your input numbers are taken properly. If the input is > 100 print 'invalid entry'.
Something like below should work.
scanf("%d", &num);
if (num > 100)
printf("invalid entry");
for (i = 0; i < num; i++) {
scanf("%s", word[i]);
if (strlen(word[i])>100)
printf("invalid entry");
}
Hope it helps!
of course you will get an error if you use woerds more than 100 length casue you
have this line: char word[100][50], aux[100];
that means that you word length limit is set to 50. use word[100][100];
also you may not delete duplicates, just skip them in output
lol of course if youre using judge , you should not output any symbols except the answer, this means you should delete all lines, like :
printf("Type how many words you want to order: ");
and check the input format, and check limitations, i mean max word length , max amounts of words
try smth like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define max_word_length = 101;
#define max_amount_of_words = 101;
int main() {
char word[max_amount_of_words][max_word_length] = {};
char aux[max_word_length];
int i, j, num;
scanf("%d", &num);
if (num < 0 || num > 100) {
printf("invalid entry");
return 0;
}
for (i = 0; i < num; i++) {
scanf("%s", word[i]);
}
for (i = 0; i < num; i++) {//loop to sort alphabetically
for (j = i + 1; j < num; j++) {
if ((strcasecmp(word[i], word[j]) > 0)) { //swapping words
strcpy(aux, word[j]);
strcpy(word[j], word[i]);
strcpy(word[i], aux);
}
}
}
bool is_joint = false;
for (i = 0; i < num; i++) { //loop to skip duplicates
if ((strcasecmp(word[i], word[i + 1]) != 0)) { //if there is a duplicate , we willnot output it
if(is_joint) printf(" ");
printf("%s ", word[i]);
is_joint = true;
}
}
return 0;
}
I got 100% on Judge, I fixed the code and looks like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char word[101][101],aux[101]; //a number higher than the limit to comparisons
int i,j,num;
scanf("%d",&num);
if(num<=0||num>100){ // if words < 0 or >100
printf("invalid input");
return 0;
}
for(i=0;i<num;i++){
scanf("%s",&word[i]); //read n words
if(strlen(word[i])>100){ //if word >100 caracters
printf("invalid input");
return 0;
}
for(j=0;j<strlen(word[i]);j++){
if (word[i][j]>=65&&word[i][j]<=90){
word[i][j]= word[i][j]+32; // if word is uppercase, make them lowcase
}
else if (word[i][j]>122||word[i][j]<97){// if word is different from alphabet lowercase
printf("invalid input");
return 0;
}
}
}
for(i=0;i<num;i++){
for(j=i+1;j<num;j++){
if((strcmp(word[i],word[j])>0)){ //loop to sort words
strcpy(aux,word[j]);
strcpy(word[j],word[i]);
strcpy(word[i],aux);
}
}
}
for(i=0;i<num-1;i++){
if((strcmp(word[i],word[i+1])!=0)){ // output words with spacebar, without the last one
printf("%s ",word[i]);
}
}
printf("%s",word[num-1]); // last word without spacebar
return 0;
}
Thank you everyone who tried to help, I've learned a lot with your suggestions!
This project is actually pretty tough assignment for a programmer who just
started in C.
Run this program in your computer.
Before running against the Judge, make sure you run many times with your manual inputs. Once you are happy with the tests, try against the Judge.
Like I said, the hardest part is storing the user's inputs according to spec (accepting space or newline characters in multiple lines).
#include <stdio.h>
#include <string.h>
int
main(void)
{
int iNumW, iIndex;
int iWCnt = 0;
int iC;
char caTemp[100];
char caWords[100][100];
char *cpDelimeter = " \n";
char *cpToken;
char *cp;
short sIsWord = 1;
char caGarbage[100];
scanf("%d", &iNumW );
fgets(caGarbage, sizeof caGarbage, stdin); //Remove newline char
//Get word inputs
while( iWCnt < iNumW )
{
fgets(caTemp, sizeof caTemp, stdin );
for( cpToken = strtok( caTemp, cpDelimeter ); cpToken != NULL; cpToken = strtok( NULL, cpDelimeter)){
cp = cpToken;
while( *cp ){
sIsWord = 1;
//Check if alphabet
if( !isalpha(*cp) ){
sIsWord = 0;
break;
}
cp++;
}
if( sIsWord ){
strcpy( caWords[iWCnt], cpToken );
//printf( "%s\n", caWords[iWCnt]);
iWCnt++;
if( iWCnt >= iNumW ) break;
} else {
printf("invalid entry.\n");
}
//printf("%d\n", iWCnt);
}
}
int i,j ;
for (i = 0; i < iWCnt; i++) {//loop to sort alphabetically
for (j = i + 1; j < iWCnt; j++) {
if ((strcasecmp(caWords[i], caWords[j]) > 0)) { //swapping words
strcpy(caTemp, caWords[j]);
strcpy(caWords[j], caWords[i]);
strcpy(caWords[i], caTemp);
}
}
}
for (i = 0; i < iWCnt; i++) { //loop to skip duplicates
if ((strcasecmp(caWords[i], caWords[i + 1]) != 0)) { //if there is a duplicate , we willnot output it
printf("%s ", caWords[i]);
}
}
return 0;
}

Checking if all elements in array are zero

I'm having trouble determining if two words entered are anagrams.
#include <stdio.h>
#include <string.h>
int main() {
char ch;
int letter_count[26] = {0};
int i;
int sum = 0;
printf("Enter first word: ");
do
{
scanf("%c", &ch);
letter_count[ch - 'a']++;
} while (ch != '\n');
for(i = 0; i < 26; i++)
printf("%d ", letter_count[i]);
printf("\n");
printf("Enter second word: ");
do
{
scanf("%c", &ch);
letter_count[ch - 'a']--;
} while (ch != '\n');
for(i = 0; i < 26; i++)
printf("%d ", letter_count[i]);
for(i = 0; i < 26; i++)
if(letter_count[ch] != 0)
sum++;
if (sum == 0)
printf("anagrams");
else
printf("not anagrams");
}
I have to use the do while part of the code. I can enter the two words, and it prints out the elements in the array, so that "Mattress" and "Smartest" together would have all the elements be zero. However, I'm having trouble with the last part, which is to use a third loop to check whether all the elements are zero.
I figured I could declare an int before hand and have it increment whenever an element wasn't zero, and I could just have any sum greater than zero not be an anagram. However, it always prints out anagram for me.
In your third loop, using letter_count[ch] will not check the entire array. You should iterate through the array using the loop variable i. That part of the code should be:
for (i=0; i<26; i++)
if (letter_count[i] != 0)
sum++;
To handle both upper case and lower case letters, use topper() or to lower() in <ctype.h> to avoid out-of-bound access.
#include <stdio.h>
#include <string.h>
#include <ctype.h> // <---
int main() {
char ch;
int letter_count[26] = {0};
int i;
_Bool bad = 0;
printf("Enter first word: ");
do
{
scanf("%c", &ch);
if(!isalpha(ch)) // <---
{
puts("Not a letter");
continue;
}
letter_count[tolower(ch) - 'a']++; // <---
} while (ch != '\n');
for(i = 0; i < 26; i++)
printf("%d ", letter_count[i]);
printf("\n");
printf("Enter second word: ");
do
{
scanf("%c", &ch);
if(!isalpha(ch)) // <---
{
puts("Not a letter");
continue;
}
letter_count[tolower(ch) - 'a']--; // <---
} while (ch != '\n');
for(i = 0; i < 26; i++)
printf("%d ", letter_count[i]);
printf("\n"); // <---
for(i = 0; i < 26; i++)
if(letter_count[i] != 0)
{
bad = 1;
break; // <---
}
if (bad == 0)
printf("anagrams");
else
printf("not anagrams");
}
Take a look at all places marked // <---.

While loop runs once

I am trying to run a program that will repeatedly read a letter from the user, with the most being entered as 12. If the user enters a sentinel value that they input, the loop should terminate. However, as soon as the first character is read in the loop, it terminates.
Also, the program will place the same word in the reverse order in another array, then check them to see if the first array (read forward), is the same as the other array (read backward). If it is, it displays that the word is a palindrome.
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
int main()
{
int charCount, counter, i, temp, check,check2;
char letter[12], letter2[12];
charCount = 0;
counter = 10;
check = 0;
i = 1;
check2 = 0;
printf("Enter your sentinel value.:");
scanf_s(" %c", &letter[check2]);
while ((i<13) && (letter[i] != letter[check2]))
{
printf("Enter individual letters in word (in order).:");
scanf_s(" %c", &letter[i]);
charCount++;
if (letter[i] == letter[check2])
{
break;
}
i++;
}
printf("Letters entered:%i\n", charCount);
for (i = 0; i < charCount; i++)
{
letter2[i] = letter[i];
}
for (i = 0; i <= (charCount / 2); i++)
{
temp = letter2[counter];
letter2[counter] = letter2[i];
letter2[i] = temp;
counter--;
}
for (i = 0; i <= charCount; i++)
{
if (letter[i] = letter2[i])
{
check++;
}
}
if (check = charCount)
{
printf("Word is a palindrome.\n");
}
system("PAUSE");
return 0;
}
the letter[1] value will be unassigned when the while loop enters for the first time right ? I think you can take that condition out of the while loop since you are considering it in the if statement inside the while loop

Hangman in C. Questions regarding arrays and strings

Ok so this is my code. I'm supposed to make a program that asks from one player a word and requests from the other one to find it, guessing one letter at a time. So basically, Hangman. My questions are these:
The SCounter variable increases to random numbers when I try to increase it by one. I've tried thinking about it and I don't know why. For example, when the guess word is Kala(Greek for "Good/Fine"), SCounter equals to wrong amount of letters when I type guess any letter after the first.
My second question is in regards to guess. My program only works when I write char guess[2]. When I write char guess[0] it loops forever. I don't underestand why.
int main(int argc, char *argv[]) {
SetConsoleOutputCP(1253);
int i = 0;
start :printf("Enter the guess word: ");
char word[25], sword[25];
char guess[2];
char alphabet[28] = {"abcdefghijklmnopqrstuvwxyz "};
int Counter = 6;
int SCounter = 0;
gets(word);
for (i=0; i<strlen(word); i++){
sword[i]='-';
}
while(Counter != 0)
{
printf("So far: ");
for(i = 0; i < strlen(alphabet); i++)
{
printf("%c", alphabet[i]);
}
printf("\n");
printf("Guess a character: ");
gets(guess);
printf("\n");
for(i = 0; i < strlen(word); i++)
{
if(word[i] == guess[0])
{
sword[i] = guess[0];
}
/*else
{
Counter--;
printf("You only have %d wrong guesses left.\n", Counter);
}*/
}
for(i = 0; i < strlen(sword); i++)
{
if (word[i]==sword[i]){
SCounter++;
}
printf("%c", sword[i]);
}
printf("\n");
printf("%d letters found so far.", SCounter);
printf("\n");
for(i = 0; i < strlen(alphabet); i++)
{
if (strlen(guess)<2)
{
if(alphabet[i] == guess[0])
{
alphabet[i] = '-';
}
}
}
if (SCounter == strlen(word)){
Counter = 0;
}
if (strcmp(word, sword)==0){
printf("Congratulation Player 1! You win!\n");
goto start;
}
}
return 0;
}
It looks like the SCounter variable is not reset to zero between iterations, so it keeps growing.
Move the declaration / initialization of SCounter to the scope where it is used to fix this problem:
int SCounter = 0; // This is where the declaration should be
// Remove the declaration of SCounter at the outermost scope.
for(i = 0; i < strlen(sword); i++)
{
if (word[i]==sword[i]){
SCounter++;
}
printf("%c", sword[i]);
}
Here are a few notes on the rest of your program:
Using goto is not going to score extra points with your instructor. To many, this is a red flag; consider rewriting without goto.
The gets function is inherently unsafe. Please refrain from using it for new development. Use fgets(guess, 2, stdin); instead.

int array doesnt get char values

I am absolutely brand new at programming and im not sure how to explain what im doing here.
The whole purpose of this piece is to enter values and then print them out in the same order. Now I wanna quit from entering values when pressing 'q' and so I have to scanf for chars but when I assign them back to the int array the values are not the same.
Hope that makes any sense to you but in any case heres my code:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 5000
define flush fflush(stdin)
main() {
int input[SIZE] = {0},i = 0;
int counter = 0;
char inputs, quit;
do {
system("cls");
printf("Input number ('q' to quit and display numbers entered): ");
flush;
scanf("%c",&inputs);
flush;
if (inputs == 'q')
quit = 'q';
else {
input[i] = inputs;
counter++;
i++;
}
} while (i < SIZE && quit != 'q');
for(i = 0; i < counter; i++){
printf("%i.%i\n", i + 1, input[i]);
}
system("pause");
}
Ive been trying to do this on my own btw and also researched some information online regarding chars but couldnt find anything that would help me. Thanks a lot in advance.
You should nor be getting integer through %c neither assign char values to integers variables when that is not the intention, rather you should approach something like this
i = 0;
do {
printf("Enter a number: ");
scanf("%d", &input[i]);
i++; counter++;
printf("Do you want to continue? (y/n) : ");
scanf("%c", &inputs);
} while(inputs == 'y');
or u can get the number of integer inputs upfront and loop to get that much integers.
try instead (using your original code as much as possible):
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define SIZE 5000
int main()
{
int input[SIZE] = {0},i = 0;
int counter = 0;
char inputs[32];
bool quite = false;
do
{
system("cls");
printf("Input number ('q' to quit and display numbers entered): ");
// read a string from user, then convert when appropr
fgets(stdin, sizeof(inputs), inputs);
if (inputs[0] == 'q')
{
quit = true;
}
else if ( isdigit(inputs[0]) )
{
input[i] = atoi(inputs); // this will disregard any ending \n
counter++;
i++;
}
}
while (i < SIZE && !quit);
for(i = 0; i < counter; i++)
{
printf("%i.%i\n", i + 1, input[i]);
}
system("pause");
}
Another variant. This one will read in characters regardless of the use of whitespaces, since it uses getchar() rather than scanf(). I'm not sure if this is what you want. It seems as though you want integers but are reading characters. So this solution may be completely off base.
#include <stdio.h>
#include <stdlib.h>
#define SIZE 5000
int main()
{
char input[SIZE] = {0};
int i = 0;
int counter = 0;
char inputs;
printf("Input number ('q' to quit and display numbers entered): ");
while (((inputs = getchar()) != EOF) && (counter < SIZE))
{
if (inputs == 'q')
break;
input[counter] = inputs;
counter++;
}
for(i = 0; i < counter; i++)
{
printf("%c\n", input[i]);
}
system("pause");
return 0;
}
If you do really want ints, this one should work.
Notice that the atoi() function can be used to convert a C-string to an int.
The fgets() function is used to read the C-string from STDIN. However, scanf("%s", input); would also work here, as opposed to the scanf("%c", &inputs); that you used.
#include <stdio.h>
#include <stdlib.h>
#define INPUT_SIZE 1000
#define SIZE 5000
int main()
{
char input[INPUT_SIZE] = {0};
int numbers[SIZE] = {0};
int i = 0;
int counter = 0;
while ((fgets(input, sizeof(input), stdin) != NULL) && (counter < SIZE))
{
system("cls");
printf("Input number ('q' to quit and display numbers entered): ");
if (input[0] == 'q')
break;
numbers[counter] = atoi(input);
counter++;
}
for(i = 0; i < counter; i++)
{
printf("%i\n", numbers[i]);
}
system("pause");
return 0;
}

Resources