开发者

changing a program in c, so it takes an optional command line argument *infile*

Now I do have a hw question for everyone...I've been staring at this 开发者_运维百科for a couple of days kind of tinkering and playing around but even with that I end up with a load of errors...

What I'm trying to do is take the program below and change it so that it takes an optional command line argument infile. If infile is given, then copy infile to standard output, otherwise copy standard input to standard output as before.

The trick about this is that the solution must use the original copy loop (lines 9-11) for both cases. One can only insert code, and not change any of the existing code. Any help would be great. Thanks.

/* $begin cpfile */
include "csapp.h"
int main(int argc, char **argv)
{
    int n;
    rio_t rio;
    char buf[MAXLINE];

    Rio_readinitb(&rio, STDIN_FILENO);                  //line 9
    while((n = Rio_readlineb(&rio, buf, MAXLINE)) != 0) //line 10
        Rio_writen(STDOUT_FILENO, buf, n);              //line 11
        /* $end cpfile */
        exit(0);
        /* $begin cpfile */
    }
/* $end cpfile */


C programs get command line arguments through the two arguments to main(), traditionally called argc and argv (for argument count and argument vector, respectively).

Arguments are not "named" anything, they're just strings.

A solution for you could look like this:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, char *argv[])
{
    int fileno;
    /* ... your definitions should remain here, too */

    if(argc > 1)
    {
       /* Assume first argument is filename, and open it. */
       fileno = open(argv[1], O_RDONLY);
       if(fileno < 0)
       {
         printf("Unable to open file, aborting\n");
         return 1;
       }
    }
    else
      fileno = STDIN_FILENO;

  /* ... your code goes here ... */
}

Then you'd of course need to change the call to Rio_readinitb() to use the fileno variable for the file descriptor.

If you literally can't change that line, for whatever reason ... I guess you can use the preprocessor to make the symbol evaluate to the new variable name:

#undef  STDIN_FILENO
#define STDIN_FILENO fileno

This is of course not exactly pretty, but should work.

Make sure you put those preprocessor macros after the fileno = STDIN_FILENO; line.


You can insert dup2 before the lines 9 - 11 and it seems that you will not need change code on the lines 9 - 11. This is an example.

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>


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

    int file_handle;
    int dup2_res;
    if (argc == 2) {
        file_handle = open(argv[1], O_RDONLY);
        dup2_res = dup2 (file_handle, STDIN_FILENO);
    }

    char buffer[100];
    ssize_t read_bytes = 1;
    while (read_bytes)
    {
        read_bytes = read(STDIN_FILENO, &buffer, sizeof(buffer) );
        buffer[read_bytes] = 0;
        printf("%s", buffer);
    }
    close(file_handle);

    return 0;
}


If STDIN_FILENO cannot be reassigned, it sounds like a task for freopen():

freopen(argv[1], "r", stdin);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜