RNR's blog

By RNR, history, 6 years ago, In English

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

  • Vote: I like it
  • +66
  • Vote: I do not like it

| Write comment?
»
6 years ago, # |
  Vote: I like it 0 Vote: I do not like it

Auto comment: topic has been updated by RNR (previous revision, new revision, compare).

»
6 years ago, # |
Rev. 2   Vote: I like it 0 Vote: I do not like it

Are there such cool things possible with cin and cout? Because std::string can't be scanned with scanf and using Fast I/O we cannot use both scanf/cin at a time?

  • »
    »
    4 years ago, # ^ |
    Rev. 2   Vote: I like it +3 Vote: I do not like it

    You can take char array as input by using scanf and then turn that char array into string type.

    Example:

    char a[1000] ={0};     // Declare char array and initialize all of its index with '\0'
    
    scanf("%[^\n]", a );   // take input using scanf until newline character
    getchar();             // for removing newline character from the input stream.
    
    string a1(a);          // Declare string type variable and initialize it with char array
    
    

    That's how you may only use scanf and printf for input output but also take advantage of string type of c++.

  • »
    »
    4 years ago, # ^ |
      Vote: I like it 0 Vote: I do not like it
    string s(100, '\0');
    scanf("%s", s.c_str());
    
»
6 years ago, # |
  Vote: I like it 0 Vote: I do not like it

In part End of File, I think you should change it to:

while (scanf() != -1){
   //do something
}

I have tried this problem before, which I use EOF and get Time limit exceeded. And when I changed to  - 1, I got Accepted. Until now, I still don't know the reason why.

Here is my accepted code, with pass the second test case in 38.70 ms. But when you change  - 1 to EOF then it need about 6000 ms to pass the second test case.

If you know the reason why, please help me. Anyway, thank you very much for your tutorial.

  • »
    »
    6 years ago, # ^ |
    Rev. 2   Vote: I like it +5 Vote: I do not like it

    Maybe it is the problem of the Online Judge and the version of C they are using. I have used EOF in many cases and it worked.

    Scanf 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.(More details are given in REF)

    Another possible solution is to use:-

    int a,b;
    while(scanf("%d %d",&a,&b)){
    }
    

    This can be used in case the last input is other than integers and you have some characters or string.

    or

    int a,b;
    while(scanf("%d %d",&a,&b)==2){
    }
    

    You may have a look at these

    • »
      »
      »
      6 years ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      Thankyou for your reply. But in the first case:

      int a,b;
      while(scanf("%d %d",&a,&b)){
      }
      

      it read infinite times in my computer.

      By the way, I had try this problem in the other Online Judge and get the same result, Time limit exceeded.

      • »
        »
        »
        »
        6 years ago, # ^ |
        Rev. 2   Vote: I like it +5 Vote: I do not like it

        Oh sorry. I have entered some string at the end and it returns 0 because it didn't scan successfully so it returned 0 and exited the while loop so it helps in that format.I have updated thanks. See the comment below for more.

»
6 years ago, # |
  Vote: I like it 0 Vote: I do not like it

Some more

while(fgets()!=0)){
//do something
}

Using cin

while(cin >> x){
//Your code here...
}
»
6 years ago, # |
  Vote: I like it 0 Vote: I do not like it

Auto comment: topic has been updated by RNR (previous revision, new revision, compare).

»
6 years ago, # |
  Vote: I like it 0 Vote: I do not like it

Auto comment: topic has been updated by RNR (previous revision, new revision, compare).

»
6 years ago, # |
  Vote: I like it 0 Vote: I do not like it

Auto comment: topic has been updated by RNR (previous revision, new revision, compare).

»
4 years ago, # |
  Vote: I like it 0 Vote: I do not like it

This is so cool, thank you. :D