3

Consider the following code:

freopen("buffer.txt", "w+", stdin);
fprintf(stdin, "hello");
fseek(stdin, 0, SEEK_SET);
char str[16];
scanf("%s", str);
printf("%s", str);

I've found no entries in standard restricting me from doing that, but also no entries explicitly allowing it. Should I expect this code to work on any standard compliant compiler? Would any standard i/o function break or lead to UB if stdin (or stdout) is opened in read-write mode? What about c++ streams?

Denis Sheremet
  • 2,453
  • 2
  • 18
  • 34
  • 1
    well... looks ok, but check the return value: `if (!freopen(...)) /* error */;` – pmg Feb 09 '20 at 09:48
  • Why would you even think about opening an input stream for write? It doesn't say on your car's fuel-filler not to put honey in, but that doesn't mean it's a good idea – Mark Setchell Feb 09 '20 at 09:49
  • @MarkSetchell It could make sense, if someone wants to get the input from `stdin` to "look" what is in it but futhermore wants to have this input remained in `stdin` for further operations explicitly on `stdin`. – RobertS supports Monica Cellio Feb 09 '20 at 10:08
  • 1
    @RobertSsupportsMonicaCellio Thank you for taking the time to explain it. I am now imagining some kind of *"peeking at the buffer without consuming it"* is maybe possible but still having trouble with the concept of opening an input for writing. – Mark Setchell Feb 09 '20 at 10:18

1 Answers1

3

From C++ standard for freopen function:

FILE * freopen ( const char * filename, const char * mode, FILE * stream );

mode

C string containing a file access mode. It can be:

...

w+ - write/update: Create an empty file and open it for update (both for input and output). If a file with the same name already exists its contents are discarded and the file is treated as a new empty file.

So, by standard it is perfectly legal.

However, if you want to be more sure, then check if the return value is null pointer or not. Or even more, check the errno variable if it is set to a system-specific error code on failure.

Furthermore, if you take a closer look at the freopen docs, you will see the following sentence:

This function is especially useful for redirecting predefined streams like stdin, stdout and stderr to specific files.

This is one more confirmation it is legal to use w+ for stdin.

NutCracker
  • 11,485
  • 4
  • 44
  • 68
  • 1
    Re "*This is one more confirmation it is legal to use w+ for stdin.*", No, all it says is that you can redirect stdin. It's silent on whether you can change its mode. – ikegami Feb 09 '20 at 10:31
  • @ikegami: Unless it places a special restriction on changing its mode, the general allowance to change mode combined with the allowance to use on stdandard streams implies it's allowed. – R.. GitHub STOP HELPING ICE Feb 09 '20 at 16:19