I am writing a program for fun (not for school), and am having a hard time figuring out why the scanf function isn't executing on every iteration of my loop - I've toyed with both 'for' loops and 'while' loops.
I know that depending on how I write the scanf function (i.e. scanf("%s", &variablename); VS scanf("%99[^\n]s", &variablename);) makes a difference, but I have tried everything and I'm desperate!
When I do a printf check on my input from the scanf, on every iteration it is only intaking one string per iteration, so if I enter two words in my first input, then it takes two iterations to process - one word per. Here is the segment of code I'm describing:
int main(void){
int tries = 0;
int score = 0;
char question[100];
char useranswer[100];
const char *phrase = {"our favorite saying\0"};
printf("\nQuestion #3 (10 points): What is our secret saying?\n");
sleep(1);
tries = 1;
while (tries<=3){
printf("YOUR ANSWER:");
scanf("%s[^\n]", useranswer);
if(strncmp(useranswer, phrase, 15) != 0){
printf ("Nope, try again!\n");
printf("You have used %d out of 3 tries!\n", tries);
if (tries == 2){
printf("Here's your final hint:xxx...\n");
}
if (tries == 3){
printf("You didn't get it. The answer is: our favorite saying!\n");
}
tries++;
}
if (strncmp(useranswer, phrase, 15) == 0){
printf("Damn, you're good. Well done.\n");
score += 10;
break;
}
}
The output of this code is:
Question #3 (10 points): What is our secret saying?
YOUR ANSWER:our favorite saying
Nope, try again!
You have used 1 out of 3 tries!
YOUR ANSWER:Nope, try again!
You have used 2 out of 3 tries!
Here's your final hint:xxx...
YOUR ANSWER:Nope, try again!
You have used 3 out of 3 tries!
You didn't get it. The answer is: our favorite saying!
(It only allowed me to input once, and I typed "our favorite saying".)
In comments you could find why your format specifier in scanf doesn't work.
An alternative is to use fgets instead, maybe in an helper function which takes care of some of the corner cases that can arise while reading user input:
#include <ctype.h>
char *read_line( char *buf, size_t n, FILE *pfin )
{
ssize_t length = 0;
int ch;
if ( !buf || n == 0 )
return NULL;
/* Consume trailing control characters, like '\0','\n', '\r', '\f'...
but also '\t'. Note that ' ' is not skipped. */
while ( (ch = fgetc(pfin)) != EOF && iscntrl(ch) ) { }
if ( ch == EOF )
return NULL;
/* At least one char is printable */
*buf = ch;
++length;
/* Read from file till a newline or up to n-2 chars. The remaining chars
are left in the stream buffer. Return NULL if no char is read. */
if ( fgets(buf + 1, n - 1, pfin) )
{
/* Trim the string to the first control character */
while ( !iscntrl(buf[length]) )
{
++length;
}
buf[length] = '\0';
}
return buf;
}
I'd change the following logic too. OP uses strncmp(useranswer, phrase, 15) multiple times, but that magic number 15 is lower then phrase's size so it ends up comparing only a substring.
while ( tries <= 3 ) {
printf("YOUR ANSWER:");
if ( !read_line(useranswer, sizeof useranswer, stdin) ) {
printf("Error: Unexpected end of input.\n");
exit(EXIT_FAILURE);
}
if( strcmp(useranswer, phrase) == 0 ) {
printf("Damn, you're good. Well done.\n");
score += 10;
break;
} else {
printf ("Nope, try again!\n");
printf("You have used %d out of 3 tries!\n", tries);
if (tries == 2) {
printf("Here's your final hint:xxx...\n");
}
if (tries == 3) {
printf("You didn't get it. The answer is: our favorite saying!\n");
}
tries++;
}
}
As a final note, I found OP declaration of phrase a bit weird (maybe a typo):
const char *phrase = {"our favorite saying\0"};
// string literals are already ^^ null terminated...
While we can use a simple array declaration, like:
const char phrase[] = "our favorite saying";
Consider also what values sizeof phrase returns in those two different cases.
Thanks to #chux for all the valuable hints and the interesting links provided:
https://stackoverflow.com/a/27729970/4944425
https://stackoverflow.com/a/28462221/4944425
And to #Dmitri for having pointed out in his comment that once we are sure that both the strings are null terminated, we can use strcmp instead of strncmp.
Related
I have this code and I need help converting the comments to c code
// if the input of scanf() is "q"
{
break;
}
else
{
// convert to int
}
Firstly, how do I check if an input is a certain character. Secondly, how do I turn a string into an integer. Example: "123" -> 123
Things I've tried, that didn't work: (it is possible that I implemented these solutions incorrectly)
how does scanf() check if the input is an integer or character?
Convert char to int in C and C++
I am not using any standard libraries except for stdio.h to print some logging information on the window
you have to know also that any string is terminated by null character which is '\0' to indicate the termination of the string , also you have to check is the user entered characters not numbers and so on (that's not implemented in this code).
I also handled if negative numbers are entered.
but you have to handle if the user entered decimals numbers , to sum up . there are so many cases to handle.
and here the edited code :
#include <stdio.h>
int main(){
char inputString[100];
printf("enter the input:\n");
scanf("%s", &inputString);
if(inputString[0] == 'q' && inputString[1] == '\0' )
{
printf("quiting\n");
//break;
}
else {
int i = 0;
int isNegative = 0;
int number = 0;
// check if the number is negative
if (inputString[0] == '-') {
isNegative = 1;
i = 1;
}
// convert to int
for ( ;inputString[i] != '\0' ; i++) {
number *= 10;
number += (inputString[i] - '0');
}
if(isNegative == 1)
number *= -1;
printf("you entered %d\n", number);
}
return 0;
}
The fundamental question here is, Do you want to use scanf?
scanf is everyone's favorite library function for easily reading in values. scanf has an input specifier, %d, for reading in integers.
And it has a different input specifier, %s, for reading in arbitrary strings.
But scanf does not have any single input specifier that means, "Read in an integer as an integer if the user types a valid integer, but if the user types something like "q", have a way so I can get my hands on that string instead."
Unless you want to move mountains and implement your own general-purpose input library from scratch, I think you have basically three options:
Use scanf with %d to read integers as integers, but check scanf's return value, and if scanf fails to read an integer, use that failure to terminate input.
Use scanf with %s to read the user's input as a string, so you can then explicitly test if it's a "q" or not. If not, convert it to an integer by hand. (More on this below.)
Don't use scanf at all. Use fgets to read the user's input as a whole line of text. Then see if it's a "q" or not. If not, convert it to an integer by hand.
Number 1 looks something like this:
while(some loop condition) {
printf("enter next integer, or 'q' to quit:\n");
if(scanf("%d", &i) != 1) {
/* end of input detected */
break;
}
do something with i value just read;
}
The only problem with this solution is that it won't just stop if the user types "q", as your original problem statement stipulated. It will also stop if the user types "x", or "hello", or control-D, or anything else that's not a valid integer. But that's also a good thing, in that your loop won't get confused if the user types something unexpected, that's neither "q" nor a valid integer.
My point is that explicitly checking scanf's return value like this is an excellent idea, in any program that uses scanf. You should always check to see that scanf succeeded, and do something different if it fails.
Number 2 would look something like this:
char tmpstr[20];
while(some loop condition) {
printf("enter next integer, or 'q' to quit:\n");
if(scanf("%19s", tmpstr) != 1) {
printf("input error\n");
exit(1);
}
if(strcmp(tmpstr, "q") == 0) {
/* end of input detected */
break;
}
i = atoi(tmpstr); /* convert string to integer */
do something with i value just read;
}
This will work well enough, although since it uses atoi it will have certain problems if the user types something other than "q" or a valid integer. (More on this below.)
Number 3 might look like this:
char tmpstr[20];
while(some loop condition) {
printf("enter next integer, or 'q' to quit:\n");
if(fgets(tmpstr, 20, stdin) == NULL) {
printf("input error\n");
exit(1);
}
if(strcmp(tmpstr, "q\n") == 0) {
/* end of input detected */
break;
}
i = atoi(tmpstr); /* convert string to integer */
do something with i value just read;
}
One thing to note here is that fgets includes the newline that the user typed in the string it returns, so if the user types "q" followed by the Enter key, you'll get a string back of "q\n", not just "q". You can take care of that either by explicitly looking for the string "q\n", which is kind of lame (although it's what I've done here), or by stripping the newline back off.
Finally, for both #2 and #3, there's the question of, what's the right way to convert the user's string to an integer, and what if it wasn't a valid integer? The easiest way to make the conversion is to call atoi, as my examples so far have shown, but it has the problem that its behavior on invalid input is undefined. In practice, it will usually (a) ignore trailing nonnumeric input and (b) if there's no numeric input at all, return 0. (That is, it will read "123x" as 123, and "xyz" as 0.) But this behavior is not guaranteed, so these days, most experts recommend not using atoi.
The recommended alternative is strtol, which looks like this:
char *endp;
i = strtol(tmpstr, &endp, 10); /* convert string to integer */
Unlike atoi, strtol has guaranteed behavior on invalid input. Among other things, after it returns, it leaves your auxiliary pointer endp pointing at the first character in the string it didn't use, which is one way you can determine whether the input was fully valid or not. Unfortunately, properly dealing with all of the ways the input might be invalid (including trailing garbage, leading garbage, and numbers too big to convert) is a surprisingly complicated challenge, which I am not going to belabor this answer with.
Here are some guidelines:
scanf("%s", &var) is incorrect: you should pass the maximum number of characters to store into the array var and pass the array without the & as it will automatically convert to a pointer to its first element when passed as an argument:
char var[100];
if (scanf("%99s", var) != 1) {
printf("premature end of file\n");
return 1;
}
to compare the string read to "q", you can use strcmp() declared in <string.h>:
if (strcmp(var, "q") == 0) {
printf("quitting\n");
return 0;
}
to convert the string to the number it represents, use strtol() declared in <stdlib.h>:
char *p;
long value = strtol(var, &p, 0);
testing for a proper conversion is tricky: strtol() updated p to point to the character after the number and set errno in case of range error:
errno = 0;
char *p;
long value = strtol(var, &p, 0);
if (p == var) {
printf("not a number: %s\n", p);
return 1;
}
if (*p != '\0') {
printf("extra characters: %s\n", p);
return 1;
}
if (errno) {
printf("conversion error: %s\n", strerror(errno));
return 1;
}
printf("the number entered is: %ld\n", value);
return 0;
Here is a complete program:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char var[100];
char *p;
long value;
printf("Enter a number: ");
if (scanf("%99s", var) != 1) {
printf("premature end of file\n");
return 1;
}
if (strcmp(var, "q") == 0) {
printf("quitting\n");
return 0;
}
errno = 0;
value = strtol(var, &p, 0);
if (p == var) {
printf("not a number: %s\n", p);
return 1;
}
if (*p != '\0') {
printf("extra characters: %s\n", p);
return 1;
}
if (errno) {
printf("conversion error: %s\n", strerror(errno));
return 1;
}
printf("the number entered is: %ld\n", value);
return 0;
}
You can try this: (Assuming only positive integers needs to convert)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
// Write C code here
char var[100];
int numb_flag=1, i=0,number=0;
scanf("%s",var);
while(var[i]!='\0') { // Checking if the input is number
if(var[i]>=48 && var[i]<=57)
i++;
else {
numb_flag = 0;
break;
}
}
if(numb_flag==1) {
number = atoi(var);
printf("\nNumber: %d",number);
} else {
printf("\nNot A Number");
}
return 0;
}
//Mind that in order to be more precise you could also use atof().
//The function works the same way as atoi() but is able to convert float
// (returned value is 'double') the string s
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXILEN 100 /*change the value based on your needs*/
int main(){
int n, lim = MAXILEN;
char s[MAXILEN], *p = s, c;
/*taking the string from the input -- I do not use scanf*/
while(--lim > 0 && (c = getchar()) != EOF && c != '\n')
*p++ = c;
//here you can also do the check (if you want the '\n' char):
//if(c == '\n')
// *s++ = c;
*p = '\0';
if(s[0] == 'q' && s[1] == '\0')
exit(EXIT_SUCCESS); /*change the argument based on your needs*/
else
n = atoi(s);
printf("[DEBUG]: %d\n", n);
}
I want to use the scanf function to get inputs that are either two numbers, or one number from the user and put them in an array. However, I'm not sure how I can use this same function to get inputs for both one element of the array, and also two elements of the array.
i.e. if the user enters, 9 0, it should be able to successfully store that in an array and move onto new code, or if the user enters something like 1, it should also be able to successfully store that in the array, and move onto new code.
I've tried putting the scanf into a while loop:
int scanned_array[2] = {};
int element = 0;
while(scanf("%d", &scanned_array[element]) {
//... more code here which will have different functions depending on the input...
element++;
}
How can I successfully do this while only using the scanf function, while loops, arrays and if statements?
**Edit: Just wondering, if I changed my code according to what was suggested below by #nmgari, how could I go to if(num == 1) { ... without having to press ctrl+d?
Thanks for reading!
If i understand correctly you want to call scanf() once and read either one number or two.
Something like this should work:
int scanned_array[2];
int num_input = 0;
num_input = scanf("%d %d", &scanned_array[0], &scanned_array[1]);
if(num_input == 1)
{
//Do something
}
else if (num_input == 2)
{
//Do somethine else
}
Anyway, you need to consider that the second element in the array may never get a value.
You should read the input line with fgets() and parse it with sscanf():
char buf[120];
if (fgets(buf, sizeof buf, stdin)) {
int i1, i2;
switch (sscanf(buf, "%d%d", &i1, &i2)) {
case 2:
/* the user entered 2 integers */
handle_2_integers(i1, i2);
break;
case 1:
/* the user entered a single integer */
handle_1_integer(i1);
break;
default:
/* the user did not enter a number */
handle_invalid_input();
break;
}
} else {
/* the input stream is at end of file or encountered an error */
handle_end_of_file();
}
If you run scanf("%d%d", &i1, &i2), scanf() will keep reading the input stream until either end of file, or 2 integers have been read or an character has been input that cannot be converted to an integer, possibly reading multiples lines of input for one of these cases to occur. If you want to handle a single line of input, you cannot use scanf() directly.
A separate scan for whitespace could be used.
The scanset %1[ \t\r\n] will capture whitespace character by character. The loop will exit on non-whitespace or a newline.
Then try to scan an integer.
#include <stdio.h>
#include <stdlib.h>
int main ( void) {
char space[2] = "";
int scanned = 0;
int scanned_array[2] = { 0};
while ( 1) {
while ( 1 == scanf ( "%1[ \t\r\n]", space)) {
if ( '\n' == space[0]) {
break;
}
}
if ( '\n' == space[0]) {
break;
}
if ( 1 != scanf ( "%d", &scanned_array[scanned])) {
fprintf ( stderr, "bad input\n");
return 1;
}
++scanned;
if ( 2 <= scanned) {
break;
}
}
for ( int each = 0; each < scanned; ++each) {
printf ( "%d\n", scanned_array[each]);
}
return 0;
}
I m trying to do this little programm with defensive programming but its more than difficult for me to handle this avoiding the Loop-Goto as i know that as BAD programming. I had try with while and do...while loop but in one case i dont have problem. Problem begins when i m going to make another do...while for the second case ("Not insert space or click enter button"). I tried and nested do...while but here the results was more complicated.
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int i;
int length;
char giventext [25];
Loop:
printf("String must have 25 chars lenght:\n");
gets(giventext);
length = strlen(giventext);
if (length > 25) {
printf("\nString has over %d chars.\nMust give a shorter string\n", length);
goto Loop;
}
/* Here i trying to not give space or nothing*/
if (length < 1) {
printf("You dont give anything as a string.\n");
goto Loop;
} else {
printf("Your string has %d\n",length);
printf("Letter in lower case are: \n");
for (i = 0; i < length; i++) {
if (islower(giventext[i])) {
printf("%c",giventext[i]);
}
}
}
return 0;
}
Note that your code is not defensive at all. You have no way to avoid a buffer overflow because,
you check for the length of the string after it has been input to your program so after the buffer overflow has already occurred and
you used gets() which doesn't check input length and thus is very prone to buffer overflow.
Use fgets() instead and just discard extra characters.
I think you need to understand that strlen() doesn't count the number of characters of input but instead the number of characters in a string.
If you want to ensure that there are less than N characters inserted then
int
readinput(char *const buffer, int maxlen)
{
int count;
int next;
fputc('>', stdout);
fputc(' ', stdout);
count = 0;
while ((next = fgetc(stdin)) && (next != EOF) && (next != '\n')) {
// We need space for the terminating '\0';
if (count == maxlen - 1) {
// Discard extra characters before returning
// read until EOF or '\n' is found
while ((next = fgetc(stdin)) && (next != EOF) && (next != '\n'))
;
return -1;
}
buffer[count++] = next;
}
buffer[count] = '\0';
return count;
}
int
main(void)
{
char string[8];
int result;
while ((result = readinput(string, (int) sizeof(string))) == -1) {
fprintf(stderr, "you cannot input more than `%d' characters\n",
(int) sizeof(string) - 1);
}
fprintf(stdout, "accepted `%s' (%d)\n", string, result);
}
Note that by using a function, the flow control of this program is clear and simple. That's precisely why goto is discouraged, not because it's an evil thing but instead because it can be misused like you did.
Try using functions that label logical steps that your program needs to execute:
char * user_input() - returns an input from the user as a pointer to a char (using something other than get()! For example, look at scanf)
bool validate_input(char * str_input) - takes the user input from the above function and performs checks, such as validate the length is between 1 and 25 characters.
str_to_lower(char * str_input) - if validate_input() returns true you can then call this function and pass it the user input. The body of this function can then print the user input back to console in lower case. You could use the standard library function tolower() here to lower case each character.
The body of your main function will then be much simpler and perform a logical series of steps that tackle your problem. This is the essence of defensive programming - modularising your problem into separate steps that are self contained and easily testable.
A possible structure for the main function could be:
char * user_input();
bool validate_input(char *);
void str_to_lower(char *);
int main()
{
char * str_input = user_input();
//continue to get input from the user until it satisfies the requirements of 'validate_input()'
while(!validate_input(str_input)) {
str_input = user_input();
}
//user input now satisfied 'validate_input' so lower case and print it
str_to_lower(str_input);
return 0;
}
I'm a beginner programmer trying to learn C. Currently I'm taking a class and had a project assigned which I managed to finish pretty quickly, at least the main part of it. I had some trouble coding around the main() if functions though, because I started using some new functions (that is, fgets and strncmp). Now, my code works in my compiler, but not in any of the online compilers. So I'm wondering if I did something wrong with it, or if there is any way I can improve it.
Any help or contribution is appreciated, thanks!
Below is the code, the encrypt and decrypt functions are the first two functions before the main, where I believe most of the messy shortcut-code might be.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char * Encrypt(char sentence[])
{
int primes[12] = {1,2,3,5,7,11,13,17,19,23,29,31};
int x = 0;
int counter = 0;
int ispositive = 1;
while(sentence[x] != 0)
{
if (counter == 0)
{
ispositive = 1;
}
else if(counter == 11)
{
ispositive = 0;
}
if (ispositive == 1)
{
sentence[x] = sentence[x] + primes[counter];
counter++;
}
else if (ispositive == 0)
{
sentence[x] = sentence[x] + primes[counter];
counter--;
}
x++;
}
return sentence;
}
char * Decrypt(char sentence[])
{
int primes[12] = {1,2,3,5,7,11,13,17,19,23,29,31};
int x = 0;
int counter = 0;
int ispositive = 1;
while(sentence[x] != 0)
{
if (counter == 0)
{
ispositive = 1;
}
else if(counter == 11)
{
ispositive = 0;
}
if (ispositive == 1)
{
sentence[x] = sentence[x] - primes[counter];
counter++;
}
else if (ispositive == 0)
{
sentence[x] = sentence[x] - primes[counter];
counter--;
}
x++;
}
return sentence;
}
int main()
{
char message[100];
char input[7];
char *p;
int c;
int condition = 1;
while(condition == 1)
{
printf("Would you like to Encrypt or Decrypt a message? (Type TurnOff to end the program) \n \n");
fgets(input,7, stdin);
fflush(stdin);
if (!strncmp(input,"Encrypt",strlen(input)))
{
printf("\n \n Enter the message you want to Encrypt below: \n \n");
fgets(message, 100, stdin);
Encrypt(message);
printf("\n Your encrypted message is: ");
printf("%s", message);
fflush(stdin);
printf("\n \n");
}
else if (!strncmp(input,"Decrypt",strlen(input)))
{
printf("\n \n Enter the message you want to Decrypt below: \n \n");
fgets(message, 100, stdin);
Decrypt(message);
printf("\n Your Decrypted message is: ");
printf("%s", message);
fflush(stdin);
printf("\n \n");
}
else if (!strncmp(input,"TurnOff",strlen(input)))
{
printf("\n \n Thank you for using the program! \n \n");
condition = 0;
}
else
{
printf("That's not a valid input \n \n");
}
}
}
After the printf you doing fflush(stdin) instead of you have to do fflush(stdout). Because you are printing the output. The output is printed in stdout. So, you have to flush the stdout buffer not stdin buffer.
You can use the strcmp instead of strncmp. Because in here you are comparing the hole character in the input array. So, the strcmp is enough.
strcmp(input, "Encrypt").
The strcmp or strncmp function get the input in array upto a null or the size of the string you are declared.
The size for the input array is too few.
lets take the input is like below.
Encrypt\n
sureshkumar\n
In here you first fgets in main function reads the upto "Encrypt" it does not skip the '\n'.
The '\n' is readed form another fgets. So, it does not get the encrypt message "sureshkumar".
So, you have to modify you code. You will increase the size for the input array.
And check the condition like below.
if(strcmp(input, "Encrypt\n") == 0)
{
/*
You will do what you want
*/
}
You can use the above way or you can read the input and overwrite the '\n' to '\0' in the input array and compare as it is you before done. But you have to use the strcmp. Because the array size is incremented.
This is the right way for using the fgets. Use of fgets is to read upto new line.
You have to use the null character for the character array. Because this is necessary for the character arrays.
Your initiative towards using strcmp() and fgets() is good, though, it requires following understanding:
1. fgets() writes atmost size-1 characters into buffer and then terminates with '\0'. In your case,
fgets(input,7, stdin);
You gave input "Encrypt"/"Decrypt"/"TurnOff"
but
'input' buffer got data as "Encryp"/"Decryp"/"TurnOf"
because of size=7 (only (7-1)=6 characters being read, last position reserved for '\0' character by fgets()).
Your strncmp() calls will work correctly with your current code, since for strncmp(), length to compare
n = strlen(input) = 6;
6 characters are matching fine in all three cases of "Encrypt"/"Decrypt"/"TurnOff".
Summary is that your current code will work fine, But your actual intention is violated. You actually wanted to read and compare full length of option string.
EDIT DONE : Modifications suggested:
#define SIZE 9 <-- EDIT : Change done here, instead of 7, size = 9 is used
to allow reading '\n' so that it does not affect
fgets() read in successive iteration
char input[SIZE];
fgets(input, SIZE, stdin); // read str is e.g. "Encrypt\n"
input[SIZE-2] = '\0'; // To replace '\n' with '\0'
Similarly, you need to be careful when reading into 'message' array using fgets().
Here's a basic question:
How can I take the input from a user and only accept numbers?
I know I need to use this start:
do{
ch=getchar();
}while (ch != '\n');
But I know it's not enough. This will block every input, including numbers, so I need to break when input is number.
also how do I break not after the first digit of the number?
I tried looking this up with no luck.
thanks!
When you need to perform error checking, do different things based on the input, etc., it's best to read user input line by line and process each line as you see fit.
// Make it large enough for your needs.
#define LINE_LENGTH 200
char line[LINE_LENGTH];
// Keep reding lines of text until there is nothing to read.
while ( fgets(line, sizeof(line), stdin) != NULL )
{
// Process contents of line.
}
If you expect to see only one number per line, you can use sscanf to extract numbers from each line.
while ( fgets(line, sizeof(line), stdin) != NULL )
{
int num;
if ( sscanf(line, "%d", &num) == 1 )
{
// Got a number. Use it.
}
}
The probably easiest way to read in a number is using scanf:
int number;
if (scanf("%d",&number) == 1) {
printf("successfully read number %d\n",number);
} else {
printf("not a number.\n");
}
It skips leading white spaces and then takes characters from stdin as long as these match an integral number format. Note that you still might have to press "enter" before your program will proceed, because the operating system might buffer the input (beyond your control).
Note that a ch=getchar() will take also the first non-digit value from stdin, which can then not be consumed by any further access to stdin anymore. scanf, in contrast, keeps this character in the buffer for later use.
Just check if the input is some value between '0' and '9'
#include <stdio.h>
int main(void)
{
size_t len = 0;
char str[32];
int ch;
while (len < sizeof(str) - 1) {
ch = getchar();
if ((ch >= '0') && (ch <= '9')) {
str[len++] = (char)ch;
} else {
break;
}
}
str[len] = '\0';
puts(str);
return 0;
}
simple, nice and neat solution:), I used to solve similar questions when I started programming, this will let you only input numbers
#include <stdio.h>
int main()
{
char ch;
do{
ch=getchar();
}while (!(ch>=48 && ch<=57));
printf("yay,we got a number : %c !",ch);
return 0;
}