嗨,我正在编写一个简单的客户端-服务器程序。在这个程序中,我必须使用getopt()
来获取端口号和IP地址,像这样:
server -i 127.0.0.1 -p 10001
我不知道如何从optarg获取值,以便稍后在程序中使用。
#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;
}
char buf[BUFSIZE+1];
snprintf(buf,BUFSIZE,"%s",optarg);
或者更完整的示例:
#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;
}
如需更多信息,请参阅Getopt文档。
这是getopt文档中的一个缺陷之一:它没有清楚地说明必须复制optarg以供后续使用(例如使用strdup()),因为它可能会被后续选项覆盖或仅由getopt释放。
char **
,但它是char *
。可证明optarg指向argv元素指向的字符串之一。(这些字符串再次存储在glibc中的连续内存块中,我怀疑这个连续的char数组就是那些glibc文档所指的“原始argv数组”,它并不指代main()的参数数组中的指针数组) - nos对于IP和端口,您无需存储字符串。只需解析它们并将值存储在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 ---------- */
strdup
会导致内存泄漏。因此,在您的示例中,您需要释放addr
和port
。 - codenamezero