0

I want to directly push a character array into the standard input stream stdin, but cannot think of a syntax that works. The closest I can think of is

freopen("input.txt", "r", stdin);

which reads the contents from a file "input.txt" into the FILE pointer stdin. But I don't like this approach because 1) it relies on creating an additional file, 2) I have to worry about creating one file for each of such requests, which can turn into a ton of txt files in a folder just for this simple purpose of assigning some character array to stdin.

Is there a better, more elegant way of doing this?

4
  • 4
    Might be better to redesign your code such that it's not hard-coded to read from stdin, but a custom-provided file descriptor. Commented Jan 6, 2023 at 19:28
  • @iBug thank you for your suggestion. In my case, I am deliberately doing this to test a program that involves user input. Basically, I want to exhaust all possible user inputs to bash the program. Do you think there is a better alternative for my task? Commented Jan 6, 2023 at 19:32
  • Investigate how much pushback you can do in your environment with ungetc(). Some systems (IIRC, the older Unix systems like Solaris, HP-UX, AIX) have very limited pushback — the standard only guarantees one byte and they adhere to a limit close to that. Many modern systems (Linux, macOS) give you significant buffers — up to about 4 KiB under testing, and I didn't push it beyond that. See ungetc() — number of bytes of pushback? for the details (from a few years ago, but the test code is in my answer there). Commented Jan 6, 2023 at 19:32
  • 4
    If you want to test a program with user input, it's still a better idea to redirect stdin to a file or another controlled source from the outside (e.g. a shell script) than trying to fiddle freopen or ungetc or what have you. Commented Jan 6, 2023 at 19:39

1 Answer 1

2

You're mistaken about this assumption:

which reads the contents from a file "input.txt" into the FILE pointer stdin.

This is not what freopen does! What this does is replacing the file/connection of stdin itself.

This might be a perfectly legitimate thing to do, specifically if your program isn't expecting to have its input being redirected by its creating process.

Within the C standard library you're somewhat limited in what you can do. But if you're allowed to use POSIX syscalls, then you could to the following:

  1. dup the file descriptor of stdin into a temporary.
  2. create an anonymous pipe using the pipe syscall.
  3. dup2 the reading end of the pipe over the stdin file descriptor.
  4. write the character array to the writing end of the pipe.
  5. restore stdin by dup2 the file descriptor saved in step 1) over stdin
  6. close the temporary file descriptor obtained in 1
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, I think you are right that my understanding of freopen was not entirely correct. I am fine with writing hypothetical inputs into an input.txt file and then pointing stdin to the file. However, this process only fulfills one program test for me. I need to perform dozens of such tests, and I wonder if there is a way to avoid dozens of separate text files lying in the test folder. Your second suggestion regarding POSIX is enticing but something new to me. I need to read up on that and then come back. I hope the learning curve isn't that steep.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.