getopt 短选项实现(部分)

因为要在stm32上用,所以自己实现了一个简单的。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/**获取字符串选项及参数
*@Note	需连续调用该函数返回-1后才可以重新解析新的字符串,或者置buf=NULL,开始新的解析
*@param optarg:返回参数
*@param buf:输入字符串选项及参数,eg -d 1 -s abc -t 0 -g
*	buf=NULL时,结束解析,以便进行新的解析
*@param optstring:待处理的选项字符串,如: "ab:cd"
*@return	解析正确返回支持的选项,解析失败返回-1.解析结束返回0
*	1. 	"d:"	buf[]="-d" 		丢失参数
*	2.	"d"		buf[]="-dx"		选项不匹配,多字符
*	3.	"d"		buf[]="-x 1"	选项不匹配
*	4.	"d"		buf[]="- d"		无选项
*	5.	解析结束
*/
char getopt(char** optarg, char* buf, const char *optstring)
{
	static char *argv[100]={NULL};
	static unsigned int i=0;	//本次搜索结束或者出现错误选项返回,则i=0;可以重新搜索
	unsigned int k=0;
	unsigned int j=0;
    	if(buf == NULL){	//结束搜索,以便进行新的字符串解析
		memset(argv,0, 100);
		i=0;
		return 0;
	}
	//第一次调用该函数分割buf字符串	
	if(i==0){	
		argv[i++] = strtok(buf," ");
		while((argv[i++] = strtok(NULL," "))!=NULL);
		i=0;
	}
    
	if(argv[i] == NULL){	//搜索结束
	      i=0;
            memset(argv,0, 100);
		return 0;
	}
	if((argv[i][k++] == '-') && (argv[i][k] !='\0')){	//eg:-d\0
			
			for(j=0; optstring[j] != '\0'; j++){
				if(argv[i][k] == optstring[j]){			//match 选项
					break;
				}
			}
			if((optstring[j]) == '\0'){				//no match选项
					printf("invalid cmd \r\n");
					i=0;
					return -1;
			}
			if(argv[i][k+1] != '\0'){						//无效选项,选项为多字符,eg:-dx\0,	
					printf("invalid cmd \r\n");
					i=0;
					return -1;
				}
				//以下为有效选项:argv[0][k+1]=='\0'	
			i++;	//移到下一字符串
			if((optstring[j+1]) == ':'){	//应有参数				
					*optarg = argv[i];
					if((*optarg == NULL) || (*optarg)[0] == '-'){	//但无参数,eg:-d 后为NULL 或 -d -s
						printf("%c: lost argument \r\n", optstring[j]);
						i=0;
						return -1;
					}else{										//有参数
						i++;		//移到下一字符串
						return optstring[j];								
					}				
			}
			else{												//不需要参数
				*optarg = NULL;
				return optstring[j];		
			}		
	}
	i=0;
	return -1;
}
#if 0
void main()
{	
    char* optarg=NULL;
    char opt;
    char buf[128] = "-l qwd -d 1 -q         -w      350 -e -s";
    while((opt = getopt(&optarg, buf, "d:s:l:qw:e"))!=-1){
        printf("%c: %s\n", opt, optarg);
    }
    memset(buf, 0, 128);
    memcpy(buf, "-l   qwd  -d  1",15  );
    while((opt = getopt(&optarg, buf, "d:s:l:qw:e"))!=-1){
        printf("%c: %s\n", opt, optarg);
    }
}
#endif

void main()
{
//    char buf[128] = "       ads  bc d  ";
    int i=0;
    char*p;
    char buf[128] = " ads qwd iuy    ";
    printf("start:%s_end\n", buf);
    for(i=0; i<20; i++){
    printf("%d:%c_end\n",i, buf[i]);
    }
    p=strtok(buf," ");
    printf("start:%s_end\n", p);
    for(i=0; i<20; i++){
    printf("%d:%c_end\n",i, buf[i]);
    }


    p= strtok(NULL," ");
    printf("start:%s_end\n", p);
    for(i=0; i<20; i++){
    printf("%d:%c_end\n",i, buf[i]);
    }

    printf("===============\n");
    char* p1=p;
    p=strtok(p1," ");
    printf("start:%s_end\n", p);
    for(i=0; i<20; i++){
    printf("%d:%c_end\n",i, buf[i]);
    }

    p=strtok(p," ");
    printf("start:%s_end\n", p);
    for(i=0; i<20; i++){
    printf("%d:%c_end\n",i, buf[i]);
    }

    p=strtok(NULL," ");
    printf("start:%s_end\n", p);
    for(i=0; i<20; i++){
    printf("%d:%c_end\n",i, buf[i]);
    }
}


csl-B85M-D3V:~/test$ ./test4
l: qwd
d: 1
q: (null)
w: 350
e: (null)
s: lost argument


l: qwd
d: 1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值