What Is the Cin Analougus of Scanf Formatted Input

Formatted input in C

Declare friend1 & friend2 as char array if you want to store names into them as below

char friend1[50];/** take the char array of required size **/
char friend2[50];

And while scanning you no need to provide & in scanf if friend1 is declared as char array, because char array name itself address.

printf("Please enter name of your friend...\n");
scanf("%s", friend1);

Apply the same for friend2. Also while printing don't use & if you want to print value of average.

Replace

 printf("Average age of your friends %s and %s is %4.2f years old\n"  ,&friend1,&friend2,&average);

with

printf("Average age of your friends %s and %s is %4.2f years old\n"  ,friend1,friend2,average);

Why do C++ standards introduce more output methods without input counterparts?

std::format and std::print are already quite a big library addition in itself and I could image that the limited resources for the standard committee to consider the addition of additional features didn't allow them to consider an input equivalent at the same time.

It might also be that the committee wanted to collect more experience with std::format/std::print first before adding an input equivalent or that there are objections to such an addition in principle, in the proposed implementation details or the priority of such an addition.

I couldn't find any definitive statements pointing towards any of these directions and I have no insider knowledge.

Anyway, the committee is still considering a std::scan proposal as follow-up to the std::format proposal, see https://github.com/cplusplus/papers/issues/493 for a log of the procedure the proposal has gone through so far. You can also see there polls on design directions, etc. There seems to not have been much activity since 2019, but I am not sure whether this really means anything or not.

In a reddit thread here from March 2022, Elias Kosunen, one of the authors of the proposal and author of scnlib mentions that there are still some unsure design questions that need to be made sure of before going forward with the proposal, hoping to be able to target C++26, but acknowledging that a farther delay would be preferable to adding a "half-baked" design to the standard.

Using scanf() in C++ programs is faster than using cin?

Here's a quick test of a simple case: a program to read a list of numbers from standard input and XOR all of the numbers.

iostream version:

#include <iostream>

int main(int argc, char **argv) {

int parity = 0;
int x;

while (std::cin >> x)
parity ^= x;
std::cout << parity << std::endl;

return 0;
}

scanf version:

#include <stdio.h>

int main(int argc, char **argv) {

int parity = 0;
int x;

while (1 == scanf("%d", &x))
parity ^= x;
printf("%d\n", parity);

return 0;
}

Results

Using a third program, I generated a text file containing 33,280,276 random numbers. The execution times are:

iostream version:  24.3 seconds
scanf version: 6.4 seconds

Changing the compiler's optimization settings didn't seem to change the results much at all.

Thus: there really is a speed difference.


EDIT: User clyfish points out below that the speed difference is largely due to the iostream I/O functions maintaining synchronization with the C I/O functions. We can turn this off with a call to std::ios::sync_with_stdio(false);:

#include <iostream>

int main(int argc, char **argv) {

int parity = 0;
int x;

std::ios::sync_with_stdio(false);

while (std::cin >> x)
parity ^= x;
std::cout << parity << std::endl;

return 0;
}

New results:

iostream version:                       21.9 seconds
scanf version: 6.8 seconds
iostream with sync_with_stdio(false): 5.5 seconds

C++ iostream wins! It turns out that this internal syncing / flushing is what normally slows down iostream i/o. If we're not mixing stdio and iostream, we can turn it off, and then iostream is fastest.

The code: https://gist.github.com/3845568

Disadvantages of scanf

The problems with scanf are (at a minimum):

  • using %s to get a string from the user, which leads to the possibility that the string may be longer than your buffer, causing overflow.
  • the possibility of a failed scan leaving your file pointer in an indeterminate location.

I very much prefer using fgets to read whole lines in so that you can limit the amount of data read. If you've got a 1K buffer, and you read a line into it with fgets you can tell if the line was too long by the fact there's no terminating newline character (last line of a file without a newline notwithstanding).

Then you can complain to the user, or allocate more space for the rest of the line (continuously if necessary until you have enough space). In either case, there's no risk of buffer overflow.

Once you've read the line in, you know that you're positioned at the next line so there's no problem there. You can then sscanf your string to your heart's content without having to save and restore the file pointer for re-reading.

Here's a snippet of code which I frequently use to ensure no buffer overflow when asking the user for information.

It could be easily adjusted to use a file other than standard input if necessary and you could also have it allocate its own buffer (and keep increasing it until it's big enough) before giving that back to the caller (although the caller would then be responsible for freeing it, of course).

#include <stdio.h>
#include <string.h>

#define OK 0
#define NO_INPUT 1
#define TOO_LONG 2
#define SMALL_BUFF 3
static int getLine (char *prmpt, char *buff, size_t sz) {
int ch, extra;

// Size zero or one cannot store enough, so don't even
// try - we need space for at least newline and terminator.

if (sz < 2)
return SMALL_BUFF;

// Output prompt.

if (prmpt != NULL) {
printf ("%s", prmpt);
fflush (stdout);
}

// Get line with buffer overrun protection.

if (fgets (buff, sz, stdin) == NULL)
return NO_INPUT;

// Catch possibility of `\0` in the input stream.

size_t len = strlen(buff);
if (len < 1)
return NO_INPUT;

// If it was too long, there'll be no newline. In that case, we flush
// to end of line so that excess doesn't affect the next call.

if (buff[len - 1] != '\n') {
extra = 0;
while (((ch = getchar()) != '\n') && (ch != EOF))
extra = 1;
return (extra == 1) ? TOO_LONG : OK;
}

// Otherwise remove newline and give string back to caller.
buff[len - 1] = '\0';
return OK;
}

And, a test driver for it:

// Test program for getLine().

int main (void) {
int rc;
char buff[10];

rc = getLine ("Enter string> ", buff, sizeof(buff));
if (rc == NO_INPUT) {
// Extra NL since my system doesn't output that on EOF.
printf ("\nNo input\n");
return 1;
}

if (rc == TOO_LONG) {
printf ("Input too long [%s]\n", buff);
return 1;
}

printf ("OK [%s]\n", buff);

return 0;
}

Finally, a test run to show it in action:

$ printf "\0" | ./tstprg     # Singular NUL in input stream.
Enter string>
No input

$ ./tstprg < /dev/null # EOF in input stream.
Enter string>
No input

$ ./tstprg # A one-character string.
Enter string> a
OK [a]

$ ./tstprg # Longer string but still able to fit.
Enter string> hello
OK [hello]

$ ./tstprg # Too long for buffer.
Enter string> hello there
Input too long [hello the]

$ ./tstprg # Test limit of buffer.
Enter string> 123456789
OK [123456789]

$ ./tstprg # Test just over limit.
Enter string> 1234567890
Input too long [123456789]

Is there an equivalent method to C's scanf in Java?

Take a look at this site, it explains two methods for reading from console in java, using Scanner or the classical InputStreamReader from System.in.

Following code is taken from cited website:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class ReadConsoleSystem {
public static void main(String[] args) {

System.out.println("Enter something here : ");

try{
BufferedReader bufferRead = new BufferedReader(new InputStreamReader(System.in));
String s = bufferRead.readLine();

System.out.println(s);
}
catch(IOException e)
{
e.printStackTrace();
}

}
}

--

import java.util.Scanner;

public class ReadConsoleScanner {
public static void main(String[] args) {

System.out.println("Enter something here : ");

String sWhatever;

Scanner scanIn = new Scanner(System.in);
sWhatever = scanIn.nextLine();

scanIn.close();
System.out.println(sWhatever);
}
}

Regards.

Why does scanf appear to skip input?

When you enter a, then cin >> i fails to read it because the type of i is int to which a character cannot be read. That means, a remains in the stream forever.

Now why i prints 0 is a different story. Actually it can print anything. The content of i is not defined once the attempt to read fails. Similar thing happens with scanf as well.

The proper way to write it this:

do
{
++j;
if (!(cin>>i))
{
//handle error, maybe you want to break the loop here?
}
cout<<i<<" "<<j<<"\n";
}
while((i!=8) && (j<10));

Or simply this (if you want to exit loop if error occurs):

int i = 0, j = 0;
while((i!=8) && (j<10) && ( cin >> i) )
{
++j;
cout<<i<<" "<<j<<"\n";
}


Related Topics



Leave a reply



Submit