c scanf integer with consective input but only need to read one - c

I got input like 12345679890 but I just want to read 1 integer at a time, that is read 1 then 2 then 3 ... and do some operations next. However when I use scanf, it read all the numbers i.e. 1234567890. Can anyone help? Thank you!!
This is the code that I have
#include <stdio.h>
int main() {
int input;
scanf("%x",&input);
while (scanf("%x",&input)==1){}
}

12345679890 is an integer, what you want to do is read one digit at a time. To do this, you would use the format string %1u rather than %x.
For a start, %x specifies a hexadecimal item, meaning it will accept a through f as well, and %d would allow for a leading sign which you probably don't want.
In addition, you appear to consume (and throw away) the first digit before you enter the loop, so you would be better off with something like:
#include <stdio.h>
int main(void) {
unsigned int digit;
while (scanf("%1d", &digit) == 1) {
//doSomethingWith(digit);
}
return 0;
}

Related

Can a number be both a string, and an integer simultaneously?

I'm trying to understand a line of code in a problem set provided by CS50. Herein lies the issue:
can a number both be simultaneously a string an an integer? Isn't a string traditionally considered to be a string of letters (i.e a word etc? or a paragraph)?
if a number can be both a string and an integer, what is the use of differentiating it? Particularly in the line of code below.
#include <cs50.h>
#include <stdio.h>
int get_positive_int(string prompt);
int main(void)
{
int i = get_positive_int("Positive Integer: ");
printf("%i\n", i);
}
// Prompt user for positive integer
int get_positive_int (string prompt)
{
int n;
do
{
n = get_int("%s", prompt);
}
while (n <0 || n > 8);
return n;
}
"No!" a variable can't have multiple data types. This may be possible but only with the representation context. For Example:
String a= "1";
Int b=1;
1)We can print both variables and both will give us the same output.
2)We can perform calculations on the second one but to perform calculations on the string, you may need to convert it into number format - either int, double or float.
I saw your follow up question. The difference between these two functions is clear with my second point. You have to pass a string value to the function int get_positive_int(string prompt). But in the case of int get_positive_int(int prompt), you may have to pass an integer value to this function. Both these functions will return an integer value. It depends what you are doing inside the function.
For the function int get_positive_integer(string prompt), you may get a string from the user and convert it into an integer, then return that integer value.
The answer to your question is "no". A number can have one of several C types (e.g. int, double, ...), but only one of them, and string is not a numeric type.
I'm not sure what's unclear to you about the code.

Getting int from a user to array in c

I'm trying to get an array of ints from the user, i did check for illegal input and it works just fine except for the last input:
int *array=(int*)malloc(sizeof(int)*size);
For example for the size 3, let's say the input is 3 5 2.2
So when i assign the numbers into the array the last input (2.2) is considered as 2 and the program continues even though it shouldn't.
Any ideas?
Thank you.
Has nothing to do with your use of malloc(). Instead, you need to check how you are parsing the input. A very naive parser would just read the 2.2 as 2 with some extra garbage at the end. scanf() for example, behaves this way.
You can test this easily:
#include <stdio.h>
void main(void) {
int i;
scanf("%d",&i);
printf("%d\n",i);
}
Feed it a decimal, such as 4.2 and what do you get? 4 -- what happened to the .2 at the end? It's still in the input buffer, actually, waiting for something to read it.
You will have to use a smarter scanner to verify that the user isn't entering garbage.
As PaulProgrammer suggested above that you will have to use a smarter scanner to verify that the user isn't entering garbage.You can use character reader scanner and then check if value entered by user is an integer or not by checking some characteristics, if it belongs to int just convert the character string into integer using functions like atoi(), else output a warning to user.
I have written a small code for you which takes 6 integers and checks for floats and other wrong values.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char ch,arr[20]; //arr is an array for storing the character values initially taken as input.
int x,input[100],i=0,count=0; //input is an array which will hold the integer values
while((x=scanf("%c",&ch))>0){
if(ch=='.') //checking if there is any floating point number
{
printf("Wrong Input");
return 0;
}
if(ch>='0' && ch <='9') //check if ch is in the range of 0-9
{
arr[i++]=ch;
}
if(ch==' ' || ch=='\n'){
arr[i]='\0';
input[count++]=atoi(arr);
i=0;
}
if(count==7) break;
}
for(int loop=0;loop<6;loop++){
printf("%d ",input[loop]);
}
}
I hope you got the point.Please notice when you write this code make sure that it checks for every possible input error.

In C how do I detect whether an input is a character or integer at the same time?

Quite new to C so apologies for the long read and no doubt rubbish programming.
So my program is reading in a CSV file, containing the specification of 15 different transistors. It then compares an input to the data from the CSV file. After the data is input, the program determines which transistors are most suitable. This is meant to loop until the letter q is entered, which is when the program is meant to stop.
The input is entered as eg.
10 0.05 120 5000 20
for volt, amp, power, freq and gain respectively. The program doesn't care about type, company or price.
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#define MAX 15
#define MAX_IN 10000
struct data{
char type[10], company[10];
int volt, power, freq, gain;
float amp, price;
};
struct input{
int volt, power, freq, gain;
float amp;
};
struct input inputs[MAX_IN];
struct data datas[MAX];
main()
{
int chk = 1, num=0;
while(chk == 1)
{
chk = input_function(&num);
}
}
int input_function(int *number)
{
int j=0;
char check=0;
scanf("%c%d %f %d %d %d", &check, &inputs[j].volt, &inputs[j].amp, inputs[j].power, &inputs[j].freq, &inputs[j].gain);
if(check!='q')
{
check_function(j);
++*number;
++j;
return 1;
}
else
{
return 0;
}
}
num is an integer used to determine how many inputs I have put in so that the check function compares the correct input for the input structure.
In a previously similar problem, using %c%d let it check for both a character and an integer at the same time, but this isn't working.
Previously I had it almost working, but it took q as the first input to voltage - so every input after was off by one. Anyone have any ideas?
scanf, fscanf, and sscanf are broken-as-specified and shouldn't ever be used for anything. Forget you ever heard of them.
Use fgets (or getline if available) to read the entire line. Examine its first character manually. If it is q, exit. Otherwise, use a chain of calls to strtol and strtod to parse the line and convert text to machine numbers. (Pay close attention to the part of the strtol/strtod manpages where they explain how to check for errors; it's a little tricky.)

Using atof() function in C with multiple input values

The goal of this program is to create a function which reads in a single string, user typed, command (ultimately for program to be used in conjunction with a robot) which consists of an unknown command word(stored and printed as command), and an unknown number of decimal parameters(the quantity is stored and printed as num, and the parameters are to be stored as float values in the array params). In the User input, the command and parameters will be separated by spaces. I believe my issue is with the atof function when I go to extract the decimal values from the string. What am I doing wrong? Thank you for the help!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void func(char *input, char *command, int *num, float *params);
int main()
{
char input[40]={};
char command[40]={};
int num;
float params[10];
printf("Please enter your command: ");
gets(input);
func(input,command,&num,params);
printf("\n\nInput: %s",input);
printf("\nCommand: %s",command);
printf("\n# of parameters: %d",num);
printf("\nParameters: %f\n\n",params);
return 0;
}
void func(char *input, char *command, int *num, float *params)
{
int i=0, k=0, j=0, l=0;
int n=0;
while(input[i]!=32)
{
command[i]=input[i];
i++;
}
for (k=0; k<40;k++)
{
if ((input[k]==32)&&(input[k-1]!=32))
{
n++;
}
}
*num=n;
while (j<n)
{
for (l=0;l<40;l++)
{
if((input[l-1]==32)&&(input[l]!=32))
{
params[j]=atof(input[l]);
j++;
}
}
}
}
A Sample Output Screen:
Please enter your command: Move 10 -10
Input: Move 10 -10
Command: Move
# of parameters: 2
Parameters: 0.000000
The Parameters output should, ideally, read "10 -10" for the output. Thanks!
Change atof(input[l]) to atof(input + l). input[l] is single char but you want to get substring from l position. See also strtod() function.
Other people have already remarked the problem in your code, but may I suggest that you have a look at strtod() instead?
While both atof() and strtod() discard spaces at the start for you (so you don't need to do it manually), strtod() will point you to the end of the number, so that you know where to continue:
while(j < MAX_PARAMS) // avoid a buffer overflow via this check
{
params[j] = strtod(ptr, &end); // `end` is where your number ends
if(ptr == end) // if end == ptr, input wasn't a number (say, if there are none left)
break;
// input was a number, so ...
ptr = end; // continue at end for next iteration
j++; // increment number of params
}
Do note that the above solution does not differentiate between invalid arguments (say, foo instead of 3.5) and missing ones (because we've hit the last argument). You can check for that by doing this: if(!str[strspn(str, " \t\v\r\n\f")]) --- this checks if we're at the end of string (but allowing trailing whitespace). See the second side-note for what it does.
SIDE-NOTES:
You can use ' ' instead of 32 to check for space; this has two advantages:
It is clearer to the reader (it's very clear that it's a whitespace, instead of "some magic number that happens to have meaning")
It works in non-ASCII encodings (and the standard allows other encodings, though ASCII is by far the most popular; one common encoding is EBCDIC)
For future reference, this trick can help you skip whitespace: ptr += strspn(ptr, " \t\v\r\n\f");. strspn returns the number of characters at the start of the string that match the set (in this case, one of " \t\v\r\n"). Check documentation for more info.
Example for strspn: strspn("abbcbaa", "ab"); returns 3 because you have aab (which match) before c (which doesn't).
you are trying to convert a char into a float,
params[j]=atof(input[l]);
you should get the entire word(substring) of the float.
Example, "12.01" a null terminated string with 5 characters and pass it to atof, atof("12.01") and it will return a double of 12.01.
so, you should first extract the string for each float parameter and pass it to atof
Avoid comparing character to ascii value, rather you could have use ' ' (space) directly.
Instead of using for loop with a fixed size, you can use strlen() or strnlen() to find the length of the input string.

counting the number of digits in using only scanf in c

I need to limit the input from a user to only positive values, and count the number of digits in that number. The user will only type in a (+/-) whole number up to 9 characters long.
I'm only allowed to use the scanf function and for, while, or do-while loops.(I saw in similar questions how to do this using getchar, but I can only use scanf). I'm not allowed to use arrays, or any other library besides stdio.h and math.h
I know that if I write:
n=scanf("%c%c%c%c%c",&a,&b,&c,&e,&f);
n will count the number of successful scanf conversions.
The problem i'm having is that when I define the input with char, it does everything I want except that the user MUST enter 5 characters. So if the user wants to input "55" he has to press "5" "5" "enter" "enter" "enter".
I need the program to move on after the first "enter" but also be flexible to receive a number up to 9 digits long.
again, I can't use getchar or anything fancy. Just the really basic stuff in C that you learn in the first 2 weeks.
Use scanf to read the number into a long int , then use a for loop with a /10 to count the number of digits
What do you want the program to do in case of a -ve number being entered?
#include<stdio.h>
int main()
{
long int a;
int b;
do
{
scanf ("%ld",&a);
if(a<0)
printf ("invalid input");
}while(a<0);
for(b=0;a!=0;b++,a=a/10);
printf("%d",b);
}
(does not handle -ve numbers specially)
Something like
#include <stdio.h>
int main(void)
{
char buffer[10] = { 0 };
size_t len;
scanf("%9[0-9]", buffer);
for(len = 0; buffer[len] != 0; len++) ;
printf("%zu '%s'\n", len, buffer);
return 0;
}
works, but I don't know if it fits your need.
EDIT (bits of explanation)
You can replace size_t with int (or unsigned int), though size_t is better. If you do, use %d or %u instead of %zu.
The basic idea is to exploit a feature of the format of scanf; the 9[0-9] says the input is a sequence of up to 9 char in the given set i.e. the digits from 0 to 9.
The for(...) is just a way to count char, a simple implementation of a strlen. Then we print the result.
The approach I would take would be the following.
Loops are allowed, so go ahead and set one up.
You need to have a variable somewhere that will keep track of what the current number is.
Think about typing out a number, one character at a time. What needs to happen to the current_number variable?
You need to stop the loop if a return key has been pressed.
Something like this should do for starters, but I'll leave the rest up to you, specifically what return_check(ch), update_state(current_val) and char_to_int(ch) looks like. Also note that rather than use a function, feel free to put your own function directly into the code.
int current_val=0;
int num_digits=0;
char ch="\0"
for (num_digits=0;return_check(ch) && num_digits<=9;num_digits++)
{
fscanf("%c");
current_val=update_state(current_val);
current_val=current_val+char_to_int(ch);
}
As for the logic in update_state(), think about what happens, one character at a time, if a user types in a number, like 123456789. How is current_val different from a 1 to a 12, and a 12 to a 123.
Can you wrap a loop around it, something like (I don't know if all of the syntax is right):
const int max_size=9
int n=0; //counter for number of chars entered
char a[max_size-1];
do {
scanf(%c,&a[n]);
n++;
} while (a[n] != '\r' && n<max_size)

Resources