How to get a value from optarg

佐手、 提交于 2019-11-30 12:19:53

问题


Hi I am writing a simple client-server program. In this program I have to use getopt() to get the port number and ip address like this:

server -i 127.0.0.1 -p 10001

I do not know how can I get values from optarg, to use later in the program.


回答1:


How about like this:

char buf[BUFSIZE+1];
snprintf(buf,BUFSIZE,"%s",optarg);

Or in a more complete example:

#include <stdio.h>
#include <unistd.h>

#define BUFSIZE 16

int main( int argc, char **argv )
{
    char c;
    char port[BUFSIZE+1];
    char addr[BUFSIZE+1];

    while(( c = getopt( argc, argv, "i:p:" )) != -1 )
        switch ( c )
        {
            case 'i':
                snprintf( addr, BUFSIZE, "%s", optarg );
                break;
            case 'p':
                snprintf( port, BUFSIZE, "%s", optarg );
                break;
            case '?':
                fprintf( stderr, "Unrecognized option!\n" );
                break;
        }

    return 0;
}

For more information see the documentation of Getopt.




回答2:


You use a while loop to move through all the arguments and process them like so ...

#include <unistd.h>

int main(int argc, char *argv[])
{
    int option = -1;
    char *addr, *port;

    while ((option = getopt (argc, argv, "i:p:")) != -1)
    {
         switch (option)
         {
         case 'i':
             addr = strdup(optarg);
             break;
         case 'p':
             port = strdup(optarg);
             break;
         default:
              /* unrecognised option ... add your error condition */
              break;
         }
    }

    /* rest of program */

    return 0;
}



回答3:


It is one of the numerous flaws of the getopt documentation: it does not state clearly that optarg must be copied for later use (using strdup(), for instance) because it may be overwritten by later options or just plain freed by getopt.




回答4:


In the case of an ip and port you don't need to store the strings. Just parse them and store the values in a sockaddr.

#include <arpa/inet.h>                  // for inet_ntop, inet_pton                                                                                                                                                                                                                                                                                                          
#include <getopt.h>                     // for getopt, optarg                                                                                                                                                                                                                                                                                                                
#include <netinet/in.h>                 // for sockaddr_in, etc                                                                                                                                                                                                                                                                                                              
#include <stdio.h>                      // for fprintf, printf, stderr                                                                                                                                                                                                                                                                                                       
#include <stdlib.h>                     // for atoi, EXIT_SUCCESS                                                                                                                                                                                                                                                                                                            
#include <string.h>                     // for memset                                                                                                                                                                                                                                                                                                                        
#include <sys/socket.h>                 // for AF_INET                                                                                                                                                                                                                                                                                                                       

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

    memset(&sa, 0, sizeof(sa));                                                                                                                                                                                                                                                                                                                                              
    sa.sin_family = AF_INET;                                                                                                                                                                                                                                                                                                                                                 
    sa.sin_addr.s_addr = htonl(INADDR_ANY);                                                                                                                                                                                                                                                                                                                                         
    sa.sin_port = 0;                                                                                                                                                                                                                                                                                                                                                         

    while ((c = getopt(argc, argv, "i:p:")) != -1)                                                                                                                                                                                                                                                                                                                           
    {                                                                                                                                                                                                                                                                                                                                                                        
        switch (c)                                                                                                                                                                                                                                                                                                                                                           
        {                                                                                                                                                                                                                                                                                                                                                                    
            case 'p':                                                                                                                                                                                                                                                                                                                                                        
                sa.sin_port = htons(atoi(optarg));                                                                                                                                                                                                                                                                                                                           
                break;                                                                                                                                                                                                                                                                                                                                                       
            case 'i':                                                                                                                                                                                                                                                                                                                                                        
                inet_pton(AF_INET, optarg, &(sa.sin_addr));                                                                                                                                                                                                                                                                                                                  
                break;                                                                                                                                                                                                                                                                                                                                                       
            case '?':                                                                                                                                                                                                                                                                                                                                                        
                fprintf(stderr, "Unknown option\n");                                                                                                                                                                                                                                                                                                                         
                break;                                                                                                                                                                                                                                                                                                                                                       
        } /* -----  end switch  ----- */                                                                                                                                                                                                                                                                                                                                     
    }                                                                                                                                                                                                                                                                                                                                                                        

    char str[INET_ADDRSTRLEN];                                                                                                                                                                                                                                                                                                                                               
    inet_ntop(AF_INET, &(sa.sin_addr), str, INET_ADDRSTRLEN);                                                                                                                                                                                                                                                                                                                
    printf("%s:%d\n", str, ntohs(sa.sin_port));                                                                                                                                                                                                                                                                                                                              

    return EXIT_SUCCESS;                                                                                                                                                                                                                                                                                                                                                     
} /* ----------  end of function main  ---------- */                                            


来源:https://stackoverflow.com/questions/1973742/how-to-get-a-value-from-optarg

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!