1

So i am providing a file content to the c program in Command prompt like this. eg- TYPE "FileName" | CProgram.exe . Type command takes the content of file and provides it to my cporgram.exe

Code::

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

# define CACHE 102400

int main(int argc, char* argv[])
{
    
    char *buf = malloc(CACHE * sizeof(char));
    FILE* f = fopen("out.txt", "wb");
    size_t bytesread;

    while(bytesread = fread(buf, sizeof(char), CACHE, stdin))
    {
        printf("bytes read = %zu\n", bytesread);
        fwrite(buf, bytesread, 1, f);
    }
    
    return 0;
}

Im providing a image file as an input. The problem is that the program terminates after reading few bytes. But if i provide a text file it seems to work fine. What should i change so my program can read the piped image file content properly

ryyker
  • 22,849
  • 3
  • 43
  • 87
  • Hey i am not using fopen as the content is piped to the STDIN in CMD. i just have to read the stdin which is what im doing in fread. Sample output Bytes read = 2727 and then the program stops. But the piped file has more bytes to read – shatish syn Oct 06 '20 at 12:09
  • What happens if instead of piping you fopen the file? – Jabberwocky Oct 06 '20 at 12:11
  • That works fine but i have to read the piped content from STDIN thats my usecase. and its not working – shatish syn Oct 06 '20 at 12:13
  • 3
    If you're using Windows like the tag suggests, you need to figure out how to reopen stdin in binary mode. – Shawn Oct 06 '20 at 12:16
  • Hey @Shawn i donot have any problem while printing the content of the files. for instance this command TYPE image.png. prints the binary content of the file with no error. The problem occurs only when i try to read the content in my program thanks – shatish syn Oct 06 '20 at 12:27
  • 1
    @Shawn thank you so much that is exactly my scenarioa. Its working now many thanks to you dude you saved my day <3 – shatish syn Oct 06 '20 at 13:03

1 Answers1

1

If you can include a batch file into your solution, i.e. one that will feed the contents of a file into a shell variable, then use the shell variable as a command line argument to the executable, then the following steps will work:

  • Copy this into a batch file, say read.bat:
    set /p in= < somebinaryfile.bin
    CProgram.exe "%in%"

Note: Unless somebinaryfile.bin location is listed in the path environment variable, it should include <path>, eg: C:\dir1\dir2\somebinaryfile.bin

  • Then execute from command line:

    read.bat

Note, you need to set stdin to binary mode at the beginning of your main() function. for example using _setmode(_fileno(stdin), O_BINARY);

My test code is posted here (Note: it is not fully tested, but works as far as reading a binary file from stdin and transferring binary content to a new file.)

Windows10, using GNU GCC compiler

#include <windows.h>
#include <io.h> // _setmode()
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h> // O_BINARY
#include <time.h>

void make_binary(void);

int main(int argc, char *argv[])
{
    _setmode(_fileno(stdin), O_BINARY);//sets stdin mode to binary 

    //make_binary();//used to produce binary file for testing input
                    //comment after first use.

    FILE *fp = fopen(".\\new_binary.bin", "wb");
    if(fp)
    {
        fwrite(argv[1], sizeof(unsigned char), 1000, fp);
        fclose(fp);
    }
    return 0;
}

//Create some binary data for testing
void make_binary(void)
{
    FILE *fp = fopen(".\\binary.bin", "wb");
    unsigned char bit[1000];
    srand(clock());
    for(int i=0; i< 1000; i++)
    {
        bit[i] = (unsigned char)rand();
    }
    size_t count = fwrite(bit, sizeof(*bit), 1000, fp);
    printf("Number of bytes written to binary.bin = %u\n", count);
    fclose(fp);
}

Yield from a typical session:
enter image description here

ryyker
  • 22,849
  • 3
  • 43
  • 87