Related
I have to take two inputs from the user with %
input example: 20% 30%
I tried this
scanf("%d%d ", &x,&y);
how can I input two values with %? I can only take two integer values.
%% matches literal % character, so this should do it:
int r = scanf("%d%%%d%%", &x,&y);
if(r != 2) {
puts("scanf error");
exit(1);
}
General note: it's more robust to read entire lines with fgets or POSIX getline, then parse them, for example with sscanf.
Also, please read scanf documentation on what %d and %% do, and what the return value actually means.
Firstly, are you really obligated to also take the %? Couldn't you instead ask the user to input integers?
If you still want to take inputs with %, I think you could treat your inputs as char*, iterate through them until you encounter the '%' char, and then delete it.
You could then use the atoi function to transform your char* into integers.
So I think this should be pretty straight forward. I actually can't even understand what could possibly be going wrong, and that's what bugs me the most.
Here's the deal: I have to read a couple of numbers from a file, but these numbers are in scientific notation. An example file would have the numbers like this:
1.00090E+00,2.90000E+00
So I thought I'd simply read it like this: get a double, ignore a character, get an int, ignore a character, get another double, ignore a character, and get a final int, so for this example, it would:
get (1.00090)
ignore (E)
get (+00)
ignore (,)
get (2.90000)
ignore (E)
get (+00)
So, I wrote these fscanf:
fscanf(arquivo, " %lf%*c%d%*c", &mantissa1, &expoente1);
x[i] = numToFloat(mantissa1, expoente1);
fscanf(arquivo, "%lf%*c%d", &mantissa2, &expoente2);
fx[i] = numToFloat(mantissa2, expoente2);
I separated them to make the understanding simpler. But then, it doesn't work. It reads the first double correctly, but then it messes up the int. And then it messes up everything on the second fscanf.
I tried all that I could think of. Put the formatted string onto the fscanf ("%lfE%d," and "%lfE%d"). To read the signal into a character variable ("%lf%*c%c%d%*c"). None of it works.
Any guesses as to what's wrong?
First, you do not need to parse the mantissa and exponent separately. scanf natively understands n.nnnEĀ±nnn notation. This is why your format string doesn't behave as you expect; the %lf directive consumes the entire first number including the E+00 piece, then %*c consumes the comma, %d the 2, and now we're hopelessly out of sync.
Second, you should not use any of thescanf functions, ever. Instead, read a line at a time with fgets (or getline, if you have it), split it on commas with strtok, and convert numbers to binary with strtod (which also natively understands scientific notation). This will be more coding up front, but the result will be easier to read and debug, it will be easier to make it robust against malformed input, and it will have well-defined behavior on input overflow.
(Technically you do not need to use strtok, as strtod will tell you where each number ends, but it is conceptually simpler to do the splitting first.)
You might be able to adapt this example to your needs, it used the %lg format specifier:
#include <stdio.h>
int main(void){
double d, e;
int n;
printf("Enter 2 scientific floats: ");
fflush(stdout);
n = scanf("%lg %*c %lg", &d, &e);
if(n == 2) {
printf("%f\n", d);
printf("%f\n", e);
} else {
printf("Bad input\n");
}
}
Program session
Enter 2 scientific floats: 1.8e+4,4.2e-1
18000.000000
0.420000
Why do we pass the format specifiers to scanf( ) in C as its parameters?
I mean, can't we just do
scanf( &var ); // Here, var is any pre-declared variable.
the type of var can be fetched from its declaration. Why is this not allowed ?
I see the below code as a waste of memory.
scanf( "%d" , &var );
The type cannot be "fetched from it's declaration". There is nothing magical about scanf(), it's just a function. A function in C cannot access meta information about variables.
This is why, in general, function arguments are declared including their type. For variable-argument functions such as scanf(), the first argument is not optional and it is used to describe the number and type of the other arguments in some fashion chosen by the function itself.
You clearly need to read some book on C programming to get better understanding of the core concepts. Unlike some other languages, C doesn't have I/O mechanism baked into the language. scanf() is just a library function and as such, this function has no way to automagically know the type of the variable it is supposed to fill.
Because %d will simply specify what the type of var is, there is no memory wastage. scanf(&var) would not work because the function is not designed to accept arguments that way.
You know that variables in C can be of different types:
int: Integer
char: Character
float: Floating point number.
...
Unlike other languages, variable types cannot be implicitly inferred at compilation time in C. That is why you always declare the type of your variables ( Example: int a or char c).
Because scanf is just a function in C, and because functions in C should take parameters of a specific type, people who coded C decided to use the following format:
scanf("%d", &var) ; // for integers
scanf("%c", &var); //for chars
scanf("%f", &var); //for double and floats.
using %d or %c does not waste memory or whatsoever. you can think about it as a flag that specifies the type of the input variable.
Could the developers of C do it without %d, %c...etc? Yes they could, but then, they have to handle all possible exceptions that might arise from sending the wrong type.
Suppose the developers of C used just the following format
scanf(&var);
That is surly very concise, but then you will have to use the same syntax to send chars/int/double...etc, and then the function scanf has to figure out a way to decide about the type of the variable that was sent. Remember what I told you before? variable types CANNOT be implicitly inferred at compilation time, and thus, this task will be almost impossible.
They could however use a different scanf function for every type. For example:
scanfInt(&var); //for integers.
scanfFloat(&var); //for floats.
...
...
That would work perfectly, but it makes less sense to replicate the same code of scanf and use different functions just because the type is different.
So what is the solution? ==> Use the same function name ( scanf ), and then add a parameter (%d, %f, %c..) that will be used internally as a flag by C to know the parameter type.
I hope now you have a better understanding of the use of %d, %f....
There are two major points you are missing here.
First, we humans sitting at the keyboard will write something like:
char var = '0';
And we know that the "type" of this variable is char and we probably intend to store a character there. Once the compiler gets a hold of this it removes these "human" elements all that is left is at some memory location there is 1 byte reserved, further references to places in the code where we wrote "var" will interact with this memory location. That is all the compiler knows, there is no understanding of the intended variable "type".
Second, the format specificers do so much more than just indicate a simple type. Look at any page explaining scanf() and you'll see a long list, take special note of things like scan sets, negated scan sets, and expected input lengths.
Let's say I want the user to enter just a single digit, 0-9, well I don't have to just assume they will do as I ask, I can help ensure they will by using the format specifiers in scanf():
int var = 0;
print("enter 1 digit (0-9):\n");
scanf("%1d", &var);
Now, no matter how many digits they enter, I'll only have stored the first one.
What if you have a string that you want to read from the user, and you want to read everything up until you hit a new line character (read over spaces). We'll there are a number of options for this, but scanf can do it too. The "standard" to read a string is:
scanf("%s",some_string);
But that will stop at any whitespace character, so you wouldn't want scanf() to make an assumption in this case, you'd want to be able to use a specific negated scanset:
scanf("%[^\n]",some_string);
My assignment states
"The program is not allowed to show any menu: It must receive the option of the mathematical function to execute and its arguments as parameters in the main function."
and examples of execution of the program are (suppose the program is called c2):
./c2 fradd 2/3 5/7
# Expected output: 29/21
My understanding is that we have to write a function fFradd() outside of int main (int argc, char * argv[]). Then implement that function.
So my question is: How do I take the fractions given as arguments and split them into n1, d1, n2, d2?
I know (using the example given) that 2/3 would be saved into one space of the argv[] array (I'm not sure that's the proper terminology but hopefully you understand my point). I'm just not sure how to get the program to read that argument (argv[2]) and recognize 2/3 as n1/d1.
The closest I could find was using something like sscanf(argv[2],"%i/%i",n1,d1);, but I know sscanf is for strings...and obviously that can't be done with scanf()
You're 100% right, you should use sscanf().
Not sure what you mean by "sscanf() is for strings". It's for scanning a string, and converting parts of the string into other values of other types. Here, read the manual page one more time to refresh your idea of what the function is capable of doing.
Converting to integer is very common, and is done almost as you said. You must pass the address of the destination variable for each conversion though, so make it:
int n, d,
if(sscanf(argv[i], "%d/%d", &n, &d) == 2)
{
printf("got the fraction %d/%d\n", n, d);
}
the above should probably be put into a loop, as the argv[i] implies.
Why does C's printf format string have both %c and %s?
I know that %c represents a single character and %s represents a null-terminated string of characters, but wouldn't the string representation alone be enough?
Probably to distinguish between null terminated string and a character. If they just had %s, then every single character must also be null terminated.
char c = 'a';
In the above case, c must be null terminated. This is my assumption though :)
%s prints out chars until it reaches a 0 (or '\0', same thing).
If you just have a char x;, printing it with printf("%s", &x); - you'd have to provide the address, since %s expects a char* - would yield unexpected results, as &x + 1 might not be 0.
So you couldn't just print a single character unless it was null-terminated (very inefficent).
EDIT: As other have pointed out, the two expect different things in the var args parameters - one a pointer, the other a single char. But that difference is somewhat clear.
The issue that is mentioned by others that a single character would have to be null terminated isn't a real one. This could be dealt with by providing a precision to the format %.1s would do the trick.
What is more important in my view is that for %s in any of its forms you'd have to provide a pointer to one or several characters. That would mean that you wouldn't be able to print rvalues (computed expressions, function returns etc) or register variables.
Edit: I am really pissed off by the reaction to this answer, so I will probably delete this, this is really not worth it. It seems that people react on this without even having read the question or knowing how to appreciate the technicality of the question.
To make that clear: I don't say that you should prefer %.1s over %c. I only say that reasons why %c cannot be replaced by that are different than the other answer pretend to tell. These other answers are just technically wrong. Null termination is not an issue with %s.
The printf function is a variadic function, meaning that it has variable number of arguments. Arguments are pushed on the stack before the function (printf) is called. In order for the function printf to use the stack, it needs to know information about what is in the stack, the format string is used for that purpose.
e.g.
printf( "%c", ch ); tells the function the argument 'ch'
is to be interpreted as a character and sizeof(char)
whereas
printf( "%s", s ); tells the function the argument 's' is a pointer
to a null terminated string sizeof(char*)
it is not possible inside the printf function to otherwise determine stack contents e.g. distinguishing between 'ch' and 's' because in C there is no type checking during runtime.
%s says print all the characters until you find a null (treat the variable as a pointer).
%c says print just one character (treat the variable as a character code)
Using %s for a character doesn't work because the character is going to be treated like a pointer, then it's going to try to print all the characters following that place in memory until it finds a null
Stealing from the other answers to explain it in a different way.
If you wanted to print a character using %s, you could use the following to properly pass it an address of a char and to keep it from writing garbage on the screen until finding a null.
char c = 'c';
printf('%.1s', &c);
For %s, we need provide the address of string, not its value.
For %c, we provide the value of characters.
If we used the %s instead of %c, how would we provide a '\0' after the characters?
Id like to add another point of perspective to this fun question.
Really this comes down to data typing. I have seen answers on here that state that you could provide a pointer to the char, and provide a
"%.1s"
This could indeed be true. But the answer lies in the C designer's trying to provide flexibility to the programmer, and indeed a (albeit small) way of decreasing footprint of your application.
Sometimes a programmer might like to run a series of if-else statements or a switch-case, where the need is to simply output a character based upon the state. For this, hard coding the the characters could indeed take less actual space in memory as the single characters are 8 bits versus the pointer which is 32 or 64 bits (for 64 bit computers). A pointer will take up more space in memory.
If you would like to decrease the size through using actual chars versus pointers to chars, then there are two ways one could think to do this within printf types of operators. One would be to key off of the .1s, but how is the routine supposed to know for certain that you are truly providing a char type versus a pointer to a char or pointer to a string (array of chars)? This is why they went with the "%c", as it is different.
Fun Question :-)
C has the %c and %s format specifiers because they handle different types.
A char and a string are about as different as night and 1.
%c expects a char, which is an integer value and prints it according to encoding rules.
%s expects a pointer to a location of memory that contains char values, and prints the characters in that location according to encoding rules until it finds a 0 (null) character.
So you see, under the hood, the two cases while they look alike they have not much in common, as one works with values and the other with pointers. One is instructions for interpreting a specific integer value as an ascii char, and the other is iterating the contents of a memory location char by char and interpreting them until a zero value is encountered.
I have done a experiment with printf("%.1s", &c) and printf("%c", c).
I used the code below to test, and the bash's time utility the get the runing time.
#include<stdio.h>
int main(){
char c = 'a';
int i;
for(i = 0; i < 40000000; i++){
//printf("%.1s", &c); get a result of 4.3s
//printf("%c", c); get a result of 0.67s
}
return 0;
}
The result says that using %c is 10 times faster than %.1s. So, althought %s can do the job of %c, %c is still needed for performance.
Since no one has provided an answer with ANY reference whatsoever, here is a printf specification from pubs.opengroup.com which is similar to the format definition from IBM
%c
The int argument shall be converted to an unsigned char, and the resulting byte shall be written.
%s
The argument shall be a pointer to an array of char. Bytes from the array shall be written up to (but not including) any terminating null byte. If the precision is specified, no more than that many bytes shall be written. If the precision is not specified or is greater than the size of the array, the application shall ensure that the array contains a null byte.