int currD, currM, currY;
scanf("%d/%d/%d", &currD, &currM, &currY);
I saw this code receiving birth date in the format DD/MM/YYYY, but I wonder what's the meaning of putting '/', I know without this, it will lead to bad input because of the character '/'. So what does it actually mean?
When encountering code that you don’t understand, and which is calling a function from a library, your first order of business is to research the documentation for that function. For C standard functions it’s enough to google the function name.
A good reference in this case is cppreference (don’t be misled by the website name, this is the C reference, not the C++ reference). It gives the function’s definition as
int scanf( const char *format, ... );
Now look for the parameter description of the format parameter:
pointer to a null-terminated character string specifying how to read the input.
The subsequent text explains how to read the format string. In particular:
[…] character [except %] in the format string consumes exactly one identical character from the input stream, or causes the function to fail if the next character on the stream does not compare equal.
conversion specifications [in] the following format
introductory % character
conversion format specifier
d — matches a decimal integer.
In other words:
scanf parses a textual input based on the format string. Inside the format string, / matches a slash in the user input literally. %d matches a decimal integer.
Therefore, scanf("%d/%d/%d", …) will match a string consisting of three integers separated by slashes, and store the number values inside the pointed-to variables.
Is just the separator in the date format. The error must raise when some function searchs for those /.
The first parameter of scanf is a string specifying the format of the string you want to use to store the informations in the further arguments. You can see this format string as a pattern : %d means an integer, and without the '%' it means it just has to match exactly the characters.
Input is expected to provide like 04/07/2019.
If input is provided only 04072019. currD alone hold the value 04072019, currM and currY might garbage value as it is not initialised.
It expects the input to be in the format three integers separated by two slashes ("/"). For example: 10/11/1999.
Related
For example consider the following code -
fscanf(fp,"%d:%d:%[^:]:%[^\n]\n",&pow->no,&pow->seen,pow->word,pow->means);
printf("\ntthis is what i read--\n%d:%d:%s:%s:\n",pow->no,pow->seen,pow->word,pow->means);
here pow is pointer to an object declared before,
when I put s as in fscanf(fp,"%d:%d:%[^:]s:%[^\n]\n" the 3rd one is read but not the last one
output is --
4:0:Abridge::
but when i do fscanf(fp,"%d:%d:%[^:]:%[^\n]s\n" all are read
output is --
4:0:Abridge:To condense:
AND without s anywhere fscanf(fp,"%d:%d:%[^:]:%[^\n]\n" all are read
output is --
`4:0:Abridge:To condense:
WHY??
To answer your question what is the meaning of %[^\n]s there are two format specifier one is [] and another is s.
Now the first one will scan anything other than \n and then it gets a \n and keeps it in stdin. And move on. But it doesn't stop here - it basically then tries to find a match for the letter s. In case it doesn't find it - it fails. (The explanation with %[^:]s will be same as this one).
Now decide if this is what you really want.[^\n] is the right one which will scan until \n is found (and yes it doesn't skip whitespace like %s do). scanset covers the letter including s also. And more than that %[^\n]s is self contradictory. So no use of it either.
%d:%d:%[^:]s:%[^\n]
%d - Matches an optionally signed decimal integer. (Ignore whitespace)
: - Then looks for ':'
%d - Matches an optionally signed decimal integer. (Ignore whitespace)
: - Then looks for ':'
%[^:] - No white space ignored - everything is taken into input except `:`
':' is unread.
s - Tries to match 's'. No white space ignored.
%[^\n] - Everything except '\n' inputted. `\n` left unread.
The specifier IS "%[]", you don't need the "s" there.
Read the manual page for scanf()
Your format string doesn't match the input because you the "s" is not part of the specifier and it's not present in the input where the format is expecting it.
By reading the documentation in the link above, you will find out — if you don't already know — that you should also check the return value of scanf() before calling printf() or otherwise your code will invoke undefined behavior, because some of the passed pointers don't get initialized.
I have this .txt file that contains only:
THN1234 54
How can I take only the number 54, to isolate it from the rest and to use it as an integer variable in my program?
If the input is from standard input, then you could use:
int value;
if (scanf("%*s %d", &value) != 1)
…Oops - incorrectly formatted data…
…use value…
The %*s reads but discards optional leading blanks and a sequence of one or more non-blanks (THN1234); the blank skips more optional blanks; the %d reads the integer, leaving a newline behind in the input buffer. If what follows the blank is not convertible to a number, or if you get EOF, you get to detect it in the if condition and report it in the body of the if.
Hmmm…and I see that BLUEPIXY said basically the same (minus the explanation) in their comment, even down to the choice of integer variable name.
Wow. It's been a long time since I have used C. However, I think the answer is similar for C and C++ in this case. You can use strtok_r to split the string into tokens then take the second token and parse it into an int. See http://www.cplusplus.com/reference/clibrary/cstring/strtok/.
You might also want to look at this question as well.
Code I have:
int main(){
char readChars[3];
puts("Enter the value of the card please:");
scanf(readChars);
printf(readChars);
printf("done");
}
All I see is:
"done"
after I enter some value to terminal and pressing Enter, why?
Edit:
Isn't the prototype for scanf:
int scanf(const char *format, ...);
So I should be able to use it with just one argument?
The actual problem is that you are passing an uninitialized array as the format to scanf().
Also you are invoking scanf() the wrong way try this
if (scanf("%2s", readChars) == 1)
printf("%s\n", readChars);
scanf() as well as printf() use a format string and that's actually the cause for the f in their name.
And yes you are able to use it with just one argument, scanf() scans input according to the format string, the format string uses special values that are matched against the input, if you don't specify at least one then scanf() will only be useful for input validation.
The following was extracted from C11 draft
7.21.6.2 The fscanf function
The format shall be a multibyte character sequence, beginning and ending in its initial shift state. The format is composed of zero or more directives: one or more white-space characters, an ordinary multibyte character (neither % nor a white-space character), or a conversion specification. Each conversion specification is introduced by the character %. After the %, the following appear in sequence:
An optional assignment-suppressing character *.
An optional decimal integer greater than zero that specifies the maximum field width
(in characters).
An optional length modifier that specifies the size of the receiving object.
A conversion specifier character that specifies the type of conversion to be applied.
as you can read above, you need to pass at least one conversion specifier, and in that case the corresponding argument to store the converted value, if you pass the conversion specifier but you don't give an argument for it, the behavior is undefined.
Yes, it is possible to call scanf with just one parameter, and it may even be useful on occasion. But it wouldn't do what you apparently thought it would. (It would just expect the characters in the argument in the input stream and skip them.) You didn't notice because you failed to do due diligence as a programmer. I'll list what you should do:
RTFM. scanf's first parameter is a format string. Plain characters which are not part of conversion sequences and are not whitespace are expected literally in the input. They are read and discarded. If they do not appear, conversion stops there, and the position in the input stream where the unexpected character occured is the start of subsequent reads. In your case probably no character was ever successfully read from the input, but you don't know for sure, because you didn't initialize the format string (see below).
Another interesting detail is scanf's return value which indicates the number items successfully read. I'll discuss that below together with the importance to check return values.
Initialize locals. C doesn't automatically initialize local data for performance reasons (in today's light one would probably enforce user initialization like other languages do, or make auto initialization a default with an opt-out possibility for the few inner loops where it would hurt). Because you didn't initialize readchars, you don't know what's in it, so you don't know what scanf expected in the input stream. On top it probably is nominally undefined behaviour. (But on your PC it shouldn't do anything unexpected.)
Check return values. scanf probably returned 0 in your example. The manual states that scanf returns the number of items successfully read, here 0, i.e. no input conversion took place. This type of undetected failure can be fatal in long sequences of read operations because the following scanfs may read in one-off indexes from a sequence of tokens, or may stall as well (and not update their pointees at all), etc.
Please bear with me -- I do not always read the manual, check return values or (by error) initialize variables for little test programs. But if it doesn't work, it's part of my investigation. And before I ask anybody, let alone the world, I make damn sure that I have done my best to find out what I did wrong, beforehand.
You're not using scanf correctly:
scanf(formatstring, address_of_destination,...)
is the right way to do it.
EDIT:
Isn't the prototype for scanf:
int scanf(const char *format, ...);
So I should be able to use it with just one argument?
No, you should not. Please read documentation on scanf; format is a string specifying what scanf should read, and the ... are the things that scanf should read into.
The first argument to scanf is the format string. What you need is:
scanf("%2s", readChars);
It Should provided Format specifiers in scanf function
char readChars[3];
puts("Enter the value of the card please:");
scanf("%s",readChars);
printf("%s",readChars);
printf("done");
http://www.cplusplus.com/reference/cstdio/scanf/ more info...
I found this in some code and could not understand what it does:
scanf("%[^:]:%[^:]:%[^:\n]", a, b, c);
There was no mention of the [^:]: format string in the C documentation and I am quite confused.
The format string %[..] is for specifying the possible characters. For example %[A-DF] is for A, B, C, D, and F. And the ^ at the beginning is for any character excluding the characters specified. Hence, the first format string is for reading characters excluding colon. And the next is colon, and so on. You may test the scanf for the following input:
Adam:And:Apple
Important thing you should remember is, scanf() function accepts the arguments how it is specified.
For example:
scanf("%d %d",&a,&b);
assuming a and b are integer.
In the command line you have to input a and then followed by space and then b.because you have given a space in-between two "%d's". if you are giving n number of spaces are other character then you have to enter in-between those character before the value gets accepted.
Hence in your case:
you enter the string not containing ":" in it.
Consider this case, if you want to enter a string containing ":" in it.
For example:
"some:init" is the string then, in first %[^:] the string "some" is stored,then comes the ":" and then in second %[^:] it stores init. Then it wait for one more ":" and then the string not containing ":".
ultimately accepting the input in this format doesn't fetch any thing.
The only thing matters is how you print it on to the console.
This question already has an answer here:
Code for printf function in C [duplicate]
(1 answer)
Closed 8 years ago.
What is the exact use of % in scanf and printf? And would scanf and printf work without the % sign? All I could find is that % is the conversion specifier but I want to know how it works actually?
% is simply the symbol used to identify the beginning of a conversion specifier in the format string; why % as opposed to any other symbol is an open question, and probably doesn't have that interesting an answer. The printf and scanf functions search the format string for conversion specifiers to tell them the number and types of additional arguments to expect, and how to format the output (for printf) or interpret the input (for scanf).
To print a literal %, you need to use %%.
printf can work without using a conversion specifier, but you'll be limited to writing literal strings. scanf is pretty useless without it.
The '%' character is used in the format string of the scanf() and print()-like functions from the standard header <stdio.h>, to indicate place holders for variable data of several kinds. For example, the format specifier "%d" is a place holder for a value having type int.
Thus, the variadic function printf() expects additional parameters passed as arguments to the function, the first of them having type int.
The value of this int argument is converted to string, and it will be replace to the place holder "%d".
In the case of scanf(), the situation is similar, but now scanf() is an input function that expects that the user enters in command-line a value fitting on the type indicated by the format specifier. Thus, a format specifier "%d" will expect that the user enters a value of type int.
Since all the arguments in C are passed by value, the input data requires you use the address of the variable, to mimic a by-reference mode of passing arguments.
There are a lot of options and details related to these format specifiers.
Yo need to take a look at the bibliography.
For example, start in Wikipedia:
printf() format string
scanf() format string
The % in a scanf() or printf() is a keyword whose purpose is identify the type of data that will be stored in the named variable. So, in the following example, the compiler would build instructions to accept input data of type integer and store it in the memory location at the address assigned to num1:
int num1;
scanf("%d",&num1);