Trouble with strchr in C - c

I can't work out why Strchr() is not working in my function. I need to see if the users guess matches any of the letters in a hidden word. It is a Hangman game.
int guessLetter(char* word, int* guessedLetters)
{
char guess[20];
char *s;
printf("Enter your guess: ");
scanf("%s", &guess);
s = strchr (word, guess);
printf("%s", s);
if (s != NULL) {
printf ("Good Guess\n");
} else {
printf ("Bad Guess\n");
}
}
No matter if the guess is right or wrong, my else statement is being activated. My printf shows that s is being given the value of Null no matter if the character is in the word or not.
So I guess my problem is with this part of the code:
s = strchr (word, guess);
I am new to C, so I am sure I am just missing something very basic. I have tried to search the web as much as I can, but I don't really seem to be able to understand what I am doing wrong.

strchr takes an int as 2nd argument but you are passing a char*. You Turn on your compiler warnings.
What you wanted is to loop over the word to see if any of the characters are in guess.
s = 0;
for(size_t i=0; word[i]; i++) {
s = strchr (guess, word[i]);
if(s) break; //Found a match
}
This would break on the first match and you can modify it if you want to check for all characters in word.
There's an argument mismatch in scanf call too:
scanf("%s", &guess);
should be
scanf("%s", guess);
scanf expects a char* for format string %s but you are passing char(*)[20] i.e. &guess is of type char (*)[20].

Related

How to print the nth term of a string using scanf function?

The console will not do anything after the user has entered a string.
I have got the code to work using char string="enteraword" and taking out the whole printf and scanf function, however I need the code to work with a scanf function.
#include <stdio.h>
#include <string.h>
int main()
{
char* string;
printf("Enter a word: ");
scanf("%s", string);
char c=string[1];
printf("The second letter in %s is %c", string, c);
return 0;
}
This code has undefined behavior, you're passing an uninitialized pointer to scanf(), asking it to store a string there.
Also, remember that %s will stop at whitespace, so it's very unclear what "terms" should mean here.
Try e.g.:
char string[1024];
if(scanf("%1023s", string) == 1 && string[0] != '\0')
{
const char c = string[1];
printf("The second letter of '%s' is '%c'\n", string, c);
}

Tokenizing a string

I am in the process of writing a C program that parses a string and tokenizing it by breaking the string characters into words that are seperated by white space. My question is when i run my current program:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char input[20];
printf("Please enter your word:\n");
scanf("%c", &input);
printf("%c", input[1]);
return 0;
}
If i was to enter the word "This", i would expect to get back "h" when i run the program but instead i get a downwards pointing arrow. However, when the input is set to print out input[0] i get back a "T".
Edit: I have modified my code so that it prints out the whole string now which i will show below
int main()
{
char input[20];
printf("Please enter your words:\n");
scanf("%s", input);
printf("%s", input);
return 0;
}
My goal is to be able to break that string into chars that i can search through to find whitespace and thus being able to isolate those words for example, if my input was "This is bad" i'd like the code to print out
This
is
bad
Edit:
I have modified my code to fit one of these answers but the problem i run into now is that it won't compile
int main()
{
char input[20];
printf("Please enter your words:\n");
size_t offset = 0;
do
{
scanf("%c", input + offset);
offset++;
}
while(offset < sizeof(input) && input[offset - 1] != '\n');
}
printf("%c", input[]);
return 0;
Problems:
1) scanf("%c", input); only set the first element of the array input.
2) printf("%c", input[1]); prints the second element of the array input, which has uninitialized data in it.
Solution:
Small state machine. No limit on string size like 20.
#include <ctype.h>
#include <stdio.h>
int main() {
int ch = fgetc(stdin);
while (ch != EOF) {
while (isspace(ch)) {
// If only 1 line of input allowed, then add
if (ch == '\n') return 0;;
ch = fgetc(stdin);
}
if (ch != EOF) {
do {
fputc(ch, stdout);
ch = fgetc(stdin);
} while (ch != EOF && !isspace(ch));
fputc('\n', stdout);
}
}
return 0;
}
scanf("%c", &input); does not do what you think it does.
First of all, %c scans only a single character: http://www.cplusplus.com/reference/cstdio/scanf/
Second, array's name is already a pointer to it's first element, so stating &input you make a pointer to a pointer, so instead of storing your character in array's first element you store it in pointer to the array which is a very bad thing.
If you really want to use scanf, I recommend a loop:
size_t offset = 0;
do
{
scanf("%c", input + offset);
offset++;
}
while(offset < sizeof(input) && input[offset - 1] != '\n');
Using scanf("%s", input") leaves you vulnerable to buffer overflow attacks if the word is longer than 20 characters http://en.wikipedia.org/wiki/Buffer_overflow
In my example I assumed, that you want to finish your word with a newline character.
EDIT: In scanf documentation is also a good example:
scanf("%19s", input);
It scans no more than 19 characters, which also prevent buffer overflow. But if you want to change input size, you have to change it two places.
You can use
char * strtok ( char * str, const char * delimiters );
to tokenize your string. If you have your input in input[] array and want to tokenize the string accoring to whitespace character, you can do the following :
char *ptr;
ptr = strtok(input, " ");
while(ptr != NULL) {
printf("%s\n", ptr);
ptr = strtok(NULL, " ");
}
Only the first call to strtok() requires the character array as input. Specifying NULL in the next calls means that it will operate on the same character array.
Your scanf only picks up the first character, input[1] contains random garbage. Use scanf("%19s", input) instead.

Swap two words in a string using C programming

I am close to finish writing a program to swap two words inputed to a program. If i input "Billy Bob" the output will be "#\300_\377" Something weird like that... I believe there is something wrong with my scanf but not quite sure. Here is what i have so far..
{ int i,j,l;
char str[59];
printf("Enter the string\n");
scanf("%s", &str[59]);
l=strlen(str);
for(i=l-1; i>=0; i--)
{ if(str[i]==' ')
{ for(j=i+1; j<l; j++)
printf("%c",str[j]);
printf(" ");
l=i;
}
if(i==0)
{ printf(" ");
for(j=0; j<l; j++)
printf("%c",str[j]);
}
}
scanf("%s", &str[59]);
Writes the input at the end of the allocated space. Use the address of the first element:
scanf("%s", str);
but this will give you the first word, so either do:
scanf("%s %s", str1, str2); // str1, str2 are arrays
or use fgets:
fgets(str, 59, stdin);
Instead of using scanf("%s", &str[59]);, you could use gets(str);.
It works perfectly fine...
This is wrong:
scanf("%s", &str[59]);
//^not reading the str, str[59] is even out of bound
should be:
scanf("%s", str);
That way of writing the function is somewhat difficult to read. I'm not exactly sure what circumstances you are writing it in but an alternative solution would be to split up the input string by a token, in this case a space, and print out the two strings in the opposite order. An example of the function strtok() can be found here.
Something like this:
char str[] ="billy bob";
char * firstToken;
char * secondToken
firstToken = strtok(str, " ");
secondToken = strtok(NULL, " ");
printf("%s %s", secondToken, firstToken);
You're passing the first address after str to scanf. Change &str[59] to str.

Why aren't my strings printing the proper value?

Here is my code to print the string
char accname[MAX][MAXSTRING], transname[MAX][MAXSTRING];
printf ("Enter title for new account: ");
accname[i][i] = validatestring();
printf ("\n");
printf ("Enter title for transaction: ");
transname[i][i] = validatestring();
printf ("\n");
printf ("%s %s", accname[i], transname[i]);
my code for validatestring()
char validatestring() {
int keeptrying = 1, rc;
char i[31];
do
{
rc = scanf("%30[^\n]", &i);
if (rc == 0)
{
printf (" **Invalid input try again: ");
clear();
}
else if (getchar() != '\n')
{
printf (" **Title is longer than 30 characters: ");
clear();
}
else
{
keeptrying = 0;
}
} while (keeptrying == 1);
return i;
}
at the printf stage for accname[i] / transname[i] i don't get the value I entered, I get weird conversion string types, sometimes I got the first character of my input but now I get something completely different. Can anyone figure out why?
Your validatestring function is hopelesely broken.
Firstly, you declared validatestring as returning char. Yet you attempt too return a char * from it (see return i, where i is char [31]). This should not even compile.
Secondly, if you intend to return a string from validatestring, you have to make sure that you are not returning a pointer to a local buffer from it. i is a local array. A pointer to i cannot be returned from validatestring.
Yeah that is because what you are doing is trying to store everything in one char.
array[i][i]
which is a character position in which you are trying to store everything in it
I think what you intend to do is
*array[i] // It is a pointer to that location which you referring to.
This will store your string in array[i] from which you can access your characters using
array[i][i]
I hope this solves your problem.Also your function should return a char pointer char*.
This should do it:
*accname[i] = validatestring();
Also change the return type of your function to char*

C application skips my scanf calls

I'm trying to write code to count how many times a string repeats inside another one. (If there is some easier approach, please let me know.)
Here is the code that I have now:
int getStringLenght (char str[]) {
int lenghtOfTheString;
int i;
for (i = 0; i < 100; i++) {
if(str[i] == '\0') {
lenghtOfTheString = i;
break;
}
}
return lenghtOfTheString;
}
int main()
{
printf("Type a string: ");
char T[1024];
scanf("%s",&T);
char P[100];
printf("Type a substring: ");
scanf("%s",&P);
printf("%s",P);
int stringSize = getStringLenght (P);
int occurences = 0;
int i;
for (i = 0; i < 10; i++) {
int j;
if(T[i] == P[0]) {
for (j = 0;j<10;j++) {
char c1 = T[i+j];
char c2 = P[j];
if(c1 != c2) {
break;
}
if(j == stringSize-1) {
occurences++;
//printf("string iguais em i = %d",i);
}
}
}
}
printf("\nThe substring %s was found %d times", P, occurences);
return 0;
}
The app compiles. When I type "banana", for example, on the first scanf, and then "na" on the second, the app comes out with the right answer. But, if I type "banana and milk" on the first scanf, it automatically interprets the second scanf as "and", even when I don't type anything but "banana and milk ENTER"
What's happening?
scanf's "%s" conversion only reads characters until it encounters white-space (e.g., space, new-line, or tab). When you enter more than one word, it reads the first. The second call reads the second, and so on.
If you want to read an entire line, you usually want to use fgets instead (scanf can do the job as well, but it's a little trickier, and uses a feature of which many are unaware, so they often find it difficult to understand).
You don't understand how scanf works. http://www.cplusplus.com/reference/clibrary/cstdio/scanf/ %s will only read one string, terminated by white space. If you want to keep reading strings, or read a line, you have to keep using scanf until one of your strings ends in a new line or EOF, or use another function, like fgets.
You have to remember that many functions are already implemented. This is why your getStringLength (you have typo in it's name) is needless. You can simply check the string's length using strlen function from string.h. What is more when you import this file you also have access to strstr function which finds the first occurrence of a given substring in a string. Try to use them instead of reinventing the wheel ;)
That is a standart problem with scanf. There are 3 ways to fix this:
1: Call fflush after each scanf:
scanf("%s", some_string); // you don't need to write &some_string because giving a array to a function automatically converts it to a pointer
fflush(stdin);
fflush() isn't available on every system.
2: Putting scanf in a loop:
do
scanf("%s", somestring);
while (getchar() != '\n');
3: Don't use scanf! Use fgets and sscanf!
char buffer[100]; // buffer for fgets()
fgets(buffer, 100, stdin); // read a line from stdin (standart input) into buffer
sscanf(buffer, "%s", some_string); // convert buffer in any format you want

Resources