I have created a code reverse a string but for some reason it is not working. But I think my logic is right. Then why is it not working??
#include <stdio.h>
#include <stdlib.h>
int main() {
char words[100];
int i=0;
printf("Enter a word/sentence: ");
scanf("%s", words);
while (words[i]!='\0') {
++i;
}
printf("\nThe Reverse is: ");
while (i<=0) {
printf("%s",words[i]);
i--;
}
return 0;
}
While you already have an answer, there are a few additional points you need to consider before you have a solution that doesn't have the potential to invoke Undefined behavior.
First, always, always validate all user input. For all you know a cat could have gone to sleep on the 'L' key (with millions being entered), or a more likely case, the user just decides to type a 100-char sentence (or more) which leaves 'words' as an array of chars that is NOT nul-terminated and thus not a valid string in C. Your loop to get the length now invokes Undefined Behavior by reading beyond the end of words off into the stack until the first random '0' is encounter or a SegFault occurs.
To prevent this behavior (you should really just use fgets) but with scanf you can provide a field-width modifier to prevent reading more than length - 1 chars. This insures space for the nul-terminating character.
Further, the "%s" conversion-specifier stops conversion on the first whitespace character encountered -- making your "Enter a .../sentence" an impossibility because scanf ("%s", words) will stop reading after the first word (at the first whitespace.
To correct this problem (you should really just use fgets) or with scanf you can use a character class (stuff between [...]) as the conversion specifier that will read until a '\n' is encountered., e.g. scanf ("%[^\n]", words). However, recall, that is still not good enough because more than 99-chars can be entered leaving the string un-terminated at 100 and invoking Undefined Behavior at character 101 (off the end of the array).
To prevent this problem (ditto on fgets), or include the field-width modifier, e.g. scanf ("%99[^\n]", words). Now no more than 99-chars will be read regardless of the cat sleeping on the 'L' key.
Putting that altogether, you could do something like:
#include <stdio.h>
#define MAXC 100 /* if you need a constant, define one */
int main(void) {
char words[MAXC] = "";
int i = 0, rtn = 0; /* rtn - capture the return of scanf */
printf ("Enter a word/sentence : ");
if ((rtn = scanf ("%99[^\n]", words)) != 1) { /* validate ! */
if (rtn == EOF) /* user cancel? [ctrl+d] or [ctrl+z]? */
fprintf (stderr, "user input canceled.\n");
else /* did an input failure occur ? */
fprintf (stderr, "error: invalid input - input failure.\n");
return 1; /* either way, bail */
}
for (; words[i]; i++) {} /* get the length */
printf ("Reversed word/sentence: ");
while (i--)
putchar (words[i]); /* no need for printf to output 1-char */
putchar ('\n');
return 0;
}
Example Use/Output
$ ./bin/strrevloops
Enter a word/sentence : My dog has fleas.
Reversed word/sentence: .saelf sah god yM
Look things over and let me know if you have any further questions.
There are few mistakes in your program.
After you have reached the end of the string.You should do i-- as your array index of i will be pointing to '\0'.
Your while loop checks for <= but it should be >=.
Use %c for printing chararcters. %s is used to print strings and not char.
#include <stdio.h>
#include <stdlib.h>
int main() {
char words[100];
int i=0;
printf("Enter a word/sentence: ");
scanf("%s", words);
while (words[i]!='\0') {
++i;
}
i--;
printf("\nThe Reverse is: ");
while (i>=0) {
printf("%c",words[i]);
i--;
}
return 0;
}
Related
I'm very new to C, any help would be greatly appreciated.
I can't use the <string.h> or <ctype.h> libraries.
This is the code I have:
int main(void)
{
char character;
printf("Introduce characters: ");
scanf(" %c", &character);
printf("\nSize of character: %d", sizeof(character)/sizeof(char));
return 0;
}
This only prints 1 as the size.
I read in another post that the problem was that initializing character by char character; would only let me store 1 single character. So, I modified it to be an array:
int main(void)
{
char character[10];
printf("Introduce maximum 10 characters: ");
scanf(" %s", character);
printf("\nSize of character: %d", sizeof(character)/sizeof(char));
return 0;
}
The problem now is that by doing character[10], it prints out that the size is 10. How would I go about fixing this?
sizeof(character)/sizeof(char) gives you the size of the array you declared, not the size of what the user has entered.
sizeof(character) gives the size of the entire array in bytes
sizeof(char) gives the size of a single character in bytes
So, when you do sizeof(character)/sizeof(char), you get the actual size (i.e. number of elements) of your array. What you are trying to achieve can be done with strlen(). But since you can't use <string.h>, you can write it yourself:
int strlen2(char *s)
{
int size;
for (size = 0; s[size]; size++)
;
return size;
}
Then use it like:
#include <stdio.h>
int main(void)
{
char character[10];
printf("Introduce maximum 10 characters: ");
scanf("%s", character);
printf("\nSize of character: %d", strlen2(character));
}
strlen2() counts the number of characters of your string, it stops counting when it encounters the first \0 character (null terminator).
Avoid using scanf() to read input
Your code is prone to bugs. If the user enters a string more than 9 characters long (don't forget the \0 is added at the end of your string), you'll get a buffer overflow, because character is only supposed to contain 10 characters. You would want to limit the number of characters read into your string:
scanf("%9s", character); // Read only the first 9 characters and ignore the rest
Moreover, scanf() is used to parse input, not to actually read it. Use fgets() instead:
#include <stdio.h>
#include <string.h> // for strcspn()
int main(void)
{
char character[10];
printf("Introduce maximum 10 characters: ");
if(!fgets(character, 10, stdin)) {
fprintf(stderr, "Error reading input.\n");
return 1;
}
character[strcspn(character, "\n")] = '\0'; // fgets() reads also `\n` so make sure to null-terminate the string
printf("\nSize of character: %zu", strlen(character));
}
fgets() accepts three arguments:
The first one is the array in which you want to store user input
The second one is the size of your array
The third one is the file stream you want to read from
It returns NULL on failure so you should check that as well.
Well if you can't use any headers, maybe you can create a custom strlen() function.
strlen() pretty much counts all character until the '\0' character is found. '\0' is used to signify the end of string and is automatically appended by scanf("%s",...).
#include <stdio.h>
size_t ms_length(const char *s)
{
size_t i = 0;
for (; s[i] != '\0'; i++)
;
return i;
}
int main(void)
{
char *str = "hello";
printf("%zu\n", ms_length(str));
return 0;
}
And if you want to be pedantic, you might even want to check the return value of scanf(), for input errors and also apply a limit to the character to be read to avoid a buffer overflow.
if (scanf(" %9s", character) != 1) /* 9 characters + 1 reserved for \0 */
{
/* handle error */
return 1;
}
I'm new to C and programming in general. It's a guessing game where the user has a certain amount of guesses to guess whatever the hidden message is.
Unfortunately, even if I enter the correct word, it does not register it as being correct.
#include <stdio.h>
#include <stdlib.h>
Lost(){
printf("You lost");
}
Won(){
printf("You won");
}
int main(void)
{
char HiddenMessage[7] = "Cameron";
char Guess[50] = "";
int Tries = 0;
int MaxTries = 5;
while(Tries != MaxTries && strcmp(HiddenMessage, Guess) != 0){
printf("Guess the secret word:");
scanf("%s", Guess);
Tries++;
if (Tries == MaxTries){
Lost();
}
else if (strcmp(HiddenMessage, Guess) == 0){
Won();
}
}
return 0;
}
How do I structure this to ensure that if a Guess occurs correctly within the number of tries it runs Won();
You should have received a warning about:
char HiddenMessage[7] = "Cameron";
if your compiler was doing its job properly :-)
Seven characters is not enough to store Cameron and the end-of-string marker. Try it again with:
char HiddenMessage[] = "Cameron";
This will make sure enough characters are set aside for the full string.
If you're interested, this is covered in C11 6.7.9 Initialization /14 (emphasis added):
An array of character type may be initialized by a character string literal or UTF−8 string literal, optionally enclosed in braces. Successive bytes of the string literal (including the terminating null character if there is room or if the array is of unknown size) initialize the elements of the array.
So what your code will give you is the sequence of characters { 'C', 'a', 'm', 'e', 'r', 'o', 'n' } but with no \0 at the end to make it a C string. That means strcmp cannot be guaranteed to give you the results you want (it will possibly run off the end of the array during the comparison).
And, as an aside, scanf with the unbounded %s format specifier is considered rather dangerous in non-trivial code, since there's no way to protect against buffer overflow.
If you're looking for a fairly bullet-proof user input function that can detect and mitigate this, have a look at this earlier answer of mine.
It allows prompting, prevents buffer overflow, properly handles line-based user input (no half lines delivered to user) and so on.
It's what I use for simple console applications (where no better user input method is available).
There are, essentially, four errors in your code:
As paxdiablo has stated, your HiddenMessage array is not large enough to hold the text you have given plus the nul terminator.
You need to define (or at least declare) your Lost and Won functions before you use them.
The definitions of these two functions are incorrect, as you have not specified a return type: void is suitable for functions that don't return anything.
You must include stdio.h to get the definitions of printf and scanf
Here's a fixed (and working) version of your code with the corrections made:
#include <stdlib.h>
#include <stdio.h> // MUST include this for "printf" and "scanf" functions
// You can keep these DEFINITIONS after "main" if you like, but then you'll need to
// have "pre-declarations" of them (the two commented lines immediately below).
// void Lost();
// void Won();
void Lost() {
printf("You lost");
}
void Won() {
printf("You won");
}
int main()
{
char HiddenMessage[8] = "Cameron"; // Added enough space for the nul terminator
char Guess[50] = "";
int Tries = 0;
int MaxTries = 5;
while (Tries != MaxTries && strcmp(HiddenMessage, Guess) != 0) {
printf("Guess the secret word:");
scanf("%s", Guess);
Tries++;
if (Tries == MaxTries) {
Lost();
}
else if (strcmp(HiddenMessage, Guess) == 0) {
Won();
}
}
return 0;
}
Feel free to ask for further clarification and/or explanation.
Another significant problem is your failure to validate any of the input. Any time (means ANY time) you take input, you must validate the input succeeds before relying on the data. Failure to validate invites undefined behavior.
Validations are simple, if you read input with a function check the return to validate you got all the input you were expecting. For example:
printf (" try no. %d - Guess the seceret word: ", tries + 1);
if (scanf ("%49s", guess) != 1) { /* read/validate word */
fputs ("(error: EOF encountered reading guess.)\n", stderr);
return 1;
}
(note: the use of the field-width modifier to limit the number of characters that can be read. Failing to control the number of characters than can be input will read to attempt to write beyond the bounds of your array if the user enters 50 (or more) characters.)
Your logic is a bit awkward. All you need to do is loop continually until the user either wins the game or exhausts the number of tries available. Rearranging your logic slightly, you could do something like:
(Edited to empty-stdin)
printf ("HANGMAN - you have %d tries to guess the word.\n\n", MAXTRIES);
for (;;) { /* loop continually until win or tries exhausted */
printf (" try no. %d - Guess the seceret word: ", tries + 1);
if (scanf ("%49s", guess) != 1) { /* read/validate word */
fputs ("(error: EOF encountered reading guess.)\n", stderr);
return 1;
}
if (strcmp (hiddenmsg, guess) == 0) /* compare hiddenmsg & guess */
break; /* if matched, break loop */
if (++tries == MAXTRIES) { /* test if all tries exhausted */
fputs ("\nyou have exhausted all guesses - you lost :(\n", stderr);
return 1;
}
/* empty stdin */
for (int c = getchar(); c != EOF && c != '\n'; c = getchar()) {}
}
puts ("\ncongratulations - you won.\n"); /* issue congrats & exit */
Putting it altogether in an example, you could do:
#include <stdio.h>
#include <string.h>
#define MAXTRIES 5
#define MAXGUESS 50
int main (void) {
char hiddenmsg[] = "Cameron",
guess[MAXGUESS] = "";
int tries = 0;
printf ("HANGMAN - you have %d tries to guess the word.\n\n", MAXTRIES);
for (;;) { /* loop continually until win or tries exhausted */
printf (" try no. %d - Guess the seceret word: ", tries + 1);
if (scanf ("%49s", guess) != 1) { /* read/validate word */
fputs ("(error: EOF encountered reading guess.)\n", stderr);
return 1;
}
if (strcmp (hiddenmsg, guess) == 0) /* compare hiddenmsg & guess */
break; /* if matched, break loop */
if (++tries == MAXTRIES) { /* test if all tries exhausted */
fputs ("\nyou have exhausted all guesses - you lost :(\n", stderr);
return 1;
}
/* empty stdin */
for (int c = getchar(); c != EOF && c != '\n'; c = getchar()) {}
}
puts ("\ncongratulations - you won.\n"); /* issue congrats & exit */
}
Example Use/Output
Typical try and fail game:
$ ./bin/hangman
HANGMAN - you have 5 tries to guess the word.
try no. 1 - Guess the seceret word: Alligator
try no. 2 - Guess the seceret word: Campers
try no. 3 - Guess the seceret word: Scam
try no. 4 - Guess the seceret word: Horses
try no. 5 - Guess the seceret word: Bananna
you have exhausted all guesses - you lost :(
A lucky win:
$ ./bin/hangman
HANGMAN - you have 5 tries to guess the word.
try no. 1 - Guess the seceret word: Lightning
try no. 2 - Guess the seceret word: Thunder
try no. 3 - Guess the seceret word: Geroge
try no. 4 - Guess the seceret word: Cameron
congratulations - you won.
(Testcase After Edit w/Example from Comment)
$./bin/hangman
HANGMAN - you have 5 tries to guess the word.
try no. 1 - Guess the seceret word: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxCameron
try no. 2 - Guess the seceret word: foo
try no. 3 - Guess the seceret word: Cameron
congratulations - you won.
Look things over and let me know if you have any further questions.
As strcmp compares the difference between each character till the end of string that is \0 So your buffer needs to be large enough to hold your string i.e. char HiddenMessage[8] = "Cameron";
PS you can avoid a lot of lengthy code
#include <stdlib.h>
int main()
{
char HiddenMessage[8] = "Cameron";
char Guess[50] = "";
int Tries = 0;
int MaxTries = 5;
while (Tries != MaxTries)
{
printf("Guess the secret word:");
scanf("%s", Guess);
Tries++;
if (strcmp(HiddenMessage, Guess) == 0)
{
Won();
return 0;
}
}
Lost();
return 0;
}
void Lost()
{
printf("You lost");
}
void Won()
{
printf("You won");
}
There are multiple problems with your code. The size of HiddenMessage reported by #paxdiablo is just one of them.
You should use fgets instead of scanf because scanf won't consume the newline. You will be stuck on the second iteration.
You increment Tries and test it against MaxTries before testing if the guess was correct. As a consequence the program will tell that the user lost before testing the validity of the last guess.
Once the user guessed the word and won, you must break from the while loop and terminate the program. With your code, after the program reported that the user won, it will ask for another guess if it wasn't the last guess.
Given the following code:
#include <stdio.h>
int main()
{
int testcase;
char arr[30];
int f,F,m;
scanf("%d",&testcase);
while(testcase--)
{
printf("Enter the string\n");
fgets(arr,20,stdin);
printf("Enter a character\n");
F=getchar();
while((f=getchar())!=EOF && f!='\n')
;
putchar(F);
printf("\n");
printf("Enter a number\n");
scanf("%d",&m);
}
return 0;
}
I want a user to enter a string, a character and a number until the testcase becomes zero.
My doubts / questions:
1.User is unable to enter a string. It seems fgets is not working. Why?
2.If i use scanf instead of fgets,then getchar is not working properly, i.e whatever character I input in it just putchar as a new line. Why?
Thanks for the help.
Mixing functions like fgets(), scanf(), and getchar() is error-prone. The scanf() function usually leaves a \n character behind in the input stream, while fgets() usually does not, meaning that the next call to an I/O function may or may not need to cope with what the previous call has left in the input stream.
A better solution is to use one style of I/O function for all user input. fgets() used in conjunction with sscanf() works well for this. Return values from functions should be checked, and fgets() returns a null pointer in the event of an error; sscanf() returns the number of successful assignments made, which can be used to validate that input is as expected.
Here is a modified version of the posted code. fgets() stores input in a generously allocated buffer; note that this function stores input up to and including the \n character if there is enough room. If the input string is not expected to contain spaces, sscanf() can be used to extract the string, leaving no need to worry about the newline character; similarly, using sscanf() to extract character or numeric input relieves code of the burden of further handling of the \n.
#include <stdio.h>
int main(void)
{
int testcase;
char arr[30];
char F;
int m;
char buffer[1000];
do {
puts("Enter number of test cases:");
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
/* handle error */
}
} while (sscanf(buffer, "%d", &testcase) != 1 || testcase < 0);
while(testcase--)
{
puts("Enter the string");
/* if string should not contain spaces... */
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
/* handle error */
}
sscanf(buffer, "%29s", arr);
printf("You entered: %s\n", arr);
putchar('\n');
puts("Enter a character");
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
/* handle error */
}
sscanf(buffer, "%c", &F);
printf("You entered: %c\n", F);
putchar('\n');
do {
puts("Enter a number");
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
/* handle error */
}
} while (sscanf(buffer, "%d", &m) != 1);
printf("You entered: %d\n", m);
putchar('\n');
}
return 0;
}
On the other hand, if the input string may contain spaces, fgets() can read input directly into arr, but then the stored string will contain a \n character, which should probably be removed. One way of doing this is to use the strcspn() function to find the index of the \n:
#include <string.h> // for strcspn()
/* ... */
puts("Enter the string");
/* or, if string may contain spaces */
if (fgets(arr, sizeof arr, stdin) == NULL) {
/* handle error */
}
/* replace newline */
arr[strcspn(arr, "\r\n")] = '\0';
printf("You entered: %s\n", arr);
putchar('\n');
/* ... */
Note that a maximum width should always be specified when using %s with the scanf() functions to avoid buffer overflow. Here, it is %29s when reading into arr, since arr can hold 30 chars, and space must be reserved for the null terminator (\0). Return values from sscanf() are checked to see if user input is invalid, in which case the input is asked for again. If the number of test cases is less than 0, input must be entered again.
Finally got the solution how can we use scanf and fgets together safely.
#include <stdio.h>
int main()
{
int testcase,f,F,m;
char arr[30];
scanf("%d",&testcase);
while((f=getchar())!=EOF && f!='\n')
;
while(testcase--)
{
printf("Enter the string\n");
fgets(arr,30,stdin);
printf("Enter a character\n");
F=getchar();
while((f=getchar())!=EOF && f!='\n')
;
putchar(F);
printf("\n");
printf("Enter a number\n");
scanf("%d",&m);
while((f=getchar())!=EOF && f!='\n')
;
}
}
We need to make sure that before fgets read anything,flushout the buffer with simple while loop.
Thanks to all for the help.
A simple hack is to write a function to interpret the newline character. Call clear() after each scanf's
void clear (void){
int c = 0;
while ((c = getchar()) != '\n' && c != EOF);
}
Refer to this question for further explaination: C: Multiple scanf's, when I enter in a value for one scanf it skips the second scanf
This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 6 years ago.
I have written a small code to take multiple strings as input from user. Prior to that, I'm asking the user to input the number of strings to take as input. While taking strings as input, a new line character automatically occupies the the place of first string. I don't know what is happening :( Here is my code:
#include<stdio.h>
#include<string.h>
void main()
{
char *arr[20],str[40];
int n;
printf("enter the number of strings\n");
scanf("%d",&n);
int i;
printf("Enter the strings\n");[It isn't taking 3 strings as input,as a newline character is already occupying first place][1]
for(i=0;i<n;i++)
{
gets(str);
arr[i]=(char *)malloc(sizeof str);
strcpy(arr[i],str);
}
printf("The Strings are:\n");
for(i=0;i<n;i++)
{
printf(arr[i]);
printf("\n");
}
}
Following on from the comments, there are a number of issues you have in your code. First gets, don't use it, it is a 'hanging' offense -- enough said.
Next, validate all user input. For all you know, a cat could be stepping on the keyboard. Make sure you test what you receive as input, and that it matches what you expect.
Mixing scanf with line-oriented input (e.g. fgets or getline can cause problems for new users. Why? The scanf family of functions do not remove the '\n' and instead leaves it in the input buffer (e.g. stdin). When you then attempt to read with fgets the first character it sees in stdin is what? A '\n', which it reads and considers a whole line. If you are going to use scanf to read the number of strings, it is up to you to remove the '\n' that scanf left in stdin.
It's not hard, you can actually just use the assignment suppression operator provided by scanf in your format string. E.g.:
scanf ("%d%*c", &n);
The * is the assignment suppression operator, which when used with %*c simply tells scanf to read and discard the next character without adding to the match count (e.g. what scanf returns).
You will want to use a while loop instead of a for loop, (or use an independent index) when filling your array. Why? What if the users cancels input with a ctrl + d (or ctrl + z on windoze). If you are iterating up to n regardless of what the user does, you can easily attempt to index an array element that you haven't allocated, or allocate for a string that was not entered.
Putting it altogether, you can do something like:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum { MAXA = 20, MAXS = 40 }; /* max ptrs and str */
int main (void) {
char *arr[MAXA] = {NULL}, str[MAXS] = "";
int i = 0, n = 0, ndx = 0; /* initialize all variables */
printf ("enter the number of strings: ");
/* use assignment suppression %*c to discard the \n */
if (scanf ("%d%*c", &n) != 1) { /* always validate input */
fprintf (stderr, "error: invalid integer input.\n");
return 1;
}
if (n > MAXA) { /* validate the value of n */
fprintf (stderr, "warning: n > %d, using %d as limit.\n",
MAXA, MAXA);
n = MAXA;
}
printf("Enter the strings\n");
while (ndx < n && fgets (str, sizeof str, stdin)) { /* validate input */
size_t len = strlen (str); /* get the length */
if (str[len - 1] == '\n') /* check for '\n' */
str[--len] = 0; /* overwrite with nul-terminator */
if (!(arr[ndx] = malloc (len + 1))) { /* validate allocation */
fprintf (stderr, "error: virtual memory exhausted.\n");
break;
}
strcpy (arr[ndx], str); /* copy to array */
ndx++; /* increment index */
}
printf("\nThe Strings are:\n");
for (i = 0; i < ndx; i++) { /* you have ndx strings not n */
printf (" arr[%2d] : %s\n", i, arr[i]);
free (arr[i]); /* free memory when no longer needed */
}
return 0;
}
Example Use/Output
$ ./bin/nogets
enter the number of strings: 3
Enter the strings
My dog
has a lot
of fleas.
The Strings are:
arr[ 0] : My dog
arr[ 1] : has a lot
arr[ 2] : of fleas.
Now try the same thing and press ctrl + d instead of entering "of fleas." (you are covered).
Lastly, in any code your write that dynamically allocates memory, you have 2 responsibilities regarding any block of memory allocated: (1) always preserve a pointer to the starting address for the block of memory so, (2) it can be freed when it is no longer needed. Get in the habit of tracking the memory you allocate, and free it rather than relying on it being done on exit. That will serve you well as your programs grow more complex.
Look over the code, and make sure you understand what is going on. Let me know if you have any questions.
When you read the number of digits using scanf, it only processed the digit typed in, not the enter you pressed after entering the digit.
Might be worth while to flush the rest of the for input such as
How to clear input buffer in C?
The gets() function shall read bytes from the standard input stream, stdin, into the array pointed to by s, until a <newline> is read or an end-of-file condition is encountered.
So whenever you enter after
enter the number of strings
5
So if you press enter then gets is getting called it's taking new line as a first input.
And if you didn't input enter and press like 5abc then enter then it's going to consider abc as a first string.
You need to clear buffer before gets.
Your correct program is
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void main()
{
char *arr[20],str[40];
int n;
int ch;
printf("enter the number of strings\n");
scanf("%d",&n);
int i;
printf("Enter the strings\n");
//flush the input stream
while ((ch = getchar()) != '\n' && ch != EOF);
for(i=0;i<n;i++)
{
gets(str);
arr[i]=(char *)malloc(sizeof str);
strcpy(arr[i],str);
}
printf("The Strings are:\n");
for(i=0;i<n;i++)
{
printf("%s",arr[i]);
printf("\n");
}
}
I created a program to make a diamond out of *'s. I am looking for a way to check if the type of input is an integer in the C language. If the input is not an integer I would like it to print a message.
This is what I have thus far:
if(scanf("%i", &n) != 1)
printf("must enter integer");
However it does not display the message if it's not an integer. Any help/guidance with this issue would be greatly appreciated!
you can scan your input in a string then check its characters one by one, this example displays result :
0 if it's not digit
1 if it is digit
you can play with it to make your desired output
char n[10];
int i=0;
scanf("%s", n);
while(n[i] != '\0')
{
printf("%d", isdigit(n[i]));
i++;
}
Example:
#include <stdio.h>
#include <string.h>
main()
{
char n[10];
int i=0, flag=1;
scanf("%s", n);
while(n[i] != '\0'){
flag = isdigit(n[i]);
if (!flag) break;
i++;
}
if(flag)
{
i=atoi(n);
printf("%d", i);
}
else
{
printf("it's not integer");
}
}
Use fgets() followed by strtol() or sscanf(..."%d"...).
Robust code needs to handle IO and parsing issues. IMO, these are best done separately.
char buf[50];
fgets(buf, sizeof buf, stdin);
int n;
int end = 0; // use to note end of scanning and catch trailing junk
if (sscanf(buf, "%d %n", &n, &end) != 1 || buf[end] != '\0') {
printf("must enter integer");
}
else {
good_input(n);
}
Note:
strtol() is a better approach, but a few more steps are needed. Example
Additional error checks include testing the result of fgets() and insuring the range of n is reasonable for the code.
Note:
Avoid mixing fgets() and scanf() in the same code.
{ I said scanf() here and not sscanf(). }
Recommend not to use scanf() at all.
strtol
The returned endPtr will point past the last character used in the conversion.
Though this does require using something like fgets to retrieve the input string.
Personal preference is that scanf is for machine generated input not human generated.
Try adding
fflush(stdout);
after the printf. Alternatively, have the printf output a string ending in \n.
Assuming this has been done, the code you've posted actually would display the message if and only if an integer was not entered. You don't need to replace this line with fgets or anything.
If it really seems to be not working as you expect, the problem must be elsewhere. For example, perhaps there are characters left in the buffer from input prior to this line. Please post a complete program that shows the problem, along with the input you gave.
Try:
#include <stdio.h>
#define MAX_LEN 64
int main(void)
{ bool act = true;
char input_string[MAX_LEN]; /* character array to store the string */
int i;
printf("Enter a string:\n");
fgets(input_string,sizeof(input_string),stdin); /* read the string */
/* print the string by printing each element of the array */
for(i=0; input_string[i] != 10; i++) // \0 = 10 = new line feed
{ //the number in each digits can be only 0-9.[ASCII 48-57]
if (input_string[i] >= 48 and input_string[i] <= 57)
continue;
else //must include newline feed
{ act = false; //0
break;
}
}
if (act == false)
printf("\nTHIS IS NOT INTEGER!");
else
printf("\nTHIS IS INTEGER");
return 0;
}
[===>] First we received input using fgets.Then it's will start pulling each digits out from input(starting from digits 0) to check whether it's number 0-9 or not[ASCII 48-57],if it successful looping and non is characters -- boolean variable 'act' still remain true.Thus returning it's integer.