3

I have some code that was provided to me written in C that I'm using in a C++ project. I need to add some functionality, along with unit tests. Unfortunately it's hard coded to use getchar and other C IO functions in a way that isn't very easy to test.

What I'm trying to do is mock the C stdin. Is there some way to create a C++ stringstream and redirect C stdin to read from that?

I know how to do it with std::cin but not stdin.

anderspitman
  • 9,230
  • 10
  • 40
  • 61
  • I would bite the bullet and spend some time to rewrite the C code into proper C++ code. Although I can think of some ugly hacks to accomplish this, I cannot chance the risk that this code, with my name on it, would eventually find its way to become a feature article on http://thedailywtf.com – Sam Varshavchik Nov 01 '16 at 02:35
  • 1
    Compile C as C, not C++! They are different languages. – too honest for this site Nov 01 '16 at 02:36
  • Take a look at `freopen`: http://stackoverflow.com/questions/584868/rerouting-stdin-and-stdout-from-c however AFAIK you can only re-open `stdin` to a `FILE` source - you could hack it with a platform-specific technique that creates a 'virtual' file that corresponds to your `stringstream` but performance would suck because it would leave your program. – Dai Nov 01 '16 at 02:40
  • Another option might be to `#define getchar`, if you dare... – Dai Nov 01 '16 at 02:40
  • From the same process? Tricky. From the parent process it's trivial. Just redirect stdin when you launch the process. No muss no fuss. If it's feasible to put your mocking harness in a different process, do that and don't worry about trying to hack the standard library. – Ryan Bemrose Nov 01 '16 at 02:43
  • It's for a school project, so I don't want to pour too much time into it. There's an autograder and some provided integration tests so if adding unit tests is too much trouble I'll just skip it. Currently I'm just adding a text file for each test and using freopen. Any pitfalls there? – anderspitman Nov 01 '16 at 02:43
  • 1
    What about opening a named pipe with freopen and writing to that from my tests? – anderspitman Nov 01 '16 at 02:47
  • Maybe this will help http://www.cplusplus.com/reference/cstdio/stdin/ if not maybe associating a streambuf*. – Nick Pavini Nov 01 '16 at 03:38
  • Why a named pipe? You should just be able to use `pipe()` (assuming a POSIX environment). If you're going to write more than the atomic write size (usually 4096 bytes), you may want to fork the writing end, and have it exit when finished. – Toby Speight Nov 01 '16 at 17:44
  • This question would be much clearer if it had a [mcve]. – Toby Speight Nov 01 '16 at 17:45

0 Answers0