LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 11-20-2006, 10:57 AM   #1
schneidz
LQ Guru
 
Registered: May 2005
Location: boston, usa
Distribution: fedora-35
Posts: 5,313

Rep: Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918
creating c programs to accpet data from a pipe - '|'


hi lq,
i have this c program:
Code:
schneidz@lq> cat columnate.c
#include <string.h>
#include <stdio.h>

main(int argc, char * argv[])
{
 printf("     %-20s %29s %30s\n", argv[1], argv[2], argv[3]);
}
it runs fine but when i try to run it after a pipe i get this weird output:
Code:
schneidz@lq> columnate.x hello world
     hello                                        world
schneidz@lq> echo hello world | columnate.x
                                          _=columnate.x MANPATH=/opt/vintela/vgp/man:/opt/vas/man:/usr/share/man:/usr/share/man/info/en_US/a_doc_lib/cmds:/usr/share/man/info:/usr/lpp/X11/Xamples/man:/usr/lpp/ssp/perl/man:/usr/lpp/ssp/perl5/lib/man:/usr/lpp/ssp/perl5/man:/usr/lpp/ssp/man:/usr/lpp/perfrep/man:/usr/share/man:/usr/dt/man:/usr/nsr/nsr_extract/man:/usr/OV/man
can somebody tell me how do i make my code accept input from a pipe ?

thanks much,
~schneidz

Last edited by schneidz; 11-20-2006 at 11:01 AM.
 
Old 11-20-2006, 11:43 AM   #2
m0rg
Member
 
Registered: Jun 2003
Location: France
Distribution: slackware 11.0
Posts: 80

Rep: Reputation: 15
I'm not sure right now, but I think that reading from a pipe is just reading from stdin. So I guess you just have to get you arguments from stdin instead of argv.

You can probably just test if there are any arguments provided on the command line, if not then read them from stdin and output like you already do.

Hope this helps
 
Old 11-20-2006, 11:57 AM   #3
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 78
Quote:
Originally Posted by schneidz
hi lq,
i have this c program:
Code:
schneidz@lq> cat columnate.c
#include <string.h>
#include <stdio.h>

main(int argc, char * argv[])
{
 printf("     %-20s %29s %30s\n", argv[1], argv[2], argv[3]);
}
it runs fine but when i try to run it after a pipe i get this weird output:
Code:
schneidz@lq> columnate.x hello world
     hello                                        world
schneidz@lq> echo hello world | columnate.x
                                          _=columnate.x MANPATH=/opt/vintela/vgp/man:/opt/vas/man:/usr/share/man:/usr/share/man/info/en_US/a_doc_lib/cmds:/usr/share/man/info:/usr/lpp/X11/Xamples/man:/usr/lpp/ssp/perl/man:/usr/lpp/ssp/perl5/lib/man:/usr/lpp/ssp/perl5/man:/usr/lpp/ssp/man:/usr/lpp/perfrep/man:/usr/share/man:/usr/dt/man:/usr/nsr/nsr_extract/man:/usr/OV/man
can somebody tell me how do i make my code accept input from a pipe ?

thanks much,
~schneidz
A pipe redirects output to stdin (fd 0). To get the desired effect (changing command-line-arguments) use xargs (i.e., echo "hello world" | xargs columnate.x).
 
1 members found this post helpful.
Old 11-20-2006, 01:11 PM   #4
matthewg42
Senior Member
 
Registered: Oct 2003
Location: UK
Distribution: Kubuntu 12.10 (using awesome wm though)
Posts: 3,530

Rep: Reputation: 65
Firstly, your program is using command line arguments without first checking if they exist. This is why you get the junk output. When you use argv[n] you must check that you're not using more values in argv than it has in it, else you'll get pointers to something random, probably causing junk output like you get,m or maybe a segmentation fault (and your program crashing horribly).

If you want to print the command line arguments, you might do it like this:
Code:
#include <stdio.h>

int main(int argc, char **argv)
{
    int i;
    for (i = 1; i < argc; i++) {
        printf("%s ", argv[i]);
    }
    printf("\n");

    return 0;
}
Note that this has nothing to to with reading from a pipe! When you start a program from the shell like this:
Code:
wibble | wobble
...this means that the output of wibble (from the standard output file descriptor, 1) is connected to the input of wobble (the standard input file descriptor, 2). This has nothing to do with command line options.

In wobble, you would use the I/O function to read from the standard input file descriptor. There are many functions for doing this. If you want to get one character at a time, you might use fgetc, or one of it's friends, getc or getchar. There are several IO routines which may be suitable depending on the task. Here's an example wobble.c which changes all lower case letters to upper case letters and sends the output to standard output (which could then be piped into another process if you like).
Code:
#include <stdio.h>

int main(int argc, char **argv)
{
    int c;
    while ((c = getchar()) != EOF) {
        if (c >= 'a' && c <= 'z') {
            c -= 32;
        }
        putchar(c);
    }

    return (0);
}
 
1 members found this post helpful.
Old 11-20-2006, 02:00 PM   #5
schneidz
LQ Guru
 
Registered: May 2005
Location: boston, usa
Distribution: fedora-35
Posts: 5,313

Original Poster
Rep: Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918
thanks guys, i understand now:
Code:
schneidz@lq> cat columnate-2.c
#include <string.h>
#include <stdio.h>

main(int argc, char * argv[])
{
 char arg1[50], arg2[50];
 scanf("%s", &arg1);
 scanf("%s", &arg2);
 printf("     %-20s %29s %30s\n", arg1, arg2);
}
schneidz@lq> echo hello world | columnate.x
     hello                                        world
i also tried xorgs and that is more an ideal solution (less re-coding/ compiling)
i love options... give me money
 
Old 11-20-2006, 02:21 PM   #6
matthewg42
Senior Member
 
Registered: Oct 2003
Location: UK
Distribution: Kubuntu 12.10 (using awesome wm though)
Posts: 3,530

Rep: Reputation: 65
Yes, you can use scanf, but beware! Your program has a security flaw! If someone passes an argument which is bigger than the sizes you have statically allocated to arg1 and arg2 (minus one character because a \0 is automatically appended by scanf), a buffer over-run will occur!
 
Old 11-20-2006, 02:36 PM   #7
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 78
Quote:
Originally Posted by matthewg42
...this means that the output of wibble (from the standard output file descriptor, 1) is connected to the input of wobble (the standard input file descriptor, 2). This has nothing to do with command line options.
It connects to file descriptor 0 (stdin).


Quote:
Originally Posted by schneidz
i also tried xorgs and that is more an ideal solution (less re-coding/ compiling)
i love options... give me money
WTF is xorgs?
 
Old 11-20-2006, 02:36 PM   #8
matthewg42
Senior Member
 
Registered: Oct 2003
Location: UK
Distribution: Kubuntu 12.10 (using awesome wm though)
Posts: 3,530

Rep: Reputation: 65
Oh, by the way, you can prevent the over-run by specifying the maximum length of the input string to scanf like this:
Code:
scanf("%49s", arg1);
The number should be one less than the size you statically allocated to the char* because scanf appends \0 as the end of string marker.
 
Old 11-21-2006, 08:43 AM   #9
schneidz
LQ Guru
 
Registered: May 2005
Location: boston, usa
Distribution: fedora-35
Posts: 5,313

Original Poster
Rep: Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918Reputation: 918
Quote:
Originally Posted by osor
...
WTF is xorgs?
whoops, i meant xargs
 
Old 11-21-2006, 09:16 AM   #10
matthewg42
Senior Member
 
Registered: Oct 2003
Location: UK
Distribution: Kubuntu 12.10 (using awesome wm though)
Posts: 3,530

Rep: Reputation: 65
xorgs is something women are suppose to have, no?
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
creating pipe! sahel Programming 1 01-06-2006 02:48 PM
Clonning data, fifo/pipe/tee problem : Resource temporarily unavailable rmarco Linux - General 2 05-05-2005 11:15 AM
Creating shortcuts to programs piggysmile Linux - Software 3 05-27-2004 08:43 AM
Suse Standard Server wont accpet user logins pshepperd Linux - Software 2 01-13-2004 03:19 PM
Broken pipe error when sending data on LAN Tanc Linux - Networking 2 09-14-2003 05:16 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 12:10 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration