Why doesn't the following function stop for an input 1? - c

I'd like your help with understanding why this function does not stop when I enter any other number than 1.
int main(void) {
double sum,v;
while (scanf("%lf",&v)==1) {
printf("\t%.2f\n", sum += v);
}
It looks like it's suppose to stop whenever the input would be different from 1. I believe that it is has to do with the condition, maybe it checks something before what I think it does.

The function scanf returns the number of items matched and filled, not the actual value it read.
Upon successful completion, these functions shall return the number of
successfully matched and assigned input items; this number can be zero
in the event of an early matching failure. If the input ends before
the first matching failure or conversion, EOF shall be returned.
So in your code scanf will always return 1 for a successful read. You should be testing v instead (but not with ==).

scanf on success returns the number of items successfully read. Therefore you need additionally check if v == 1.

Related

reading string from a file via stdin in c11

So I have a .txt file that I want to read via stdin in c11 program using scanf().
The file is essentially many lines made of one single string.
example:
hello
how
are
you
How can I know when the file is finished, I tried comparing a string with a string made only with eof character but the code loops in error.
Any advice is much appreciated.
Linux manual says (RETURN section):
RETURN VALUE
On success, these functions return the number of input items
successfully matched and assigned; this can be fewer than
provided for, or even zero, in the event of an early matching
failure.
The value EOF is returned if the end of input is reached before
either the first successful conversion or a matching failure
occurs. EOF is also returned if a read error occurs, in which
case the error indicator for the stream (see ferror(3)) is set,
and errno is set to indicate the error.
So test if the return value of scanf equals to EOF.
You can read the file redirected from standard input using scanf(), one word at time, testing for successful conversion, until no more words can be read from stdin.
Here is a simple example:
#include <stdio.h>
int main() {
char word[40];
int n = 0;
while (scanf("%39s", word) == 1) {
printf("%d: %s\n", ++n, word);
}
return 0;
}
Note that you must tell scanf() the maximum number of characters to store into the destination array before the null pointer. Otherwise, any longer word present in the input stream will cause undefined behavior, a flaw attackers can try and exploit using specially crafted input.

Why char value assignment to float is not working

Note:This question is very simple but when I am searching in Google I haven't got any clear clarification.
I have following program
int main()
{
float c;
scanf("%f",&c);
printf("%f",c);
}
o/p
when I am giving a int value (e,g - 9) it is showing it as 9.000000
but when I am giving char value like 'a' it is not showing and showing 0.000000.I know the memory representation of float is totally different from int but then how when I am giving int value (9) it is showing but when I am giving char (a) which is also an int (97) is not showing.
How it is happening. What is the memory representation during char assignment.
Note that there are no chars here anywhere in your code.
This is the way scanf is supposed to work. If you check the return value from scanf (like you should be!) you'll probably see that it's returning 0, meaning no items were matched.
When you give scanf() a "%f" format string, that means "I want you to try and get me a floating point number. When you provide input like 'a', it's not going to match anything, because 'a' is not a valid floating-point number.
http://www.cplusplus.com/reference/cstdio/scanf/
First, you usually should end your printf format string with a newline \n or else call fflush.
Then, you should read the documentation on scanf i.e. its man page scanf(3)
It can fail, and it returns the number of successful matches:
Return Value
These functions return the number of input items successfully matched
and assigned, which can be fewer than provided for, or even zero in
the event of an early matching failure.
The value EOF is returned if the end of input is reached before either
the first successful conversion or a matching failure occurs. EOF is
also returned if a read error occurs, in which case the error
indicator for the stream (see ferror(3)) is set, and errno is set
indicate the error.
A failure is happening when you type an input letter a against a %f conversion specification. In your case the c variable is left unchanged (i.e. "uninitialized").
You should test the result of scanf (it is <=0 on failure in your case).
scanf in the form you wrote it will try to find and read numbers (int/float) up to the first non numerical character (newline, space, any letter). Letters are ints, but this is because of the scanf and the way it should behave. Read up the docs.

fscanf return value

What does fscanf return when it reads data in the file. For example,
int number1, number2, number3, number4, c;
c = fscanf (spFile, "%d", &number1);
//c will be 1 in this case.
c = fscanf (spFile, "%d %d %d %d", &number1, &number1, &number3, &number4);
//in this case, c will return 4.
I just want to know why it returns such values depending on the number of arguments.
From the manpage for the Xscanf family of functions:
Upon successful completion, these functions shall return the number of
successfully matched and assigned input items; this number can be zero
in the event of an early matching failure. If the input ends before
the first matching failure or conversion, EOF shall be returned. If a
read error occurs, the error indicator for the stream is set, EOF
shall be returned, and errno shall be set to
indicate the error
So your first call to fscanf returns 1 because one input item (&number1) was successfully matched with the format specifier %d. Your second call to fscanf returns 4 because all 4 arguments were matched.
I quote from cplusplus.com .
On success, the function returns the number of items of the argument
list successfully filled. This count can match the expected number of
items or be less (even zero) due to a matching failure, a reading
error, or the reach of the end-of-file.
If a reading error happens or the end-of-file is reached while
reading, the proper indicator is set (feof or ferror). And, if either
happens before any data could be successfully read, EOF is returned.
--EDIT--
If you are intention is to determine the number of bytes read to a string.
int bytes;
char str[80];
fscanf (stdin, "%s%n",str,&bytes);
printf("Number of bytes read = %d",bytes);
From the manual page:
*These functions return the number of input items successfully matched and assigned, which can be fewer than provided for, or even zero in the event of an early matching failure. *
Hence 1st one returns 1 if able to read one integer from the file, 2nd one returns 4 if able to read 4 integers from the file.
This happens to be a very straight forward question , and has been aptly answered by charles and ed before me. But they didnt mention where you should be looking for such things the next time you get stuck.
first the question --
the fscanf belongs to the family of formated input(scan) functions that are supposed to read a input and report some info on the data read like bytes or the count of items(variable addresses) that got a appropriate input read and had successfull assignment made.
here the fscanf is supposed to check for matches in the input file with the format string provided in the function call and accordingly assign the (in order of their position) variable - address with the value and once completed it will return the total count for the number of successfull assignments it made. hence the result of 1 and next was 4 (assuming input was provided properly).
second part: where to look ? --
well described details for such function are easily found in your manual pages or posix doc if you refer to one.
if you noticed , the previous two answers also contain small extracts from the man pages .
hope this helps.
The return value is not depending on the number of arguments to fscanf ,it depends on number of values successfully scanned by fscanf.

sscanf - reading from empty string

When I pass an empty string to sscanf, it returns zero and it doesn't change the given variable.
char* ptr = "";
abc = sscanf(ptr, "%s", output);
// abc == 0
Can you let me know the way to work it out?
sscanf awaits the first argument to be the C string that the function processes as its source to retrieve the data. Passing an empty string to this function can't yield your variable to be initialized, since there is nothing this function would initialize it with.
Also note that On success, the function returns the number of variables filled. This count can match the expected number of readings or fewer, even zero, if a matching failure happens. In the case of an input failure before any data could be successfully read, EOF is returned.
Following code, compiled with MinGW (gcc-core 4.5.0-1)
char str[10];
int ret = sscanf("", "%9s", str);
printf("%d\n", ret);
outputs -1 (EOF)
Good way of checking whether sscanf was successful is to check whether it's return value is really equal to the number of provided variables. In this case it would be if (ret == 1). Although many people just check, whether value greater than 0 was returned, to make sure that something has been read and that no error has occurred.

Having scanf in C return void instead of int

If I have a program that is using scanf to get user inputted data:
scanf("%d",&val);
When I run it through lint I get warnings saying that scanf returns a int and it is not being assigned anywhere. What is the c practice to solve this problem? Do I type cast it as void?
(void)scanf("%d",&val);
The C best practice to solve this warnings is simple: Check the resultcode. The scanf function returns in the int if the operation has gone ok or not, and stores the error usually in errno.
The lack of resultcode checks usually results in big errors in certain situations.
The proper answer, of course, is to not ignore the return value. For a robust program, you should always (EDIT: usually) check that the return value indicates success, and fail gracefully when it does not.
Ideally you would do something like
int scanVal = scanf("%d", &val);
if (scanVal != 1) {
// wait a minute, scanf couldn't match input to a "%d"!
}
and then act on the output in a sensible manner.
Instead of silencing the lint message, just check the return value to make sure nothing has gone wrong. From the man page:
RETURN VALUE
These functions return the number of input items
successfully matched and assigned, which can be
fewer than provided for, or even zero in the event of an early
matching failure.
The value EOF is returned if the end of input is reached before
either the first successful conversion or a matching failure occurs. EOF is also >returned if a read error occurs, in which case the
error indicator for the stream (see ferror(3)) is set, and
errno is set indicate the error.
scanf returns the number of input items successfully matched and assigned. Compare its return value to the number you expect in order to detect errors.
while (scanf("%d",&val) != 1)
printf("Try again.\n");
Use
#pragma warning(disable:<warning number>)
scanf("%d",&val);
#pragma warning(default:<warning number>)
And your compiler will suppress that warning.
The best practice is to assign the return value of scanf to see if all (or how many) items were read. In this particular case, if it returns anything but 1, something went wrong (e. g. you wanted a number but the user is giving you unprintable characters) and you should handle it appropriately.
If you want your code to be robust in the presence of bad input, don't use scanf("%d", ...).
For most errors, scanf("%d", &val) will return 0 to indicate that it wasn't able to read an int value (for example, if the input is "foo" rather than "123").
But if the input is syntactically valid but out of range (for example 9999999999999999999), the behavior is undefined.
Most implementations will probably behave sanely, but I don't know how much consistency there is.
To read an int value safely, use fgets() (not gets()) followed by strtol(). (fgets() can have problems with very long input lines, but there are ways to deal with that.)

Resources