C: Ways to use scanf - c

Can I use scanf(...) as argument to a function ?
Like this:
printInteger(scanf(....));
Can I use scanf to attribute the value that I read to some variable ?
Like this:
n = scanf(...);
p.s.: Here I'm explaining why I'm asking this.
This question can be a little weird I know, but I'm working in a project, which is developing a compiler that takes some language as input and then compile to C.
For example, this is my language, let's call 'stackoverflow' ;)
proc printInteger(integer k)
integer i;
begin
for i = 1 to k do
print i;
end
proc main()
integer n, i;
boolean ok;
begin
printInteger(getInteger);
n = getInteger;
ok = true;
while i < n do
begin
print i;
i = i + 1;
end
if ok then print 1; else print 0;
end
I won't get deeper in the language, but notice that getInteger means that I would like to do a scanf(...), what I mean is, when appears getInteger I would like to compile as scanf(...), so that's why I would like to know some ways to use scanf(...).

Can I use scanf(...) as argument to a function ? Like this:
printInteger(scanf(....));
Can I use scanf to attribute the value that I read to some variable ? Like this:
n = scanf(...);
You can use scanf as an argument to a function, but the real answer to both questions is no: scanf doesn't return any data scanned, it returns the number of items successfully scanned - or EOF if the end-of-input is reached before any successful scanning. You only get access to the items scanned using the pointers that you pass as scanf arguments to receive the values. So while you can pass scanf as an argument to a function, it won't do what you seem to want.
If you want to implement the getInteger operation in your language, in C, it's hard to make suggestions since only you know how this language/operation should work. Just using scanf, the implementation would look something like this:
int nextInt;
int numScanned = scanf("%d", &nextInt);
if (numScanned < 1)
handleError();
return nextInt;
But if you're doing general parsing for your language, then using scanf is a bad idea: you'll soon run into problems with the limitations of scanf, and you're not going to be able to anticipate all of the input types unless your language is really simple, simpler than the example that you've included.
To do this properly, find a good lex library for C. This will prevent a lot of headaches. Otherwise, if you must do the lexing yourself, start looking over fgets, get a line at a time from your input, and do the tokenizing yourself.

You ask:
Can I use scanf(...) as an argument to a function like this?
printInteger(scanf(....));
The answer to the first question is "Yes, but ...".
Can I use scanf to attribute the value that I read to some variable like this?
n = scanf(...);
The answer to the second is "No, because ...".
The "but" is mostly 'but it does not do what you expect so you would very seldom, if ever, do so'.
In the first example, scanf() returns either the (integer) number of successful conversions, or EOF if it reached EOF. In no case does it return the value that it just read (not least because, in general, it reads multiple values and most of them are not integers). So, if you want to print the number of values that was converted, you could use the printInteger() function to do so, but it is not what you'd normally want to do.
Similarly, in the second case, you can certainly assign the result of scanf() to an integer n as shown (and it is often sensible to do so if you're going to need to report an error). However, that is not the value that was read (assuming you had a %d conversion specification); it is the number of successful conversions.

Related

How can I fix the scanf to take data into the array?

Can someone please advise regarding the scanf?
"message" is an array of 4 rows by 16 columns.
After the user enters the numbers (all 1 digit integers), when hitting "Enter" there is an error message. As said - probably something with the scanf.
for (int i = 0; i < M; i++) {
for (int j = 0; j < columns; j++) {
scanf("%d", message[i][j]);
}
}
[Answer adapted from a now-deleted former question.]
scanf seems like a nice, simple, easy, convenient way to read input. And in some ways it is, but it turns out that using it correctly can be surprisingly difficult, and it's chock-full of pitfalls.
You're probably not going to want to learn about all of scanf's intricacies at first. So for now, here are some guidelines for using a subset of scanf's functionality, safely. (For reasons I fail to understand, everybody tells beginners to use scanf, but nobody ever teaches rules like these along with it.)
Remember to always use & in front of the variables you're trying to read. (This is a special rule, for scanf only. Don't try to use that & on the variables you pass to printf, for example.)
Exception to rule 1: Do not use the & when you are reading strings with %s.
If you are reading strings using %s, make sure the variable you read into is either a character array that's big enough for what the user is likely to type, or a pointer to malloc'ed memory that's big enough for what the user is likely to type. (See also note below about avoiding overflow.)
Be aware that %s reads strings that don't contain space characters. You can't use %s to read strings (like full names) that might contain spaces. (For now, please don't worry about how you might read a string that might contain spaces. See also rule 14.)
Don't try to use scanf and fgets together in the same program.
Don't try to use scanf and getchar together in the same program.
Try to limit yourself to only the format specifiers %d, %s, %f, and %lf, to read into variables of type int, string (see rule 3), float, and double, respectively.
If you want to read a character into a variable of type char, you can use " %c", but the mysterious extra explicit space character there is vital.
Use only one % sign in the format string, to read one variable. Don't try to read two or more variables in one scanf call.
Always check scanf's return value. If it returns 0, or the negative value EOF, that means it didn't successfully read anything. If it returns 1, that means it successfully read one value. (And if you break rule 9, and try to read multiple values, it'll return the number of values it did successfully read, anywhere between 0 and the number you asked for.)
If scanf returns 0 or EOF, indicating that the user did not type a valid value, just print an error message and exit. Don't try to write code that asks the user to try again, because the user's wrong input is still sitting on the input stream, and there's no good, simple way to get rid of it. (If you really want to write user-friendly code that re-prompts in case of error, scanf is not the right tool for the job.)
Never put whitespace after the format string. That includes the newline character \n. (That is, use "%d", not "%d " or "%d\n".)
Don't try to use the %[…] specifier.
If you break rule 13 (perhaps because someone told you that %[…] might be a way to read a string containing spaces, or a whole line), do not put an s after it. The format is %[…], not %[…]s.
These rules may seem restrictive, but if you follow these rules, you should be able to simply and easily and reliably get simple inputs into your simple programs, which is the goal here. scanf is otherwise remarkably hard to use, and experience has shown that there are something like 17 different horribly frustrating problems that tend to come up, and trying to solve them is a completely unnecessary distraction from your goal of learning C by writing simple C programs.
When you're reading strings with %s or %[…], there's a danger: no matter how big the array or malloc'ed buffer you're reading into is, the user might type more than that. To avoid overflow, you can use a format like %19s to explicitly tell scanf how many characters it's allowed to read. (And remember to subtract 1, to leave room for the terminating '\0'. That is, you'd use %19s to read into char str[20]; or char *p = malloc(20);.)
These rules are somewhat numerous. For a simpler set of rules, see this answer. Putting rules 7, 8, 9, 12, and 13 together, there are really only five complete format strings you want to use with scanf: "%d", "%s", "%f", "%lf", or " %c". (But no commas, no fixed strings, no whitespace other than the explicit space in " %c", nothing else.) Exception: as mentioned above, it's fine to use something like %19s to limit the length of a string being read.
If you need to do something more complicated, that you can't do while staying within these rules, it's time to either:
Learn enough about how scanf really works (and doesn't work) so that you can try to do the thing you want, but without getting stuck on one of those 17 problems, or
Learn how to do input using better and more powerful methods than scanf, perhaps by reading whole lines using fgets and then parsing them.
You're missing a "&" before "message[i][j]".
for (int i = 0; i < M; i++) {
for (int j = 0; j < columns; j++) {
scanf("%d", &message[i][j]);
}
}

Identyfying prefix in the same string as a suffix

Eg-
maabcma is valid because it contains ma as a proper prefix as well as a proper suffix.
panaba is not.
How do I find out if a word is valid or not as above in C language?
I'm not very good at string operations. So, please help me out with a pseudocode.
Thanks in advance.
I'm completely lost. T=number of test cases.
EDIT: New code. My best code so far-
#include<stdio.h>
#include<string.h>
void main()
{
int i,T,flag=0;
int j,k,len=0;
char W[10],X[10];
scanf("%d",&T);
for(i=0;i<T;i++)
{
scanf("%s",W);
for(len=0;W[len]!='\0';len++)
X[len]=W[len];
X[len]='\0';
for(j=len-1;j>=0;j--)
for(k=0;k<len;k++)
{
if(X[k]!=W[j])
flag=0;
else if((j-k)==(len-1))
flag==1;
}
if (flag == 1)
printf("NICE\n");
else
printf("NOT\n");
}
}
Still not getting the proper results. Where am I going wrong?
The thing is you are only setting the value of flag if a match exists, otherwise you must set it to 0. because see, if I have:
pammbap
my prefix is pam and suffix is bap.
According to the final for loop,
p and a match so flag is set to 1.
but when it comes to b and m it does not become zero. Hence, it returns true.
First, void is not a valid return type for main, unless you are developing for Plan 9.
Second, you should get into the habit of checking the return value of scanf() and all input functions in general. You can't rely on the value of T if the user does not input a number, because T is uninitialised. On that same note, you shouldn't use scanf with an unbounded %s scan operation. If the user enters 20 characters, this isn't going to fit into the ten character buffer that you have. An alternative approach is to use fgets to get a whole line of text at once, or, to use a bounded scan operation. If your array fits 10 characters (including the null terminator) then you can use scanf("%9s", W).
Third, single-character variable names are often very hard to understand. Instead of W, use word, instead of T, use testCount or something similar. This means that someone looking at your code for the first time can more easily work out what each variable is used for.
Most importantly, think about the process in your head, and maybe jot it down on paper. How would you solve this problem yourself? As an example, starting with n = 1,
Take the first n characters from the string.
Compare it to the last n characters from the string
Do they match?
If yes, print out the first n characters as the suffix and stop processing.
If no, increment n and try again. Try until n is in the middle of the string.
There are a few other things to think about as well, do you want the biggest match? For example, in the input string ababcdabab, the prefix ab is also the suffix, but the same can be said about abab. In this case, you don't want to stop processing, you want to keep going even if you find a prefix, so, you should just store the length of the largest prefix that is also the suffix.
Second-most-importantly, running into hurdles like this is incredibly common when learning C, so don't let this put a dampener on your enthusiasm, just keep trying!

format specifiers in scanf( ) in C?

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);

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.)

How can I use C to assign user input to a variable?

I am wondering if there is a function I could use in the standard libary. Do I need another library (BTW, I am developing for unix).
See the scanf() function in stdio.h. It takes a format specifier like printf() and pointers to the variables to store the user input in
Use scanf()
Format: int scanf ( const char * format, ... );
Read formatted data from stdin.
Reads data from stdin and stores them according to the parameter format into the locations pointed by the additional arguments. The additional arguments should point to already allocated objects of the type specified by their corresponding format tag within the format string.
Example:
#include <stdio.h>
int main(void)
{
int n;
printf("Enter the value to be stored in n: ");
scanf("%d",&n);
printf("n= %d",n);
}
However have a look at this.
You seems quite new to C so let me add a little something to Prasoon answer, which is quite correct and complete, but maybe hard to understand for a beginner.
When using scanf( const char * format, ... ); in his exemple, Prasoon use :
scanf("%d",&n);
When using this, the "%d" indicate you're going to read an integer (See wikipedia for complete format list ).
The second argument (note that the ... indicates you can send any number of arguments) indicate the address of the variable in which you are gonna stock user entry.
'Tis interesting - two answers so far both suggest scanf(); I wouldn't.
When everything goes right, scanf() is OK. When things go wrong, recovery tends to be hard.
I would normally use fgets() to read the user information for one line into a buffer (character array) first. I would then use sscanf() to collect information from the buffer into the target variables. The big advantage is that if the user types '12Z' when you wanted them to type two numbers, you can tell them what you saw and why it is not what you wanted much better. With scanf(), you can't do that.

Resources