Scanf and non-standard input format [Tutorial for beginners]

Revision en6, by RNR, 2020-05-17 19:26:58

Reading Integers until End of file:

int a[110];
for(i = 0; scanf("%d", &a[i])!=EOF; i++);

Because scanf will return the total number of input successfully scanned.

Reading date

int day, month, year;
scanf("%d/%d/%d", &month, &day, &year);

Helps when input is of format

01/29/64

Read Binary string

char str[20];
scanf("%[01]s", str);
printf("%s\n", str);

%[01]s – Read only if you see 0’s and 1’s. Shorthand for matching characters in the seq [01] can also be extended for decimals using %[0-9]s. Similarly, %[abc]s – Read only if you see a, b, c. [...] read till these characters are found. [^...] read until these characters are not found.

char s[110];
scanf(“%[^\n]s”, s);

Here,we have [^\n]. The not operator (^) is used on the character \n, causes scanf to read everything but the character \n – which is automatically added when you press return after entering input.

Read but donot store. (use * assignment suppression character)

scanf("%d %*s %d", &a, &b);

The above segment can be used to read date format and do not store the month if the format is dd month yyyy (06 Jan 2018).Read the desired input, but do not store.

To read char

char c;
scanf("%*[ \t\n]%c",&c);
scanf(“%2d”, &x);

In this example we have, a number located between the % and d which in this case is 2. The number determines the number of integers our variable input (of integer type) will read. So if the input was “3222”, our variable would only read “32”.

End of File

while (scanf() != EOF){
   //do something
}

Example from CP1

Take this problem with a non-standard input format: the first line of input is an integer N. This is followed by N lines, each starting with the character ‘0’, followed by a dot ‘.’, then followed by an unknown number of digits (up to 100 digits), and finally terminated with three dots ‘...’.

Input:-

 3
 0.1227...
 0.517611738...
 0.7341231223444344389923899277...

One possible solution is as follows.

#include <cstdio>
using namespace std;

int N;         // using global variables in contests can be a good strategy
char x[110];  // make it a habit to set array size a bit larger than needed

int main() {
  scanf("%d\n", &N);
  while (N--) {                  // we simply loop from N, N-1, N-2, ..., 0
    scanf("0.%[0-9]...\n", &x);   // `&' is optional when x is a char array
                         // note: if you are surprised with the trick above,
                      // please check scanf details in www.cppreference.com
    printf("the digits are 0.%s\n", x);
} } // return 0;

Please feel free to add more in comments. Thank you for reading. Learn and let learn.

[UPD]

Scanf with search sets

We used hyphen in format string: dd-mm-yyyy

If we want more than one option: hyphen or slash: - or / then use search set %[-/]

Store the search string in a character variable

#include <stdio.h>
void main()
{
    int date, month, year;
    char separator[2];
    printf("Input the date:");
    scanf("%d%[-/]%d%[-/]%d", &date, separator, &month, separator,&year);
    printf("Date: %d\n", date);
    printf("Month: %d\n", month);
    printf("Year: %d\n", year);
}

Examples

Input the date:31-12-2013
Date: 31
Month: 12
Year: 2013
*** another input ***
Input the date:14/1/2014
Date: 14
Month: 1
Year: 2014
*** another input ***
Input the date:26/2-2014
Date: 26
Month: 2
Year: 2014

The more simplified version using the above-mentioned assignment suppression operator.

scanf("%d%*[-/]%d%*[-/]%d", &date, &month, &year);

More Info:

That the terminal is line-buffered means that it submits input to the program when a newline character is encountered. It is usually more efficient to submit blocks of data instead of one character at a time. It also offers the user a chance to edit the line before pressing enter.

Thanks

UPD 2

stringstream

You are given a String Rectangle consists of four integers separated by single spaces, with no additional spaces in the string. The first two integers are the window coordinates of the top left pixel in the given rectangle, and the last two integers are the window coordinates of its bottom right pixel.

     string rectangle;
     cin>>rectangle;
     istringstream ss(rectangle); 
     int x1,y1,x2,y2; 
     ss >> y1 >> x1 >> y2 >> x2;
    std::string s = "split on    whitespace   ";
    std::vector<std::string> result;
    std::istringstream iss(s);
    for(std::string s; iss >> s; )
        result.push_back(s); // ["split", "on", "whitespace"]

Thank you

Tags i/o, scanf

History

 
 
 
 
Revisions
 
 
  Rev. Lang. By When Δ Comment
en6 English RNR 2020-05-17 19:26:58 235
en5 English RNR 2018-01-23 07:50:11 511 Tiny change: 'n~~~~~\n\n' -> 'n~~~~~\n\nThank you'
en4 English RNR 2018-01-08 16:11:34 1254 Tiny change: 'arn**.\n\n\n\n\n' -> 'arn**.\n\n[UPD]\n\n#### Scanf with search sets\n\n\n'
en3 English RNR 2018-01-08 15:57:37 5 Tiny change: 'd", &a[i]); i++);\n~' -> 'd", &a[i])!=EOF; i++);\n~'
en2 English RNR 2018-01-06 09:13:54 3 Tiny change: 'fully scan.\n\n#### ' -> 'fully scanned.\n\n#### ' (published)
en1 English RNR 2018-01-06 09:09:28 3020 Initial revision (saved to drafts)