Can someone tell me what's wrong with this:
int main()
{
char a[100];
int i = 0;
printf("Enter a number: ");
scanf("%c", &a[i]);
printf("The number you've entered is: %d", a[i] - '0');
}
Brief summary: I am trying to convert a number stored in a char array to its int equivalent. I know in C#, you use the intparse command, but because there isn't such one in C, I do not know what to do. When I input a two digit number, it is only outputting the first digit, of the input char.
strtol sample
#include <stdio.h>
#include <stdlib.h>
int main(){
char str[16], *endp;
int value;
printf("Enter a number: ");
fgets(str, sizeof(str), stdin);
value = strtol(str, &endp, 0);
if(*endp == '\n' || *endp == '\0'){
printf("The number you've entered is: %d\n", value);
} else {
printf("invalid number format!");
}
return 0;
}
If you mean to print ASCII value of char the no need to do a[i] - '0'.
Try this
printf("The number you've entered is: %d", a[i]);
If you are talking about string then first change your scanf statement to
scanf("%s", a);
or better to use fgets library function instead of scanf;
fgets(a, sizeof(a), stdin);
and then use strtol function.
OP method of scanf("%c", &a[i]); only handles a 1 character input.
To read the entire line, suggest using fgets() to read.
The convert to a long using strtol().
Watch for potential errors.
#include <stdio.h>
#include <stdlib.h>
int main(){
// use long to match strtol()
long i;
// size buffer to handle any legitimate input
char a[sizeof i * 3 + 3];
char *endptr;
printf("Enter a number: ");
if (fgets(a, sizeof a, stdin) == NULL) {
// If you would like to handle uncommon events ...
puts("EOForIOError");
return 1;
}
errno = 0;
i = strtol(str, &endptr, 10);
if(*endptr != '\n' /* text after number */ ||
endp == a /* no text */ ||
errno /* overflow */) {
printf("Invalid number %s", a);
}
else {
printf("The number you've entered is: %ld\n", i);
}
return 0;
}
Try
char myarray[5] = {'-', '4', '9', '3', '\0'};
int i;
sscanf(myarray, "%d", &i); // i will be -493
Edit (borrowed from [1]):
There is a wonderful question here on the site that explains and compares 3 different ways to do it - atoi, sscanf and strtol. Also, there is a nice more-detailed insight into sscanf (actually, the whole family of *scanf functions).
#include<stdio.h>
#include<stdlib.h>
int main()
{
char a[100];
int final=0,integer;
int i;
printf("Enter a number: ");
gets(a);
for(i=0;a[i]>='0'&&a[i]<='9';++i)
{
integer=a[i] - '0';
final=final*10+integer;
}
enter code here
printf("The integer is %d ", final);
}
Related
This might be a rookie question, but I need to make sure that the input given by the user is of data type char [%c] or a string [%s].
If it were an integer, I would just do something like this:
int data, x;
do {
printf("Please enter a number: ");
x = scanf(" %d", &data);
getchar();
} while(x!=1);
So I was wondering if there's a similar way to do this, if the input is supposed to be a string or a character. Thanks, Any help would be appreciated!
Avoid to use %c in scanf() because some unexpected character like \r\n will be input.
You can use a char[2] to receive a single character. An \0 will be filled after your string to represent the end of string, so the length of array must be bigger than 1.
An example:
#include <stdio.h>
int main()
{
char data[2];
scanf("%1s", data);
if (data[0] >= 'a' && data[0] <= 'z') // custom your constraint here
{
// legal
printf("legal: %s", data);
}
else
{
// illegal
printf("illegal: %s", data);
}
return 0;
}
While I input b, the data will be "b\0".
part of the answer is if you just want to read only alphabet you can use below.
#include <stdio.h>
#include <ctype.h>
int main()
{
char ch;
do {
printf("enter a char:");
scanf(" %c",&ch);
}while(!isalpha(ch));
printf("%c",ch);
return 0;
}
Update 1:
Just for the completeness and for the FUN part of the programing, have added code here.
This works well (not tested robustly, you can do if you need to) for the single char input or for a string of length 9.
Remember to type the EOF after input is entered in case length of input is < 9.
and read EOF behavior on same line and new line.
#include <stdio.h>
#include <ctype.h>
#define LEN 10
int main()
{
char ch;
char str[LEN] = {0};
int i = 0;
int ret;
printf("enter a char or string(len = 9) and press EOF if len < 9\n");
do {
if(1== (ret = scanf(" %c",&ch)))
{
if(isalpha(ch))
str[i++] = ch;
}
else
printf("scanf:Error (%d)\n", ret);
}while(ret != EOF && ( !isalpha(ch) || i < LEN-1));
str[i] = '\0';
printf("str is %s\n",str);
return 0;
}
The following program is from a homework assignment.
I need to write a program where it:
asks a Seed and a Range,
generates and displays a sequence of random numbers based on the seed and range input,
converts the above into a sequence of "A"s, "B"s, or "C"s depending on the generated sequence: turn 1 into A, 2 into B, 3 into C;
asks whether to continue; if user puts "n", stop; else starts over again.
#include <stdlib.h>
#include <stdio.h>
int main() {
int seed;
int Range;
char ch;
while (ch != "n") {
printf("Enter a seed: ");
scanf("%d", &seed);
printf("Enter a Range: ");
scanf("%d", &Range);
srand(seed);
for (int i = 0; i < 10; i++) {
scheduler(rand() % Range + 1);
}
printf("Continue?\n");
scanf("%c", &ch);
}
return 0;
}
I put two arbitrary numbers and it generates a random sequence as expected. But then it just prints "Continue?" without taking an input from me and then asks me to enter a seed. What's wrong with my code? What's the proper way to do this?
Change this:
scanf("%c", &ch);
to this:
scanf(" %c", &ch);
in order to eat the leftover character (the newline character you pressed when you entered the numbers (seed andRange`) before).
I had wrote more about that issue here.
Moreover, your code invokes Undefined Behavior (UB), since you check ch before it gets initialized here:
char ch;
while (ch != "n") {
...
}
Use a do-while loop structure instead, like this:
do {
...
} while (ch != 'n');
Furthermore, you should get a compiler warning like this:
warning: comparison between pointer and integer
while (ch != "n") {
^~
warning: comparison with string literal results in unspecified behavior [-Waddress]
Change "n" to 'n', since ch is of type char, not char*.
Putting everything together, your code should like this:
#include <stdlib.h>
#include <stdio.h>
int main() {
int seed;
int Range;
char ch;
do {
printf("Enter a seed: ");
scanf("%d", &seed);
printf("Enter a Range: ");
scanf("%d", &Range);
srand(seed);
for (int i = 0; i < 10; i++) {
scheduler(rand() % Range + 1);
}
printf("Continue?\n");
scanf(" %c", &ch);
} while (ch != 'n');
return 0;
}
#include <stdlib.h>
#include <stdio.h>
int main()
{
int seed;
int Range;
char ch = '\0'; /* initialize ch to something other than 'n' */
/* if ch not initialized, u take your chances on being able to enter while loop */
while (ch != 'n') / single quote characters, double quote for strings imply null character \0 after last character in string */
{
printf("Enter a seed: ");
fflush( stdout ); /* because of no \n in printf */
scanf("%d", &seed);
printf("Enter a Range: ");
fflush( stdout ); /* because of no \n in printf */
scanf("%d", &Range);
srand(seed);
for (int i = 0; i < 10; i++)
{
scheduler(rand() % Range + 1);
}
printf("Continue?\n"); /* bet u this works, because of \n */
scanf("%c", &ch);
}
return 0;
}
#include <stdio.h>
int main(){
float x,y;
printf("Enter 2 numbers: \n");
scanf_s("%f %f", &x, &y);
if (getchar() == '\n')
{
printf("Division: %f\n", x / y);
printf("Product: %f\n", x * y);
printf("Sum: %f\n", x + y);
printf("Difference: %f\n", x - y);
}
else
{
printf("no Float-Value!");
}
getchar();
return 0;
}
we need to get a loop in so if we enter the wrong format the program should ask again to enter two numbers
The best way of checking the validity of the input is to check the return value of scanf_s which tells you the number of variables that were successfully set. In your case, if it's 2 then all is well; otherwise you need to repeat.
In other words
do {
int c;
while ((c = getchar()) != '\n' && c != EOF); // clear the input stream
printf("Enter 2 numbers: \n");
} while (scanf_s("%f %f", &x, &y) != 2);
is an appropriate control structure, rather than if (getchar() == '\n'), which you should drop.
What I don't like about using scanf family of functions is that it will go berserk and crash your program when you input something wrong. For example, if you have scanf("%f", &a), try inputing stack overflow. It goes nuts!
So, as I said in the comments, I think you should build your own validating function, and get user input as just a string using fgets.
Here is a simple code that will get you started in it. This is very ugly code and you should refactor it.
#include <stdio.h> /* printf, fgets */
#include <ctype.h> /* isdigit, isspace */
#include <string.h> /* strlen */
int is_valid_float(char *s, int len)
{
int i;
for(i = 0; i < len; i++) {
/* floats may have a decimal point */
if(s[i] == '.') continue;
/* spaces should be ignored, since they separete the nubmers */
if(isspace(s[i])) continue;
/* is there's anything besides a number, we abort */
if(!isdigit(s[i])) return 0;
}
/* if we got here, then the input contains two valid floats.
*
* Does it? Test it!
*/
return 1;
}
int main(void)
{
float a, b;
char buf[100];
int len;
do {
fprintf(stderr, "Enter A and B: ");
fgets(buf, sizeof buf, stdin);
/* fgets will store a newline at the end of the string, we
* just overwrite it with a null terminator
*
* Thanks to #chux for the strcspn() suggestion.
*/
buf[strcspn(buf, "\n")] = 0;
} while(!is_valid_float(buf, len));
/* now, after we know the string is valid and won't cause scanf to go
* berserk, we can use it in our validated string.
*
* Here is where you should really take a moment and look at the
* validation function and improve it. Not valid strings will cause
* your program to go nuts.
*/
sscanf(buf, "%f %f", &a, &b);
/* Did it scan the numbers correctly? */
printf("A: %f\n", a);
printf("B: %f\n", b);
return 0;
}
everyone!
I hope someone can help me figure out something in C language.
This is my first seriously homework in IT, I have no experience and I'm learning in e-studies, so teacher help isn't very available.
I need to develop console application in C language. User need to input 10 integer numbers, if insert number isn't integer, need to output error and again re-enter new number until all 10 integer numbers will be inserted.
Everything works in case if I say that these 10 numbers can't be 0 (I make this to be sure that my if-else statement working), but won't work when I want that every input number will be check if it is integer or not.
How can I do it right.
Please help
so far my code look like this:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i;
float f;
int numbers[10];
for (i = 0; i < 10; i++)
{
scanf ("%d", &numbers[i]);
if (numbers[i] != 0)
{
scanf ("*%d", &numbers[i]);
}
else
{
printf ("\nError!Entered number is't integer \n");
printf ("\nPlease insert number again \n");
scanf("%*d", &numbers[i]);
}
}
}
#include <stdio.h>
int main(void) {
int i = 0;
int val;
char ch;
int numbers[10];
while(i < 10) {
val = scanf("%d", numbers + i); // read the integer into a[i]
if(val != 1) {
while((ch = getchar()) != '\n') // discard the invalid input
; // the null statement
printf("Error! Entered number is not an integer.\n");
printf("Please enter an integer again.\n");
val = scanf("%d", numbers + i);
continue;
}
++i;
}
// process the numbers array
return 0;
}
I write this line again
val = scanf("%d", numbers + i);
Now it works how I need. Great - thanks a lot
There are several techniques you might use:
Read the number as a string and reject if it contains characters not suitable for an integer. The use sscanf() to convert the string to integer.
Read the number as a float and reject if it is out of integer range or it has a non-integer value.
Read the input character by character and build up an integer value. If invalid characters appear, reject the value.
scanf returns the number of input items successfully matched and assigned. You can check this value for 1 for each call of scanf. If the value is 0, then you should discard the input to clear the stdin buffer and read input again.
#include <stdio.h>
#include <ctype.h>
int main(void) {
int i = 0;
int val;
char ch;
int numbers[10];
while(i < 10) {
// read an integer and the first non-numeric character
val = scanf("%d%c", numbers + i, &ch);
// if the number of items assigned by scanf is not 2 or if
// the first non-numeric character is not a whitespace, then
// discard the input and call read input again.
// for example input of type 32ws are completely discarded
if(val != 2 || !isspace(ch)) {
while((ch = getchar()) != '\n') // discard the invalid input
; // the null statement
printf("Error! Entered number is not an integer.\n");
printf("Please enter an integer again.\n");
continue;
}
++i;
}
// process the numbers array
return 0;
}
Although I am not entirely clear on the details of your question, here is an outline of code similar to what you want:
int main(void)
{
int i;
int numbers[10];
int sum = 0;
for(i=0; i<10; ++i)
{
printf("Enter #%d:\n", i+1);
scanf("%d", numbers+i);
if (numbers[i] % 2 == 0) // Then Number is even
{
sum += numbers[i];
}
}
printf("The sum of only the even numbers is %d\n", sum);
getch();
return 0;
}
To read an int, suggest fgets() then sscanf() or strtol()
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int i;
int numbers[10];
for (i = 0; i < 10; ) {
char buffer[50];
if (fgets(buffer, sizeof buffer, stdin) == NULL) break;
int n; // number of `char` parsed
if (sscanf(buffer, "%d %n", &numbers[i], &n) != 1 || buffer[n] != '\0') {
printf("Error! Entered number is not an integer.\n");
printf("Please enter an integer again.\n");
continue;
}
i++;
}
return 0;
}
The strtol() approach. This detects overflow issues:
if (fgets(buffer, sizeof buffer, stdin) == NULL) break;
char *endptr;
errno = 0;
long num = strtol(buffer, &endptr, 10);
if (errno || num < INT_MIN || num > INT_MAX) Handle_RangeError();
if (buffer == endptr || *endptr != '\n') Handle_SyntaxError();
numbers[i] = (int) num;
Recommend making a int GetInt(const char *prompt) function that can be used repeatedly.
User input is evil. Do not trust it until well vetted.
I'm writing a program in C that is suppose to ask the user for a number.
The number has to be greater than zero and cannot have letters before or after the number. (ie: 400 is valid but abc or 400abc or abc400 is not). I can make my program invalidate everything besides 400abc. How would I make it invalidate an input if it starts valid then turns invalid? (I'm about 2 months into an intro to c class so my knowledge is very limited.)
#include<stdio.h>
int check(void);
void clear_input(void);
main()
{
int num;
printf("Please enter a number: ");
num = check();
printf("In Main %d\n", num);
}
int check(void){
int c;
scanf("%d", &c);
while (c < 0){
clear_input();
printf("Invalid, please enter an integer: ");
scanf("%d", &c);
}
return c;
}
void clear_input(void){
char junk;
do{
scanf("%c", &junk);
}while (junk != '\n');
}
You can also check whether ascii value of each char scanned from user input should lie in range 48-57, It will only then be integer value.
strtol can be used to do it, but it takes some extra work.
After running this code:
char *endptr;
int n = strtol(num_text, &endptr, 10);
n will contain the number. But you still have to check that:
1. *endptr=='\0' - this means strtol didn't stop in the middle. In 400abc, endptr will point to abc. You may want to allow trailing whitespace (in this case, check that endptr points to an all-whitespace string.
2. num_text isn't empty. In this case, strtol will return 0, but an empty string isn't a valid number.
Read the input as a line, using fgets.
Check if all characters are numeric.
If not, it's invalid. If yes, use sscanf to get the line into an int.
Check if the int is in the range; you're done.
Scanf with %d will treat the "400abc" as 400, all the trailing characters would be ignored, so there is nothing to worry about.
If you definitely want to treat "400abc" as an invalid input, then maybe you shouldn't use %d in scanf, use %s instead?
One way is to read the whole line as a string and check by yourself if it contains any non-digits.
The other way is reading the integer and then looking into the input using fgetc() to see if the next character after the detected input is valid. Or you could even use the same scanf() for this:
char delim;
if(scanf("%d%c", &c, &delim) == 2 && !isspace(delim))
// the input is invalid
You can read the number in a character array and validate it by checking if all the characters lie in the ascii range 48 to 57 ( '0' to '9' ) .If so your no. is valid otherwise you can safely regard it as invalid input.Here the the demonstration :
#include<stdio.h>
#include<string.h>
int conv( char * word )
{
int ans=0;
int res=0;
for(int i=0;i<strlen(word);i++)
if(word[i]>='0' && word[i]<='9')
ans=(ans*10) + (word[i] - '0');
else
res=-999;
if(res==-999)
return res;
else
return ans;
}
int main()
{
char a[10];
gets(a);
int b=conv(a);
if(b==-999)
printf("Invalid Entry.\n");
else
printf("Success.No is %d.\n",b);
return 0;
}
You can adjust for negatives as well by checking the first character in the word array to be '-' and adjusting the sign accordingly.
This is C99, so compile with -std=c99
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdbool.h>
bool getNum(int *n) {
char c, s[10];
if (!scanf("%9s", s))
return false;
for (int i=0; c=s[i]; i++)
if (!isdigit(c))
return false;
*n = atoi(s);
return true;
}
int main() {
int n;
if (getNum(&n))
printf("you entered %d\n", n);
else
printf("you did not enter a number\n");
}
The following is your check function rewritten to fix your problem, so try this:
int check(void){
int n;
char c;
while (EOF==scanf("%d%c", &n,&c) || n < 0 || !isspace(c)){
clear_input();
printf("Invalid, please enter an integer: ");
}
return n;
}