Solved

C command line parsing

Posted on 2012-03-17
19
370 Views
Last Modified: 2012-03-17
I am attaching my code and I would like to take the command line argument and put it into buff.  I would like an example on how to get that done.  It seems to me it should not take to many lines of code to do it.  I need to change the line that assigns "Now is the time for all good men" to buff so it will have the info from the command line argument.  Do I just need to change the line in the for statement to assign the command line argument to buff rather than just print it?  Thanks.


    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <termios.h>
    int main(int argc, char *argv[])
    {
    int fd;
    int wd=0;
   
    speed_t baud = B9600; /* baud rate */  

    //unsigned char buff[] = { 0x02, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x23, 0x01, 0x21, 0x03};
    unsigned char buff[] = "Now is the time for all good men\n\r";

    int x;
    for (x=0; x<argc; x++)
      printf("%s\n",argv[x]);
   
    fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY );
    if (fd == -1)
    {     fprintf(stderr, "open_port: Unable to open /dev/ttyS0 - %s\n",
                            strerror(errno));
    }
    else
    {
     
      struct termios settings;
      tcgetattr(fd, &settings);

      cfsetospeed(&settings, baud); /* baud rate */
      settings.c_cflag &= ~PARENB; /* no parity */
      settings.c_cflag &= ~CSTOPB; /* 1 stop bit */
      settings.c_cflag &= ~CSIZE;
      settings.c_cflag |= CS8 | CLOCAL; /* 8 bits */
      settings.c_lflag = ICANON; /* canonical mode */
      settings.c_oflag &= ~OPOST; /* raw output */

      tcsetattr(fd, TCSANOW, &settings); /* apply the settings */
      tcflush(fd, TCOFLUSH);      
     
     
      printf("%d", fd); //i get fd value to be 3
      fcntl(fd, F_SETFL, 0);
      wd=write(fd, buff, strlen(buff));
    }
      printf("%d", wd); //i get wd to be -1, so what is the problem??
      close(fd);
      return 61;
    }
0
Comment
Question by:sargent240
  • 10
  • 7
  • 2
19 Comments
 
LVL 86

Expert Comment

by:jkr
Comment Utility
I assume you want to put the complete command line (i.e. all arguments instead of the image name itself info 'buff'? that would be like

#include <memory.h> // for 'malloc()'

//...

unsigned char* buff; // a pointer,memory will be allocated dynamically

    size_t sz = 0; // to cont the length of all arguments
    int x;
    for (x=1; x<argc; x++)
      sz += strlen(argv[i]) + 1; // plus a separating space

    buff = (unsigned char*) malloc(sz + 1); // plus the NULL terminator
    *buff = '\0';

    for (x=1; x<argc; x++) {
      strcat(buff,argv[i]);
      if (x < argv - 1) strcat(buff," "); // also add a blank seperator to all but the last arg
    }

// rest of your code

    free(buff); // free the memory again

Open in new window

0
 
LVL 19

Expert Comment

by:n2fc
Comment Utility
see:  http://einstein.drexel.edu/courses/Comp_Phys/General/C_basics/#command-line

char buff[2000]="";

for (int x=1;  x<argc;  x++)
      strcat(buff, argv[x]);

Open in new window


Note:

1. The loop starts at 1 to SKIP the command itself; start at 0 to include it!

2. The arguments will be concatenated with NO separators.

3. Make sure to allocate an appropriate buffer size, or it may overflow!

0
 

Author Comment

by:sargent240
Comment Utility
Thank YOU!

This is my present code and when I compile it is get a warning:

al@linux-5t7y:~> gcc serialInC.c
serialInC.c: In function ‘main’:
serialInC.c:32:29: warning: incompatible implicit declaration of built-in function ‘malloc’ [enabled by default]                                    
serialInC.c:37:13: warning: comparison between pointer and integer [enabled by default]                                                            


I must have screwed up somewhere along the line
0
 
LVL 19

Expert Comment

by:n2fc
Comment Utility
You will need to post FULL source code to debug the inappropriate use of malloc()...
Probably a typo...

Note that if your command line size is limited, it is unnecessary to use malloc to allocate the buffer!   A buffer slightly larger than the command line is all that is needed!  (See my example above)...
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
Sorry, typo on my side, that should have been

    for (x=1; x<argc; x++) {
      strcat(buff,argv[i]);

      // argc, not argv as in my 1st comment
      if (x < argc - 1) strcat(buff," "); // also add a blank seperator to all but the last arg
    }

Open in new window

0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
BTW, using a static buffer size here is possible - yet then it's always possible to crash your program.
0
 

Author Comment

by:sargent240
Comment Utility
I posted the source and error message a moment ago.  Did you get It?  Thanks
0
 

Author Comment

by:sargent240
Comment Utility
let me try it this way.  File attached.serialInC.c

al@linux-5t7y:~> gcc serialInC.c
serialInC.c: In function ‘main’:
serialInC.c:32:29: warning: incompatible implicit declaration of built-in function ‘malloc’ [enabled by default]
serialInC.c:72:7: warning: incompatible implicit declaration of built-in function ‘free’ [enabled by default]
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
Nope - as you can see, there's nothing ;o)
0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 

Author Comment

by:sargent240
Comment Utility
you should have it on this last post.
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
Yes, sorry, that was about the same time. Try replacing 'memory.h' with 'stdlib.h'
0
 

Author Comment

by:sargent240
Comment Utility
the compile error is gone but when I execute it I get a Seg fault.
0
 

Author Comment

by:sargent240
Comment Utility
I execute it with this command:

./a.out This works
0
 

Author Comment

by:sargent240
Comment Utility
You mentioned in an earlier post that the line;

char buff[2000]="";

should be added some where but as you can see I added:

char buff[256]="";

but that gave me a compiler error about a duplicate declaration.
0
 
LVL 86

Accepted Solution

by:
jkr earned 500 total points
Comment Utility
Hmm, I tried

#include <stdlib.h> // for 'malloc()'

//...

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

unsigned char* buff; // a pointer,memory will be allocated dynamically

    size_t sz = 0; // to cont the length of all arguments
    int x;
    for (x=1; x<argc; x++)
      sz += strlen(argv[x]) + 1; // plus a separating space

    buff = (unsigned char*) malloc(sz + 1); // plus the NULL terminator
    *buff = '\0';

    for (x=1; x<argc; x++) {
      strcat(buff,argv[x]);
      if (x < argc - 1) strcat(buff," "); // also add a blank seperator to all but the last arg
    }

// rest of your code

    free(buff); // free the memory again

    return 0;
}                                            

Open in new window


and that compiles and runs fine - strange.
0
 

Author Comment

by:sargent240
Comment Utility
did you try to compile and run the code I posted last?
0
 

Author Comment

by:sargent240
Comment Utility
I found the problem.  In our original post you used the variable i in two places where it should have been x.  I'll put my code back in again and let you know.
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
Well, that I saw also, yet I assumed you had fixed it, since it wouldn't compile otherwise. And no, unfortunately I can't try your original code at the moment.
0
 

Author Closing Comment

by:sargent240
Comment Utility
Good, Good, Good.
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

This article is meant to give a basic understanding of how to use R Sweave as a way to merge LaTeX and R code seamlessly into one presentable document.
A short article about problems I had with the new location API and permissions in Marshmallow
In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now