I am unable to insert a value into ptr char array:
int main() {
char S[MAX_STRING_LENGTH],*str;
int total,j=0,i=0;
char ptr[16],c;
scanf("%d",&total);
for(i=0;i<total;i++){
c=getchar();
do{
ptr[j]=(char)tolower(c);
j++;
c=getchar();
}while(c!='\n' && j<15 );
ptr[j]='\0';
printf("j=%d , %s",j,ptr);
}
}
The reason for this I know:
I put do-loop exit on '\n' and I'm using enter('\n') itself after inserting value in total.
That way it is exiting loop without insertion of value.
How can I correct it?
What you are doing is kind of unsafe. First of all depending on the operating system you may have to terminate on '\r' not only on '\n'. Second you never check the size of the input to be within 15 symbols. Please note I say 15 symbols because it is usually good practise to leave one cell for the zero terminating character.
If the input does not contain whitespaces(space or tab) I would advice you to use scanf("%s") as it is less error-prone. Also you will eliminate the need for a while loop.
If that is not the case, you should add a check for '\r' as well and also you will have to remove the newline character that you type after the total value. Like so:
scanf("%d", &total);
getchar();
This is needed because otherwise the newline after total will be the first char you read in your while loop and thus you will exit on the first iteration of the cycle.
If you debug your program you will see that this happens.
Because scanf did scan \n in the input stream but it didn't store it in &total . The next time you getchar() it will get it \nwhich cause the do-while only can execute once.
add
getchar();
after scanf.
input stream :
the next you getchar() will from here
|
|
A A A A A A \n A A A A A A
^
|
the variable total store string before this
During scanf you will enter some no(no of characters) say 10 and will hit enter. Now this '\n\ will not be read by scanf and it's there in input stream. During first iteration, getchar() will read this '\n' and will terminate the loop after first iteration. So better put a getchar() after scanf() so as no make inputstream to empty. apart from this,
You haven't put any check beyond array index limit. It maybe the case user keep entering the characters and you endup trying to insert beyond 16 places.
while(c != '\n' && j < 15);
Will solve your problem.
Related
I'm trying to develop a simple text-based hangman game, and the main game loop starts with a prompt to enter a guess at each letter, then goes on to check if the letter is in the word and takes a life off if it isn't. However, when I run the game the prompt comes up twice each time, and the program doesn't wait for the user's input. It also takes off a life (one life if it was the right input, two if it wasn't), so whatever it's taking in isn't the same as the previous input. Here's my game loop, simplified a bit:
while (!finished)
{
printf("Guess the word '%s'\n",covered);
scanf("%c", ¤tGuess);
i=0;
while (i<=wordLength)
{
if (i == wordLength)
{
--numLives;
printf("Number of lives: %i\n", numLives);
break;
} else if (currentGuess == secretWord[i]) {
covered[i] = secretWord[i];
secretWord[i] = '*';
break;
}
++i;
}
j=0;
while (j<=wordLength)
{
if (j == (wordLength)) {
finished = 1;
printf("Congratulations! You guessed the word!\n");
break;
} else {
if (covered[j] == '-') {
break;
}
}
++j;
if (numLives == 0) {
finished = 1;
}
}
}
I assume the problem is scanf thinking it's taken something in when it hasn't, but I have no idea why. Does anyone have any idea? I'm using gcc 4.0.1 on Mac OS X 10.5.
When you read keyboard input with scanf(), the input is read after enter is pressed but the newline generated by the enter key is not consumed by the call to scanf(). That means the next time you read from standard input there will be a newline waiting for you (which will make the next scanf() call return instantly with no data).
To avoid this, you can modify your code to something like:
scanf("%c%*c", ¤tGuess);
The %*c matches a single character, but the asterisk indicates that the character will not be stored anywhere. This has the effect of consuming the newline character generated by the enter key so that the next time you call scanf() you are starting with an empty input buffer.
Caveat: If the user presses two keys and then presses enter, scanf() will return the first keystroke, eat the second, and leave the newline for the next input call. Quirks like this are one reason why scanf() and friends are avoided by many programmers.
Newlines.
The first time through the loop, scanf() reads the character.
Then it reads the newline.
Then it reads the next character; repeat.
How to fix?
I seldom use scanf(), but if you use a format string "%.1s", it should skip white space (including newlines) and then read a non-white space character. However, it will be expecting a character array rather than a single character:
char ibuff[2];
while ((scanf("%.1s", ibuff) == 1)
{
...
}
Break the problem up into smaller parts:
int main(void) {
char val;
while (1) {
printf("enter val: ");
scanf("%c", &val);
printf("got: %d\n", val);
}
}
The output here is:
enter val: g
got: 103
enter val: got: 10
Why would scanf give you another '10' in there?
Since we printed the ASCII number for our value, '10' in ASCII is "enter" so scanf must also grab the "enter" key as a character.
Sure enough, looking at your scanf string, you are asking for a single character each time through your loop. Control characters are also considered characters, and will be picked up. For example, you can press "esc" then "enter" in the above loop and get:
enter val: ^[
got: 27
enter val: got: 10
Just a guess, but you are inputting a single character with scanf, but the user must type the guess plus a newline, which is being consumed as a separate guess character.
scanf(" %c", &fooBar);
Notice the space before the %c. This is important, because it matches all preceding whitespace.
Jim and Jonathan have it right.
To get your scanf line to do what you want (consume the newline character w/o putting it in the buffer) I'd change it to
scanf("%c\n", ¤tGuess);
(note the \n)
The error handling on this is atrocious though. At the least you should check the return value from scanf against 1, and ignore the input (with a warning) if it doesn't return that.
A couple points I noticed:
scanf("%c") will read 1 character and keep the ENTER in the input buffer for next time through the loop
you're incrementing i even when the character read from the user doesn't match the character in secretWord
when does covered[j] ever get to be '-'?
I'll guess: your code is treating a newline as one of the guesses when you enter data. I've always avoided the *scanf() family due to uncontrollable error handling. Try using fgets() instead, then pulling out the first char/byte.
I see a couple of things in your code:
scanf returns the number of items it read. You will probably want to handle the cases where it returns 0 or EOF.
My guess would be that the user is hitting letter + Enter and you're getting the newline as the second character. An easy way to check would be to add a debugging printf statement to show what character was entered.
Your code will only match the first occurrence of a match letter, i.e. if the word was "test" and the user entered 't', your code would only match the first 't', not both. You need to adjust your first loop to handle this.
When you enter the character, you have to enter a whitespace character to move on. This whitespace character is present in the input buffer, stdin file, and is read by the scanf() function.
This problem can be solved by consuming this extra character. This can be done by usnig a getchar() function.
scanf("%c",¤tGuess);
getchar(); // To consume the whitespace character.
I would rather suggest you to avoid using scanf() and instead use getchar(). The scanf()requires a lot of memory space. getchar() is a light function. So you can also use-
char currentGuess;
currentGuess=getchar();
getchar(); // To consume the whitespace character.
char c = ' ';
while(c != 'x')
{
c = getchar();
printf("threadFuncParam = %u\n", threadFuncParam);
}
In the above code snippet the print is printing threadFuncParam value twice every time I enter a character where as I expect it to print only once.
As per my understanding very first time it enters while as condition is true and and then wait for user input at getchar call on entering a character it shall print the value and then if input character is not x it shall wait for another input at getchar call, but whenever i enter a character i see 2 prints ion screen for each input. I am not able to understand why?
What i'm trying to do here is that in main thread i am taking single char input from user and in worker thread i am incrementing a counter which gets incremented every second, i print the value everytime user input a char input until user enters 'x' character.
The simple issue here is that the console (input) sends the text to the stdin only when it encounters a enter key or ctr+d.
As a result an extra \n goes into your input stream. This causes your program to read that character in the next iteration.
A simple solution would be to read all white space characters in the stream.
This can be done in multiple ways -
If you need to discard any whitespace characters (including space, tabs, vtabs, newline), you can add
scanf(" ");
before the getchar();
If you need to discard only the newlines which come as a result of pressing enter, you can add
scanf("%*[\n]")
before the getchar();
This will eat up all the \n that come before the next character. But will not eat spaces.
Finally if you want to discard only 1 \n
You can do
scanf("%*1[\n]");
Remember though, in all the cases the scanf should be immediately before the getchar() because scanf would wait till it finds the next non white space character.
All cases figured out with the help of comments from #chux.
If you tried to debug your program (its best way to learn to code), you would spot that the second value is everytime 10. In ASCII table you would find that is code for new line. Which you are pressing after the every character. Then by fast & simple searching you would find this THREAD. Where is the problem described and you would easily solve it.
char c = ' ';
while(c != 'x')
{
printf("threadFuncParam = %u\n", (char)c);
fflush(stdout);
if (scanf(" %c",&c) != 1)
{
// failed
}
}
I think the problem is in the way logic is applied. You print before you check the condition. See this for explanation:
loop 1: getchar() executed say for value 'a'.
printf() executed.
loop 2: Because c='a', condition is true. Now, getchar() is executed with 'x' value.
printf() is again executed.
loop 3: Condition is evaluated false. Loop is terminated.
So basically you should change your logic a little bit.
I'm trying to develop a simple text-based hangman game, and the main game loop starts with a prompt to enter a guess at each letter, then goes on to check if the letter is in the word and takes a life off if it isn't. However, when I run the game the prompt comes up twice each time, and the program doesn't wait for the user's input. It also takes off a life (one life if it was the right input, two if it wasn't), so whatever it's taking in isn't the same as the previous input. Here's my game loop, simplified a bit:
while (!finished)
{
printf("Guess the word '%s'\n",covered);
scanf("%c", ¤tGuess);
i=0;
while (i<=wordLength)
{
if (i == wordLength)
{
--numLives;
printf("Number of lives: %i\n", numLives);
break;
} else if (currentGuess == secretWord[i]) {
covered[i] = secretWord[i];
secretWord[i] = '*';
break;
}
++i;
}
j=0;
while (j<=wordLength)
{
if (j == (wordLength)) {
finished = 1;
printf("Congratulations! You guessed the word!\n");
break;
} else {
if (covered[j] == '-') {
break;
}
}
++j;
if (numLives == 0) {
finished = 1;
}
}
}
I assume the problem is scanf thinking it's taken something in when it hasn't, but I have no idea why. Does anyone have any idea? I'm using gcc 4.0.1 on Mac OS X 10.5.
When you read keyboard input with scanf(), the input is read after enter is pressed but the newline generated by the enter key is not consumed by the call to scanf(). That means the next time you read from standard input there will be a newline waiting for you (which will make the next scanf() call return instantly with no data).
To avoid this, you can modify your code to something like:
scanf("%c%*c", ¤tGuess);
The %*c matches a single character, but the asterisk indicates that the character will not be stored anywhere. This has the effect of consuming the newline character generated by the enter key so that the next time you call scanf() you are starting with an empty input buffer.
Caveat: If the user presses two keys and then presses enter, scanf() will return the first keystroke, eat the second, and leave the newline for the next input call. Quirks like this are one reason why scanf() and friends are avoided by many programmers.
Newlines.
The first time through the loop, scanf() reads the character.
Then it reads the newline.
Then it reads the next character; repeat.
How to fix?
I seldom use scanf(), but if you use a format string "%.1s", it should skip white space (including newlines) and then read a non-white space character. However, it will be expecting a character array rather than a single character:
char ibuff[2];
while ((scanf("%.1s", ibuff) == 1)
{
...
}
Break the problem up into smaller parts:
int main(void) {
char val;
while (1) {
printf("enter val: ");
scanf("%c", &val);
printf("got: %d\n", val);
}
}
The output here is:
enter val: g
got: 103
enter val: got: 10
Why would scanf give you another '10' in there?
Since we printed the ASCII number for our value, '10' in ASCII is "enter" so scanf must also grab the "enter" key as a character.
Sure enough, looking at your scanf string, you are asking for a single character each time through your loop. Control characters are also considered characters, and will be picked up. For example, you can press "esc" then "enter" in the above loop and get:
enter val: ^[
got: 27
enter val: got: 10
Just a guess, but you are inputting a single character with scanf, but the user must type the guess plus a newline, which is being consumed as a separate guess character.
scanf(" %c", &fooBar);
Notice the space before the %c. This is important, because it matches all preceding whitespace.
Jim and Jonathan have it right.
To get your scanf line to do what you want (consume the newline character w/o putting it in the buffer) I'd change it to
scanf("%c\n", ¤tGuess);
(note the \n)
The error handling on this is atrocious though. At the least you should check the return value from scanf against 1, and ignore the input (with a warning) if it doesn't return that.
A couple points I noticed:
scanf("%c") will read 1 character and keep the ENTER in the input buffer for next time through the loop
you're incrementing i even when the character read from the user doesn't match the character in secretWord
when does covered[j] ever get to be '-'?
I'll guess: your code is treating a newline as one of the guesses when you enter data. I've always avoided the *scanf() family due to uncontrollable error handling. Try using fgets() instead, then pulling out the first char/byte.
I see a couple of things in your code:
scanf returns the number of items it read. You will probably want to handle the cases where it returns 0 or EOF.
My guess would be that the user is hitting letter + Enter and you're getting the newline as the second character. An easy way to check would be to add a debugging printf statement to show what character was entered.
Your code will only match the first occurrence of a match letter, i.e. if the word was "test" and the user entered 't', your code would only match the first 't', not both. You need to adjust your first loop to handle this.
When you enter the character, you have to enter a whitespace character to move on. This whitespace character is present in the input buffer, stdin file, and is read by the scanf() function.
This problem can be solved by consuming this extra character. This can be done by usnig a getchar() function.
scanf("%c",¤tGuess);
getchar(); // To consume the whitespace character.
I would rather suggest you to avoid using scanf() and instead use getchar(). The scanf()requires a lot of memory space. getchar() is a light function. So you can also use-
char currentGuess;
currentGuess=getchar();
getchar(); // To consume the whitespace character.
I'm just asking what does the getchar do in this code and how does it work? I don't understand why the getchar affects the code, to me it seems as if its just getting the value but nothing is being done with the value.
int c=0;
while (c>=0)
{
scanf("%d", &c);
getchar();
}
Some possibilities of why getchar() might have been used there:
1) If it's done to ignore whitespaces (typically used when scanning chars with %c), it's not needed here because %d ignores whitespaces anyway.
2) Other possibility is that after this loop, some further scanning is done where the last \n left by the last call to scanf() might be a problem. So, getchar() might be used to ignore it.
3) In case you enter characters do not match %d, scanf() will fail. In that the characters you entered are left in the input stream and you'll never be able to read an int again (For example, if you input abcdddgdfg without that getchar() call). So, getchar() here will consume all those
chars (one per iteration) and eventually you'll be able to read int (using %d) again.
But this is all really not needed; it's just an attempt to fix flaws of scanf(). Reading inputs using scanf() and getting it correct is really difficult. That's why it's always recommended to use fgets() and parse using sscanf() or using strto*() functions if you are just scanning integers.
See: Why does everyone say not to use scanf? What should I use instead?
In this code, getchar is being called for its side effects: it reads a character from standard input and throws it away.
Probably this is reading input from the user. scanf will consume a number, but leave the newline character after the number untouched. The getchar consumes the newline and throws it away. This isn't strictly necessary in this loop, because the next scanf will skip over whitespace to find the next number, but it might be useful if the code after the loop isn't expecting to have a newline as the first thing on stdin.
This code is buggy, because it doesn't check for EOF, because it doesn't do anything sensible when the input is not a number or when there's more text on the line after the number, and because it uses scanf, which is broken-as-specified (for instance, it's allowed to crash the program if the input overflows the range of an int). Better code would be something like
char *linep = 0;
size_t asize = 0;
char *endp;
long c;
while (getline(&linep, &asize, stdin) > 0) {
errno = 0;
c = strtol(linep, &endp, 10);
if (linep == endp || *endp != '\0' || errno) {
puts("?Redo from start");
continue;
}
if (c == 0) break;
do_something_with(c);
}
free(linep);
Most likely the code is for reading in a list of integers, separated by a new line.
scanf will read in an integer, and put it into variable c.
The getchar is reading in the next character (assuming a new line)
Since it doesn't check, there is some potential that it wasn't a new line, or that scanf failed as the what it tried to read wasn't a number.
getchar(); is simply reading and consuming the character after the number, be it a space, comma, new line or the beginning of another integer or anything else.
IMO, this is not robust code. Good code would 1) at least test the result of scanf() and 2) test or limit the consumption of the following character to prevent "eating" a potential sign of the following number. Remember code cannot control what a user types, but has to cope with whatever is entered.
v space
"123 456"
v comma
"123,456"
v negative sign
"123-456"
I'm trying to develop a simple text-based hangman game, and the main game loop starts with a prompt to enter a guess at each letter, then goes on to check if the letter is in the word and takes a life off if it isn't. However, when I run the game the prompt comes up twice each time, and the program doesn't wait for the user's input. It also takes off a life (one life if it was the right input, two if it wasn't), so whatever it's taking in isn't the same as the previous input. Here's my game loop, simplified a bit:
while (!finished)
{
printf("Guess the word '%s'\n",covered);
scanf("%c", ¤tGuess);
i=0;
while (i<=wordLength)
{
if (i == wordLength)
{
--numLives;
printf("Number of lives: %i\n", numLives);
break;
} else if (currentGuess == secretWord[i]) {
covered[i] = secretWord[i];
secretWord[i] = '*';
break;
}
++i;
}
j=0;
while (j<=wordLength)
{
if (j == (wordLength)) {
finished = 1;
printf("Congratulations! You guessed the word!\n");
break;
} else {
if (covered[j] == '-') {
break;
}
}
++j;
if (numLives == 0) {
finished = 1;
}
}
}
I assume the problem is scanf thinking it's taken something in when it hasn't, but I have no idea why. Does anyone have any idea? I'm using gcc 4.0.1 on Mac OS X 10.5.
When you read keyboard input with scanf(), the input is read after enter is pressed but the newline generated by the enter key is not consumed by the call to scanf(). That means the next time you read from standard input there will be a newline waiting for you (which will make the next scanf() call return instantly with no data).
To avoid this, you can modify your code to something like:
scanf("%c%*c", ¤tGuess);
The %*c matches a single character, but the asterisk indicates that the character will not be stored anywhere. This has the effect of consuming the newline character generated by the enter key so that the next time you call scanf() you are starting with an empty input buffer.
Caveat: If the user presses two keys and then presses enter, scanf() will return the first keystroke, eat the second, and leave the newline for the next input call. Quirks like this are one reason why scanf() and friends are avoided by many programmers.
Newlines.
The first time through the loop, scanf() reads the character.
Then it reads the newline.
Then it reads the next character; repeat.
How to fix?
I seldom use scanf(), but if you use a format string "%.1s", it should skip white space (including newlines) and then read a non-white space character. However, it will be expecting a character array rather than a single character:
char ibuff[2];
while ((scanf("%.1s", ibuff) == 1)
{
...
}
Break the problem up into smaller parts:
int main(void) {
char val;
while (1) {
printf("enter val: ");
scanf("%c", &val);
printf("got: %d\n", val);
}
}
The output here is:
enter val: g
got: 103
enter val: got: 10
Why would scanf give you another '10' in there?
Since we printed the ASCII number for our value, '10' in ASCII is "enter" so scanf must also grab the "enter" key as a character.
Sure enough, looking at your scanf string, you are asking for a single character each time through your loop. Control characters are also considered characters, and will be picked up. For example, you can press "esc" then "enter" in the above loop and get:
enter val: ^[
got: 27
enter val: got: 10
Just a guess, but you are inputting a single character with scanf, but the user must type the guess plus a newline, which is being consumed as a separate guess character.
scanf(" %c", &fooBar);
Notice the space before the %c. This is important, because it matches all preceding whitespace.
Jim and Jonathan have it right.
To get your scanf line to do what you want (consume the newline character w/o putting it in the buffer) I'd change it to
scanf("%c\n", ¤tGuess);
(note the \n)
The error handling on this is atrocious though. At the least you should check the return value from scanf against 1, and ignore the input (with a warning) if it doesn't return that.
A couple points I noticed:
scanf("%c") will read 1 character and keep the ENTER in the input buffer for next time through the loop
you're incrementing i even when the character read from the user doesn't match the character in secretWord
when does covered[j] ever get to be '-'?
I'll guess: your code is treating a newline as one of the guesses when you enter data. I've always avoided the *scanf() family due to uncontrollable error handling. Try using fgets() instead, then pulling out the first char/byte.
I see a couple of things in your code:
scanf returns the number of items it read. You will probably want to handle the cases where it returns 0 or EOF.
My guess would be that the user is hitting letter + Enter and you're getting the newline as the second character. An easy way to check would be to add a debugging printf statement to show what character was entered.
Your code will only match the first occurrence of a match letter, i.e. if the word was "test" and the user entered 't', your code would only match the first 't', not both. You need to adjust your first loop to handle this.
When you enter the character, you have to enter a whitespace character to move on. This whitespace character is present in the input buffer, stdin file, and is read by the scanf() function.
This problem can be solved by consuming this extra character. This can be done by usnig a getchar() function.
scanf("%c",¤tGuess);
getchar(); // To consume the whitespace character.
I would rather suggest you to avoid using scanf() and instead use getchar(). The scanf()requires a lot of memory space. getchar() is a light function. So you can also use-
char currentGuess;
currentGuess=getchar();
getchar(); // To consume the whitespace character.