Xter
Xter

Reputation: 73

redirecting stdin to file

I want to write a program that takes whatever I type in terminal and writes it to file. Here is the code that I wrote.

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int fd[2];
void pri(){
   char a[10];
   int ad=open("t.txt",O_CREAT | O_APPEND | O_NONBLOCK |  O_RDWR, 0644);
   if(read(fd[0],a,10)>0){
       write(ad,a,10);
   }   
}
int main()
{
   int a;
   char s[10];
   pipe(fd);
   while(read(0,s,10)>0){
      write(fd[1],s,10);
      pri();
   }
   return 0;
}

Currently I am using arrays and a pipe for achieving this. Is there any way that I can achieve the same without using any arrays?

Upvotes: 1

Views: 342

Answers (2)

Achal
Achal

Reputation: 11921

I want to write a program that takes whatever I type in terminal and writes it to file. => yes it's possible, use dup() or dup2() and close() system call accordingly.

char c;
int main(int argc,char *argv[])
{

        close(1);//so that it should not print anything on console 
        int ad=open(argv[1],O_CREAT | O_APPEND | O_NONBLOCK |  O_RDWR, 0644);
        // now ad is available file descriptor which is 1
        if(ad == -1){
                perror("open");
                return 0;
        }
        while(read(0,&c,1)>0){
                write(ad,&c,1);
        //when you don't want to take any input further press ctrl+d that will first save the data
        }
        return 0;
}

What's the need of using pipe for input redirection task I mean you just want to redirect user input into file So pipe() is unnecessary if this is only task because you are not doing any kind of communication b/w child or parent process.

Upvotes: 0

Scheff&#39;s Cat
Scheff&#39;s Cat

Reputation: 20141

I want to write a program that takes whatever I type in terminal and writes it to file.

That's actually very simple and you don't need a pipe for this. (Your application itself takes the role of the pipe.)

This is what I did to demonstrate this: mycat.c

#include <stdio.h>

int main(int argc, char **argv)
{
  if (argc < 2) {
    fprintf(stderr, "ERROR: No output file!\n");
    fprintf(stderr, "Usage: mycat FILE\n");
    return 1;
  }
  FILE *fOut = fopen(argv[1], "w");
  if (!fOut) {
    fprintf(stderr, "ERROR: Cannot open file '%s' for writing!", argv[1]);
  }
  int c;
  while ((c = getc(stdin)) >= 0) {
    if (putc(c, fOut) < 0) {
      fprintf(stderr, "ERROR: Cannot write to file '%s'!", argv[1]);
    }
  }
  if (fclose(fOut)) {
    fprintf(stderr, "ERROR: Cannot write to file '%s'!", argv[1]);
  }
  return 0;
}

It reads a character from stdin and writes it to the file stream fOut which has been opened by fopen() before. This is repeated until getc() fails which might happen e.g. due to end of input.

Sample session in bash on Cygwin/Windows 10:

$ gcc --version
gcc (GCC) 6.4.0

$ gcc -std=c11 -o mycat mycat.c

$ ./mycat
ERROR: No output file!
Usage: mycat FILE

$ ./mycat mycat.txt
Hello World.
tip tip tip

At this point, I typed Ctrl+D to signal bash the end of input.

$ cat mycat.txt
Hello World.
tip tip tip

$

I used cat to output the contents of mycat.txt. It is what typed in before (as expected).

cat was actually my first idea when I read the question but then I thought: It's a question tagged (not ). Hence my C sample code.

For completeness, the same with cat:

$ cat >mycat.txt <<'EOF'
> Hello cat.
> key key key
> EOF

$ cat mycat.txt
Hello cat.
key key key

$

This remembered me that <<'EOF' is something interpreted by bash. Hence, the following works as well:

$ ./mycat mycat.txt <<'EOF'
Hello World.
tip tip tip
EOF

$ cat mycat.txt 
Hello World.
tip tip tip

$ 

This let me belief that cat works quite similar though it takes input file(s) as argument(s) and writes to stdout (which in turn might be re-directed when calling it in a shell). In opposition to mine, cat doesn't fail if no arguments are provided – it reads from stdin instead.

Upvotes: 1

Related Questions