First time ever C programming class. I have to create a C calculator using putchar/getchar. The code below if what I have to far and loops to ask the user for input. The issue I am having is how to account for space/multiple spaces before input, space/multiple spaces between the digits and operand, no spaces between operand and digits, and spaces after input by the user is complete.
Right now the code will work with one space between the digits and operand.
Meaning, 10 + 5 works. However, for example, 10+5 does not and ____5 + 10 (where __ = space), or 10+5______, or 10_________+ 10 do not work.
Any advice or help on how to account for multiple spaces in between the digits and operand and before after any user input is so very greatly appreciated.
Thank you so very much for any and all help with the current code. Really do appreciate your help and time!!
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
int add(int input1, char operand, int input2);
int subtract(int input1, char operand, int input2);
int mod(int input1, char operand, int input2);
int multiply(int input1, char operand, int input2);
int divide(int input1, char operand, int input2);
char cont(void);
int main()
{
int answer = 0;
int ch = 0;
int input1 = 0;
char operand = 0;
int input2 = 0;
int function = 0;
char flag;
do {
input1 = 0, input2 = 0, operand = 0;
printf("\nPlease enter a calculation to be made.\n");
while (((ch = getchar()) != ' ') && (ch != EOF) && (ch != '\n')){
if (ch == '-') {
printf("\nError: no negatives allowed.\n");
}
else if (!isdigit(ch)){
printf("\nError: number not inputted (first number).\n");
}
else {
input1 = (input1 * 10) + (ch - '0');
}
}
while (((ch = getchar()) != ' ') && (ch != EOF) && (ch != '\n')){
switch (ch){
case '+':
operand = '+';
break;
case '-':
operand = '-';
break;
case '%':
operand = '%';
break;
case '*':
operand = '*';
break;
case '/':
operand = '/';
break;
default:
printf("Error: input is not one of the allowed operands.");
break;
}
}
while (((ch = getchar()) != ' ') && (ch != '\n')){
if (ch == '-') {
printf("\nError: no negatives allowed.\n");
}
else if (!isdigit(ch)){
printf("\nError: number not inputted (second number).\n");
}
else {
input2 = (input2 * 10) + (ch - '0');
}
}
printf("%d", input1);
putchar(' ');
printf("%c", operand);
putchar(' ');
printf("%d", input2);
putchar(' ');
putchar('=');
putchar(' ');
if (operand == '+'){
answer = add(input1, operand, input2);
printf("%d", answer);
}
else if (operand == '-'){
answer = subtract(input1, operand, input2);
printf("%d", answer);
}
else if (operand == '%'){
answer = mod(input1, operand, input2);
printf("%d", answer);
}
else if (operand == '*'){
answer = multiply(input1, operand, input2);
printf("%d", answer);
}
else if (operand == '/'){
answer = divide(input1, operand, input2);
printf("%d", answer);
}
flag = cont();
}
while (flag == 'y' || flag == 'Y');
return 0;
}
int add(int input1, char operand, int input2){
return input1 + input2;
}
int subtract(int input1, char operand, int input2){
return input1 - input2;
}
int mod(int input1, char operand, int input2){
return input1 % input2;
}
int multiply(int input1, char operand, int input2){
return input1 * input2;
}
int divide(int input1, char operand, int input2){
return input1 / input2;
}
char cont()
{
char flag;
printf("\nDo you want to process another calculation (y/n)? ");
scanf("%c%*c", &flag);
return flag;
}
Ok! the solution to this problem involves understanding how getchar() works. It also includes a concept of how input from standard input [stdin] works.
So, whenever input to variables is taken using scanf()/getchar() etc. either operations are required in order to alert the compiler that the input for the variable is confirmed. One is new line \n(Pressing Enter) and the other is white-space. They will alert that the input is finalized.
This is explained by input 10 + 5 [Press Enter]. The first space ensures ch has values 10 and thus input1 has a value 10. Then + come through and after the space the operand gets the value of +. Later, Enter is pressed after writing 5. This will save value 5 in input2. The rest of the operations happen perfectly.
In other cases where we have so many spaces ____5 + 10 / 10+5______ / 10_________+ 10 we must look at how the code will follow on such input.
_____5+10 The first space will miss the first while loop because space is an exit condition. The control then goes to the second while loop, where second space will also be an exit condition for the loop. The same happens to the third while loop and it also exits. Thus, the answer will be input1 operand input2 and all these have default values i.e. 0, 0 (which is blank when scaled down to character) and 0 respectively.
10+5_____ Here the first space appear after 5, thus, the getchar() will feed input1 with values 10+5and other two variables don't even get assigned.
This shows why the variables couldn't get assigned the values we expected. The solution for this problem can be solved by extra processing but performing checks on how spaces appear.
Related
I hope you are having a nice day. Thank you for taking the time to read my question.
I am still a beginner in the C language. My professor has asked me to program a scientific calculator. The calculator should be able to read and store user-defined variables and work with them. for example, I should be able to enter a=5 b=9 etc. after that the program should calculate, for instance, a+1= 6, or a+b=14 and show it to the user. Of course, the user decides if the operation is addition, subtraction, division or multiplication.
The user should also be able to enter such input: e.g. c=5+9.
I have started working on the calculator, unfortunately, I have just been able to only allow the user to define one variable at a time and work with it.
For example:
a=7
7+a=14
That's all I could do. I asked my professor for help and he keeps telling me that I have to to teach the program how to separate between what is before the "=" and what's after it.
Thank you in advance for every help or piece of advice you give
This is the code I came up with
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int main() {
char situation;
float operand1, operand2;
char i = 0;
char ch;
char op;
int operand = 0;
int j, digit, number[10] = {};
int j2 = 0;
char str[100] = { 0 };
while (1) {
printf("\n\na) To calculate choose me :)");
printf("\n\nb) If you want to calculate with variables, choose me:");
printf("\n\nc) To Exit choose me :(\n\n");
scanf_s("%c", &situation, 1);
while ((getchar()) != '\n');
switch (situation) {
case 'a':
printf("type in some arithmetic terms : \n");
scanf_s("%f", &operand1);
scanf_s("%c", &op, 1);
scanf_s("%f", &operand2);
while ((getchar()) != '\n');
switch (op) {
case '+':
printf("\n\n%.2f + %.2f = %.2f\n\n", operand1, operand2, operand1 + operand2);
break;
case '-':
printf("\n\n%.2f - %.2f = %.2f\n\n", operand1, operand2, operand1 - operand2);
break;
case '*':
printf("\n\n%.2f * %.2f = %.2f\n\n", operand1, operand2, operand1 * operand2);
break;
case '/':
printf("\n\n%.2f / %.2f = %.2f\n\n", operand1, operand2, operand1 / operand2);
break;
default:
printf("\n\nERROR!\n\n");
}
break;
case 'b':
printf("\n\nTo return to the main menu please enter any capital letter of your choosing\n\n");
printf("\n\nWhen calculating with a variable, please always write the variable on the right side, Thank you. You may start:\n\n");
do {
scanf_s("%s", &str, 99);
for (i = 0; i < 100; i++) {
if (str[i] == '=') {
for (j = 0; j < strlen(str); j++) {
ch = str[j];
if (ch >= '0' && ch <= '9') {
digit = ch - '0';
number[j2] = j2 * 10 + digit;
//printf("%d", number);
}
}
scanf_s("%d", &operand);
scanf_s("%c", &op, 1);
scanf_s("%d", &number[j2]);
while ((getchar()) != '\n');
switch (op) {
case '+':
printf("\n\n%d + %c = %d\n\n", operand, str[0], operand + number[j2]);
break;
case '-':
printf("\n\n % d - % c = % d\n\n", operand, str[0], operand - number[j2]);
break;
case '*':
printf("\n\n % d * % c = % d\n\n", operand, str[0], operand * number[j2]);
break;
case '/':
printf("\n\n % d / % c = % d\n\n", operand, str[0], operand / number[j2]);
break;
default:
printf("\n\nERROR!\n\n");
}
break;
}
}
} while (islower(str[0]));
while ((getchar()) != '\n');
break;
case 'c':
printf("\n\goodbye\n\n");
exit(0);
break;
default:
printf("\n\nThis is not an acceptable input. Please Try again!");
}
}
}
There are multiple problems in your code:
int number[10] = {}; is an invalid initializer in C. You should write:
int j, digit, number[10] = { 0 };
you should use double instead of float
scanf_s("%c", &situation, 1); is not portable: the Microsoft version of this function expects the size argument 1 as an UNSIGNED whereas the Standard C function defined as optional in Annex K specifies that the size argument 1 must be passed as a size_t, hence as (size_t)1. Avoid using this function and read user input as a line with fgets() and use the standard function sscanf() instead and do test the return value to detect and report invalid and/or missing input.
Add these lines before including <stdio.h> at the top of your source file to prevent compiler warnings:
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
scanf_s("%c", &op, 1); does not skip white space, such as spaces and newlines. You should write
scanf(" %c", &op);
while ((getchar()) != '\n'); is risky: this loop will run forever if the end of file occurs before a newline can be read.
instead of j < strlen(str), which may rescan the string at every iteration, you should write:
for (j = 0; str[j] != '\0'; j++)
i is used as an index, it should have type int or size_t, not char.
the format string in printf("\n\n % d - % c = % d\n\n", ...); is incorrect: the space between the % and the c is not supported. You probably meant to write this anyway:
printf("\n\n%d - %c = %d\n\n", operand, str[0], operand - number[j2]);
printf("\n\goodbye\n\n"); is incorrect: \g is an invalid escape sequence. You should write:
printf("\n\nGoodbye\n\n");
Here is a modified version using functions to parse the line and handle variable assignment separately from evaluating expressions:
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <ctype.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* 26 global variables */
double variables['z' - 'a' + 1];
/* the function skip_spaces() updates `*pos`, skipping any white
* space in `str` at the corresponding index
*/
void skip_spaces(const char *str, int *pos) {
while (isspace((unsigned char)str[*pos]))
*pos += 1;
}
/* the function trim_spaces() updates `*pos`, skipping any white
* space in `str` at the corresponding index. In addition, it
* removes trailing white space from the string, ie: newlines,
* spaces, TABs and other white space characters
*/
void trim_spaces(char *str, int *pos) {
int len = strlen(str);
while (len > *pos && isspace((unsigned char)str[len - 1]))
str[--len] = '\0';
skip_spaces(str, pos);
}
/* the function parse_operand() reads the next operand from `str`
* at index `*pos`. It recognises floating point numbers and
* variable names, which are replaced with their value. The value is
* stored into `*value`. `*pos` is updated past the operand and any
* white space after it.
*/
int parse_operand(char *str, int *pos, double *value) {
char *endp;
skip_spaces(str, pos);
char ch = str[*pos];
if (ch >= 'a' && ch <= 'z') {
*value = variables[ch - 'a'];
*pos += 1;
skip_spaces(str, pos);
return 1; // variable
}
*value = strtod(str + *pos, &endp);
if (endp > str + *pos) {
*pos = endp - str;
skip_spaces(str, pos);
return 2; // number
}
return 0;
}
/* parse_expression: parse an expression with basic operators,
* no precedence: the function expects at least one operand and
* keeps parsing and evaluating as long as there is a supported
* operator that follows. The result is stored into `*result`.
*/
int parse_expression(char *str, int *pos, double *result) {
double operand2;
char op;
if (!parse_operand(str, pos, result)) {
printf("missing operand: %s\n", str + *pos);
return 0;
}
while ((op = str[*pos]) == '+' || op == '-' || op == '*' || op == '/' || op == '%') {
*pos += 1;
if (!parse_operand(str, pos, &operand2)) {
printf("missing operand: %s\n", str + *pos);
return 0;
}
switch (op) {
case '+':
*result += operand2;
break;
case '-':
*result -= operand2;
break;
case '*':
*result *= operand2;
break;
case '/':
*result /= operand2;
break;
case '%':
*result = fmod(*result, operand2);
break;
}
}
return 1;
}
int main() {
char str[100];
printf("type some expressions:\n");
while (fgets(str, sizeof str, stdin)) {
double result, result2;
int pos = 0;
/* strip trailing whitespace, skip initial whitespace */
trim_spaces(str, &pos);
if (!str[pos]) {
/* stop on empty line */
break;
}
/* test for a variable assignment */
if (str[pos] >= 'a' && str[pos] <= 'z' && str[pos + 1] == '=') {
/* variable assignment */
int v = str[pos] - 'a';
pos += 2;
if (parse_expression(str, &pos, &result) && !str[pos]) {
variables[v] = result;
printf("%s -> %.2f\n", str, result);
} else {
printf("invalid expression: %s\n", str);
}
} else {
/* other expression */
if (parse_expression(str, &pos, &result)) {
skip_spaces(str, &pos);
if (str[pos] == '\0') {
printf("%s -> %.2f\n", str, result);
} else
if (str[pos] == '=') {
/* comparison of expressions */
pos += 1;
if (parse_expression(str, &pos, &result2) && !str[pos]) {
if (result == result2) {
printf("%s -> true (%.2f == %.2f)\n", str, result, result2);
} else {
printf("%s -> false (%f != %f, delta: %e)\n",
str, result, result2, result2 - result);
}
} else {
printf("invalid expression: %s\n", str);
}
} else {
printf("invalid syntax: %s\n", str);
}
}
}
}
return 0;
}
Output:
b=2/3
b=2/3 -> 0.67
2/3=b
2/3=b -> true (0.67 == 0.67)
20/3=10*b
20/3=10*b -> false (6.666667 != 6.666667, delta: -8.881784e-16)
This is the Programming Project 7.12 of the C Programming - A Modern Approach. The program is expected to evaluate an expression (for example 1+2.5*3) and return its result (10.5 in this case, note that the expression is evaluated from left to right, and no operator takes precedence over any other operator).
This is what I've tried (the expression is 1 + 2.5 *3, for example): store 1 in a, + in ch, and 2.5 in b. Then let result = a, compute the "new" result by either adding, subtracting, dividing or multiplying with b. Then continue reading the expression, storing * in ch, and 3 in b. Run the while loop again until the scanf detects a new-line character. I wonder what is wrong with my method, or my code.
#include <stdio.h>
int main(void)
{
float a, b, result;
char ch;
printf("Enter an expression: ");
scanf("%f%c%f", &a, &ch, &b);
result = a;
while (ch != '\n') {
if (ch == '+')
result += b;
else if (ch == '-')
result -= b;
else if (ch == '*')
result *= b;
else if (ch == '/') {
result /= b; }
scanf("%c", &ch);
scanf("%f", &b);
}
printf("Value of expression: %.2f", result);
return 0;
}
It doesn't return anything :(
Even after you press enter after putting complete expression.
scanf("%c", &ch);
scanf("%f", &b);
Will still wait to input float because of order of scanf.
Just break immediately once you press enter as below.
while (ch != '\n') {
if (ch == '+')
result += b;
else if (ch == '-')
result -= b;
else if (ch == '*')
result *= b;
else if (ch == '/') {
result /= b; }
scanf("%c", &ch);
if (ch == '\n') break;
scanf("%f", &b);
}
I would suggest you to use fgets to read the complete expression at
once and process the expression afterwards also your current code is very naive wouldn't even work for complex expression which includes (, ) etc, you may want to use LIFO data structure by processing the read expression in reverse order.
I have been assigned with a school task.
In this task I have to create a program in C language that reads as an input from the user a mathematical expression and returns the result of it. For example the input must be something like 30 + 400 and the output must be in this case the result of the addition of 30 and 400 which is 430.The program must calculate apart from the addition and the other mathematical operations(subtraction,multiplication,division).Each expression must be read in one line and also I am not allowed to use arrays or any other complex data structure in my code.
I have tried some methods to solve this task but i can't understand how to separate the numbers from the operators so the expression can be calculated.
Here is the i have written:
#include <stdio.h>
int main(){
int ch,result;
int plus;
int minus;
int mult;
int div;
while((ch = getchar())!= EOF){
plus = 0;
minus = 0;
mult = 0;
div = 0;
if (ch != '\n'){
if (ch >= '0' && ch <='9'){ //Checks if the character is a number
result += ch;
}else if(ch== '+'){//Checks if the character is an operator
plus =1;
}else if(ch== '-'){
minus = 1;
}else if(ch == '*'){
mult = 1;
}else if(ch== '/'){
div = 1;
}
}
printf("%d\n",result);
}
}
Any suggestions or ideas would be very helpful.
P.S. I am sorry for my English and if I dint use the appropriate terms to describe this problem .
getchar returns the ASCII value you need to convert it into decimal.
You can use two integers to store the inputted numbers and act on it.
Example:
int num1 = 0,num2 = 0;
char op;
int state = 0;
while((ch = getchar())!= EOF){
if (ch != '\n'){
if (ch >= '0' && ch <='9'){ //Checks if the character is a number
if (state == 0)
num1 = num1*10 + ch- '0'; // Convert ASCII to decimal
else
num2 = num2*10 + ch- '0'; // Convert ASCII to decimal
}else {
/* Operator detected now start reading in second number*/
op = ch;
state = 1;
}
}
else {
int result =0;
switch(op)
{
case '+':
result = num1 + num2;
break;
case '-':
result = num1 - num2;
break;
case '*':
result = num1 * num2;
break;
case '/':
result = num1 / num2;
break;
}
printf("%d\n",result);
num1 = 0;
num2 = 0;
state = 0;
}
I'm writing a simple calculation program, however the only string handling functions I can use are getchar and putchar. Right now I'm just trying to assign the numbers from input to variables, but when I print the variable it's some random number. For example, I entered 3 into the console and the output was 505110. Any help would be appreciated. Thank you.
#include <stdio.h>
#include "math.h"
int addFunction( int, int);
int subtractFunction(int, int);
int multiplyFunction(int, int);
int modulusFunction(int, int);
float divideFunction(float, float);
int main(int argc, const char * argv[])
{
int iochar = 0;
char num1 = 0, num2 = 0, continuePrompt, operator = 0;
do {
iochar = getchar();
getchar();
if ((iochar >= 0) && (iochar <= 20000)) {
num1 = iochar;
}
if ((iochar == '+') || (iochar == '-') || (iochar == '*') || (iochar == '/') || ( iochar == '%')) {
operator = iochar;
}
if ((num1 >= 0) || ((iochar >= 0) && (iochar <= 20000))){
num2 = iochar;
}
switch (operator) {
case '+':
iochar = addFunction(num1, num2);
break;
case '-':
iochar = subtractFunction(num1, num2);
break;
case '*':
iochar = multiplyFunction(num1, num2);
break;
case '%':
iochar = modulusFunction(num1, num2);
break;
case '/':
iochar = divideFunction(num1, num2);
break;
}
putchar(iochar);
printf("Would you like to make another calulation? (y or n)");
scanf("%c", &continuePrompt);
} while (continuePrompt != 'n');
return 0;
}
int addFunction(int x, int y){
return x + y;
}
int subtractFunction(int x, int y){
return x - y;
}
int multiplyFunction(int x, int y){
return x * y;
}
int modulusFunction(int x, int y){
return x % y;
}
float divideFunction(float x, float y){
return x / y;
}
The code is working exactly correct. When you enter a "3" in ASCII that's really the hex value 0x33, you're printing the value in dec (%d) thus you'll see a 51 on the output.
Now you're failing to consume the newline character that was entered, so getchar() is skipping the input on the second pass and is assuming you passed in a '\n' ASCII, which is hex 0xa and thus 10 is printed next.
You don't print any newlines or spaces so on the output you'll see:
3 (I entered that)
5110 (the output from '3''\n')
To fix the main problem, consume the new line character:
int main(int argc, const char * argv[]) {
int iochar, num1, num2;
char continuePrompt = 0, operator;
do {
iochar = getchar(); // Get input from user
getchar(); //Consume new line character
When you're printing the values, you're going to get ASCII values back, so if you want the dec, you're good, if you want it in character:
printf("%c", num1);
if you wanted it in hex (0x??)
printf("%#x", num1);
Also I'd print a new line or spaces or something more helpful then just a string of output to help find problems like this.
Finally this condtion:
while (continuePrompt != 'no');
Is wrong. That can't happen, check against 'n', you can't have 'no' in a single character.
Use %c instead of %d
i.e.
printf("%c", num1);
Also,you should initialize the variables.
i.e
int iochar=0, num1=0, num2=0;
char continuePrompt = 0, operator=0;
Since you're only allowed to use putchar and getchar, I assume that you're not allowed to use printf in order to present the result. In order to use an actual number with putchar you'll have to take each digit and transform it to the correct ASCII value.
Fortunately this is very simple, since
digitRepresentationASCIIValue == singleDigitValue + '0';
However, this will only work on a single digit. So you'll have to get the length of a number and use putchar for each digit. This is very simple:
void putNumber(int num){
int order = 1; // even zero has at least one digit
int tmp = num; // even zero has at least one digit
while(tmp /= 10)
order *= 10; // count digits
if(num < 0)
putchar('-'); // sign
while(order > 0){
// put a single digit, see above how to calculate the ASCII value
putchar('0' + ( ( num / order ) % 10));
order /= 10;
}
}
In order to actually read values you would have to do the exact opposite: check whether the character provided by getchar is a digit, and modify your current number:
int num[2] = {0,0};
int currentNum = 0;
int iochar = getchar();
while(!isNewline(iochar) && iochar != EOF){
if(isDigit(iochar)){
num[currentNum] = num[currentNum] * 10 + iochar - '0';
}
else if(isOperator(iochar)){
if(currentNum == 1)
num[0] = operate(num[0],num[1],operator);
else
currentNum = 1;
operator = iochar;
num[1] = 0;
}
iochar = getchar();
}
isDigit, isNewline and isOperand are left for exercise, all three are very simple but they will give you a better idea of ASCII values. operate contains your switch statement.
Note that I used int num[2] = {0,0};. This enables (in addition to currentNum) to write something like
3 + 3 + 3 / 9
Note that all operators are evaluated from left to right, as such the result of the example above will be 1 and not 6.3333333.
Exercises:
Don't publish your solution here, but do them for yourself as they should help you to improve your ASCII/char skills. For some exercises an ASCII table might be helpful.
Explain why the digit representation is so simple. Hint: Where and in which order are numbers defined in ASCII? What happens if you increase the value of a char?
Implement the missing isDigit, isNewline and isOperand.
The code for the input isn't commented, especially this line is missing a comment:
num[currentNum] = num[currentNum] * 10 + iochar - '0';
What exactly happens there? If num[currentNum] is too complicated for you at the moment just use num1 and print the value before you read the second one. Hint: Have a look at exercise #1.
Even if the operators would be evaluated in the right order (multiplication before addition), the result wouldn't be 6.333333 but 6. Why is that? What would you have to change in your current program?
First, you need to cast the input from "getchar", since it is an ascii input.
iochar = atoi(getchar());
then you can compare it against an integer value.
To start with, return value of getchar is char, promoted to int. So, please use an char variable to store it.
Secondly, to convert the input char to int, use something like:
int num1 = iochar - '0';
I've searched in and out of these forums but am still having trouble. My understanding of C is still very basic. I'm creating a small program that takes 3 numerical values entered by the user and then calculates the highest. I nailed that.
I now want to ensure that the user enters only integer values. I managed to get the prog to keep prompting the user to re-enter the value until it is within the specified numerical range (for example, any number between 1 and 1000 inclusive, piece of cake) but that's not good enough. I used 3 while loops to test each value, but this only works as long as the input is of type integer.
The trick is I cant use built in functions. It needs to be manual (sorry, poor choice of words) I tried to use char variables and x = getchar(); to get the ASCII value and test it in a condition but I can't get it working in a loop. (while/ do-while)
I also tried using a "for loop" and array variables but once again am struggling to get it to keep prompting the user.
I've also tried to test the value returned by scanf to see if its integer but my knowledge level of correct C syntax is level: noob. Either my loops don't loop or they loop infinitely.
Here is some sample code:
int x, y, z =0;
printf("Enter the first number:\n");
scanf("d", &x);
while (condition) /* Here is where I need to determine that the entered val is false */
{
printf("Wrong input. Re-enter a valid value.\n");
x =0;
scanf("%d", &x); /*user re-prompted */
}
I'm getting the idea that I'll have to use ASCII and a loop, but I just can't get to it. Also, the values entered get sent to a function for comparing and are then returned.
Could someone give me some advice and a few tips please?
Much thanks
You would have to use something like fgets, and strtol:
long someValue;
char *bufEnd = NULL;
char buf[128]; // max line size
do {
printf("enter a value: ");
fgets(buf, 128, stdin);
someValue = strtol(buf, &bufEnd, 10); // base 10
} while (bufEnd == buf || *bufEnd != '\n');
printf("got value: %li", someValue);
What we are doing here is we are tapping into strtol's capability to tell us where it stopped parsing, by passing in bufEnd.
Then, we are making sure that bufEnd doesn't point to the beginning of buf (in which case, it didn't start with a number), and also checking to make sure that bufEnd points to \n, or the end of the line (making sure that the user didn't enter something like 123abc, which strtol would interpret as 123). You may wish to trim buf of whitespace characters first, however.
You're absolutely on the right track with "scanf()". Just check the return value. If you don't get the expected #/values, then you got invalid input:
char found = FALSE;
int ival;
double x;
while (!found)
{
printf("Please enter a valid integer: ");
if (scanf("%d", &ival) !=1) {
printf ("Invalid! Please re-enter!\n");
continue;
}
printf("Please enter a valid floating point number: ");
if (scanf("%lf", &x) !=1) {
printf ("Invalid! Please re-enter!\n");
continue;
}
found = TRUE;
}
Here's my solution. It safe against buffer overflow and straightforward .
#include <stdio.h>
#define LEN 10
int main() {
int a;
char str[LEN];
fgets( str, LEN, stdin );
while ( !sscanf( str, "%d", &a ) )
fgets( str, 10, stdin );
printf("Num is : %d\n", a);
return 0;
}
#include <stdio.h>
#include <limits.h>
#include <ctype.h>
int getInteger(int* err){
int ch;
int n;//int32
int takeNum, sign;
long long int wk;//long long int as int64
wk=0LL;
*err = 0;
takeNum = 0;//flag
sign = 1;//minus:-1, other:1
/* //skip space character
while(EOF!=(ch=getchar()) && (ch == ' ' || ch == '\t' || ch == '\n'));
ungetc(ch, stdin);
*/
while(EOF!=(ch=getchar())){
if(ch == '-'){
if(takeNum != 0){//in input number
*err = 1;
break;
}
if(sign == -1){//already sign
*err = 2;
break;
}
sign = -1;
continue;
}
if(ch >= '0' && ch <= '9'){//isdigit(ch) in ctype.h
if(takeNum == 0)
takeNum = 1;
wk = wk * 10 + (ch - '0')*sign;
if(INT_MAX < wk || INT_MIN > wk){//overflow
*err = 3;
break;
}
continue;
}
if(ch != '\n'){//input other [-0-9]
*err = 4;
}
break;
}
if(takeNum == 0){//not input number
*err = 5;
} else {
n=wk;
}
while(ch != '\n' && EOF!=(ch=getchar()));//skip to newline
return n;
}
int getValue(const char* redoprompt, int low, int high){
int num, err=0;
while(1){
num = getInteger(&err);
if(err || low > num || high < num)
printf("%s", redoprompt);
else
break;
}
return num;
}
#define max(x,y) ((x)>(y))? (x) : (y)
int main(){
const char *error_message = "Wrong input. Re-enter a valid value.\n";
int x, y, z, max;
x = getValue(error_message, 1, 1000);
y = getValue(error_message, 1, 1000);
z = getValue(error_message, 1, 1000);
max = max(max(x,y), z);
printf("max:%d\n", max);
return 0;
}