Is there a way to check if a letter appears in a string. I am trying with the following but it seems to scan only the first letter, even though it is put in a for loop. Any suggestions?
//function prototypes
char checkifletterisinword();
char guess();
int main()
{
char *thesecretword[15];
char guessedletter;
char *guessedword[15];
*thesecretword = "stackoverflow";
guessedletter = guess();
checkifletterisinword( thesecretword, guessedletter );
return 0;
};
//----functions
char checkifletterisinword( char **thesecretword, char *guessedletter )
{
for ( int i=0; i!='\n'; i )
{
if ( guessedletter == *thesecretword[i] )
{
printf( "The letter %c is in the word", guessedletter );
}
else
{
printf( "The letter %c is not in word", guessedletter );
}
return 0;
}
};
char guess()
{
char temp;
printf( "Guess a letter...\n" );
temp = getchar();
getchar();
return temp;
};
CodePudding user response:
Yes, use the strchr
function.
Syntax: char *strchr(const char *str, int character);
. First argument should be the string you need to check and second argument should be the character.
#include <stdio.h>
#include <string.h>
int main ()
{
char string[55] ="This is a string for testing";
char *p;
p = strchr (string,'i');
printf ("Character i is found at position %d\n",p-string 1);
printf ("First occurrence of character \"i\" in \"%s\" is" \
" \"%s\"",string, p);
return 0;
}
CodePudding user response:
You can use the strchr function or you can implement it on your own. In your code the condition i!=‘\n’ isn’t correct because you are comparing a int variabile to a character. Then inside the for you are returning 0(pay attention to the fact that the function expects you to return a char) and that’s why you are considering only the first letter. You can do something like this:
int checkifletterisinword(char *thesecretword, char guessedLetter){
for(int i=0;thesecretword[i]!=‘\0’;i ){
if(thesecretword[i]==guessedLetter){
return 1;
}
}
return 0;
}
I changed slightly the function prototype. This function returns 0 if there is not the character in the string and 1 otherwise
CodePudding user response:
The following lines are wrong:
char *thesecretword[15];
[...]
*thesecretword = "stackoverflow";
The line
*thesecretword = "stackoverflow";
is equivalent to:
thesecretword[0] = "stackoverflow";
This means that you are only setting thesecretword[0]
, but not thesecretword[1]
to thesecretword[14]
.
You probably only want a single pointer, so there is no point in creating an array of 15 pointers. So you probably should to change the lines to the following:
char *thesecretword;
[...]
thesecretword = "stackoverflow";
Also, the function declaration
char checkifletterisinword( char **thesecretword, char *guessedletter )
does not make sense. The return type should probably be bool
to indicate whether the letter was found or not. Also, the first parameter should be a pointer to the string to search for, not a pointer to a pointer. Additonally, the second parameter should be the value of the character to search for, not a pointer to a character.
Therefore, you should probably change the function declaration and definition to the following:
bool checkifletterisinword( char *thesecretword, char guessedletter )
Note that you must #include <stdbool.h>
in order to use the type bool
.
The line
for ( int i=0; i!='\n'; i )
also does not make sense. The loop condition i!='\n'
does not seem meaningful, because the string is terminated by a null terminating character, not a newline character. Also, you don't want to compare the index i
itself, but rather the character at that index. Therefore, you should probably change the line to the following:
for ( int i=0; thesecretword[i]!='\0'; i )
Since we have changed the parameters of the function checkifletterisinword
, the line
if ( guessedletter == *thesecretword[i] )
no longer makes sense. We should change it to the following:
if ( guessedletter == thesecretword[i] )
Also, the line
return 0;
in the function checkifletterisinword
does not make sense. We want to return true;
if the letter is found, and return false
after all letters of the string have been compared without finding a match. So the function should look like this:
bool checkifletterisinword( char *thesecretword, char guessedletter )
{
for ( int i=0; thesecretword[i]!='\0'; i )
{
if ( guessedletter == thesecretword[i] )
{
return true;
}
}
return false;
}
Depending on the returned value, we can then print an appropriate message in the function main
:
if ( checkifletterisinword( thesecretword, guessedletter ) )
{
printf( "The letter %c is in the word.\n", guessedletter );
}
else
{
printf( "The letter %c is not in word.\n", guessedletter );
}
Also, all of your function definitions have a trailing ;
. This is not permitted in ISO C.
After making all these changes, your entire program should look like this:
#include <stdio.h>
#include <stdbool.h>
bool checkifletterisinword( char *thesecretword, char guessedletter );
char guess();
int main()
{
char *thesecretword;
char guessedletter;
thesecretword = "stackoverflow";
guessedletter = guess();
if ( checkifletterisinword( thesecretword, guessedletter ) )
{
printf( "The letter %c is in the word.\n", guessedletter );
}
else
{
printf( "The letter %c is not in word.\n", guessedletter );
}
return 0;
}
bool checkifletterisinword( char *thesecretword, char guessedletter )
{
for ( int i=0; thesecretword[i]!='\0'; i )
{
if ( guessedletter == thesecretword[i] )
{
return true;
}
}
return false;
}
char guess()
{
char temp;
printf( "Guess a letter...\n" );
temp = getchar();
getchar();
return temp;
}
This program has the following behavior:
Guess a letter...
a
The letter a is in the word.
Guess a letter...
b
The letter b is not in word.
Note that you can simply use the function strchr
to search inside a string for a specific character. You don't need to write your own function for that:
#include <stdio.h>
#include <string.h>
char guess();
int main()
{
char *thesecretword;
char guessedletter;
thesecretword = "stackoverflow";
guessedletter = guess();
if ( strchr( thesecretword, guessedletter ) )
{
printf( "The letter %c is in the word.\n", guessedletter );
}
else
{
printf( "The letter %c is not in word.\n", guessedletter );
}
return 0;
}
char guess()
{
char temp;
printf( "Guess a letter...\n" );
temp = getchar();
getchar();
return temp;
}
This program has the same behavior as the first program.
CodePudding user response:
Forget about the loop for now. Your main problem is that pointers don't work the way you think they do. The following isn't anywhere near a complete tutorial, but hopefully it'll give you enough to know what followup questions you need to ask.
- A string is an array of
char
that ends with a\0
. - A string literal in double quotes will automatically add the trailing
\0
; you don't need to do it by hand. char foo[15]
declares an array of 15char
s.char *foo
holds the address of achar
. If you point it at a string, it holds the address of the first character in the string. You can then loop forward from there until you hit the\0
that marks the end.*foo
takes a pointer and evaluates to the thing it points to. So in the case of a string, it evaluates to the first character,foo[0]
.- The indexing operator
foo[idx]
is equivalent to*(foo idx)
. So you can loop through strings either by incrementing the index, or by incrementing the pointer itself, to make it point to the next element of the array:idx ; foo[idx]
andfoo ; foo[idx]
will both result in accessing element 1 of the string. - Pointers know the size of what they point at. This doesn't matter for strings, since
char
is defined to be 1 byte, but if you haveint foo[42]
, and int is 4 bytes long,foo[1]
and*(foo 1)
will look 1sizeof(int)
from the start of the array, not one byte. So it'll work the way you expect. - Permitting a user to write past the end of an array is very bad. (Specifically, it permits an attacker to run arbitrary code on your system, but the mechanics of that are way beyond the scope here.) Any time you read user input, always check that they don't input more characters than you have space for.
So in your code:
char *thesecretword[15];
declares an array of 15char
pointers, not 15char
s.*thesecretword = "stackoverflow";
Puts "stackoverflow\0" in memory somewhere, and puts the address where it starts inthesecretword[0]
.thesecretword[1]
throughthesecretword[14]
remain uninitialized.
This is how you declare the variables you meant to:
#define MAX_LEN 15 // When putting user input into `guessedword[i]`, we'll only permit it if `i < MAXLEN`
char *thesecretword = "stackoverflow";
char guessedword[MAX_LEN];