linux 解析命令行参数的例子
下面是一个把文件转数组的小程序
#include "stdio.h"
#include <string.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <getopt.h>
#include <errno.h>
#include "string.h"
#include "stdint.h"
#include "fcntl.h"
#include "unistd.h"
#define LEN_HINT 512
#define LEN_OPTION_SHORT 512
#define DEV_STR_LEN 10
const char *inputFileName=NULL;
const char *outputFileName=NULL;
const char *outArrayName =NULL;
uint64_t needLen=0;
uint32_t get_file_size(char *file_name);
const char *ac_option_hint[]={
"帮助",
"指定输入文件名",
"指定输出文件名",
"要截取的长度,可以为空",
"输出文件里面数组的名字",
""
};
static struct option option_long[ ] = {
{ "help" , no_argument , NULL , 'h' } , //" 打印帮助信息" ,
{"input", required_argument,NULL,'i' },
{"output", required_argument,NULL,'o' },
{"len", optional_argument,NULL,'l' },
{"arrayname", optional_argument,NULL,'a' },
{0, 0, 0, 0}
};
static int help_hint( char *pc_prog_name )
{
int i;
printf( "usage: \r\n %s [options] <value>\n\n", pc_prog_name);
printf( "options: \r\n");
for(i = 0; i < sizeof(option_long) / sizeof(struct option) - 1; i ++)
{
printf(" -%c,--%-16s\t%s \n" , option_long[ i ].val , option_long[ i ].name , ac_option_hint[ i ]);
}
printf( "\nexample: \r\n"
" %s -i in.txt -o out .txt -aarr1 -l100\n", pc_prog_name);
printf("\n\n");
return 0;
}
static char *get_option_short( struct option *p_option, int i_num_option, char *pc_option_short,
int i_len_option )
{
int i;
int i_offset = 0;
char c_option;
for( i = 0 ; i < i_num_option ; i ++ )
{
c_option = p_option[ i ].val;
switch( p_option[ i ].has_arg )
{
case no_argument:
i_offset += snprintf( pc_option_short + i_offset , i_len_option - i_offset , "%c" , c_option );
break;
case required_argument:
i_offset += snprintf( pc_option_short + i_offset , i_len_option - i_offset , "%c:" , c_option );
break;
case optional_argument:
i_offset += snprintf( pc_option_short + i_offset , i_len_option - i_offset , "%c::" , c_option );
break;
}
}
return pc_option_short;
}
static int parse_option( int argc, char **argv )
{
int i_option;
char ac_option_short[ LEN_OPTION_SHORT ];
int i_array_num = sizeof( option_long ) / sizeof( struct option ) ;
char c_flag = 1;
if (argc < 2 && argc != 1)
{
help_hint( argv[ 0 ] );
c_flag = 0;
goto parse_option_end;
}
#ifdef AK_RTOS
optind = 0;
#endif
get_option_short( option_long, i_array_num , ac_option_short , LEN_OPTION_SHORT );
//getopt可以解析短参数,所谓短参数就是指选项前只有一个“-”(如-t),而getopt_long则支持短参数跟长参数(如"--prefix")。
while((i_option = getopt_long(argc , argv , ac_option_short , option_long , NULL)) > 0)
{
switch(i_option)
{
case 'h' : //help
help_hint( argv[ 0 ] );
c_flag = 0;
goto parse_option_end;
case 'i' :
inputFileName=optarg;
break;
case 'o' :
outputFileName=optarg;
break;
case 'l' :
// printf("case l :%s\n",optarg);
if(optarg)
needLen = atol( optarg );
break;
case 'a' :
if(optarg)
outArrayName = optarg;
break;
case 'v' :
// volume = atoi( optarg );
break;
case 'd':
// dev_sel = atoi( optarg );
break;
case 'p' :
// save_path = optarg;
break;
}
}
parse_option_end:
return c_flag;
}
int POSIX_file_ops(const char *inFileName,const char *outFileName,uint64_t needLen);
int stdc_file_ops(const char *inputFileName,const char *outputFileName,uint64_t needLen);
int main(int argc, char** argv)
{
uint64_t inFileSize=0;
if(0 == parse_option(argc,argv)){
return -1;
}
inFileSize =get_file_size(inputFileName );
if(needLen==0)
needLen = inFileSize;
printf("in:%s(%lu) out:%s len %ld\n",inputFileName,inFileSize,outputFileName,needLen);
if(!inFileSize){
printf("null input file!\n");
return -1;
}
return stdc_file_ops(inputFileName,outputFileName,needLen);
// return POSIX_file_ops(inputFileName,outputFileName,needLen);
return 0;
}
uint32_t get_file_size(char *file_name)
{
struct stat buf;
if(stat(file_name, &buf) < 0)
{
return 0;
}
return (uint32_t)buf.st_size;
}
#define INCLUDE_FILE_STR "#include <stdint.h>\n"
int POSIX_file_ops(const char *inFileName,const char *outFileName,uint64_t needLen)
{
uint64_t arraysize=0;
unsigned char buf[1024];
int inFile = -1;
int outFile= -1;
int len = 0;
printf("using POSIX API.\n");
inFile = open(inputFileName,O_RDONLY);
outFile = open(outputFileName, O_WRONLY|O_CREAT,0666);
if (inFile<0 || outFile<0) {
printf("open file failed!\n");
exit(-1);
return -1;
}
memset(buf,0,sizeof(buf));
sprintf((char*)buf,"//extern const uint8_t %s[%lu];\nconst uint8_t %s[%lu]={\n",
outArrayName?outArrayName:"arr",needLen,outArrayName?outArrayName:"arr",needLen);
// fprintf(outFile,"#include <stdint.h>\n");
write(outFile,INCLUDE_FILE_STR,strlen(INCLUDE_FILE_STR));
// fwrite(buf, 1, strlen((char*)buf), outFile);
write(outFile,buf,strlen((char*)buf));
while (1) {
int writeBytes = 0;
memset(buf,0,sizeof(buf));
len = read(inFile,buf,sizeof(buf) );
// printf("read %d bytes\n",len);
if (len <= 0)
break;
for (size_t i = 0; i < len; i++) {
char buffer[10];
memset(buffer,0,sizeof(buffer));
sprintf(buffer,"0x%0X,",buf[i]);
write(outFile,buffer,strlen((char*)buffer) );
// fprintf(outFile,"0x%0X,",buf[i]);
if(i && (i %16 ==0)){
char c='\n';
// fwrite(&c,1,1,outFile);
write(outFile,&c,1 );
}
++arraysize;
if(arraysize>= needLen)
goto out;
}
}
out:
memset(buf,0, sizeof(buf));
sprintf((char*)buf, "\n};\n");
// fwrite(buf, 1, strlen((char*)buf), outFile);
write(outFile,buf,strlen((char*)buf) );
close(inFile);
close(outFile);
return 0;
}
int stdc_file_ops(const char *inputFileName,const char *outputFileName,uint64_t needLen)
{
int len = 0;
uint64_t arraysize=0;
unsigned char buf[1024];
FILE* inFile = NULL;
FILE* outFile= NULL;
printf("using STD C API.\n");
inFile = fopen(inputFileName,"r");
outFile = fopen(outputFileName, "wb+");
if (!inFile || !outFile) {
printf("open file failed!\n");
exit(-1);
return -1;
}
memset(buf,0,sizeof(buf));
sprintf((char*)buf,"//extern const uint8_t %s[%lu];\nconst uint8_t %s[%lu]={\n",
outArrayName?outArrayName:"arr",needLen,outArrayName?outArrayName:"arr",needLen);
fprintf(outFile,"#include <stdint.h>\n");
fwrite(buf, 1, strlen((char*)buf), outFile);
while (1) {
int writeBytes = 0;
memset(buf,0,sizeof(buf));
len = fread(buf, 1, sizeof(buf), inFile);
// printf("read %d bytes\n",len);
if (len <= 0)
break;
for (size_t i = 0; i < len; i++) {
fprintf(outFile,"0x%0X,",buf[i]);
if(i && (i %16 ==0)){
char c='\n';
fwrite(&c,1,1,outFile);
}
++arraysize;
if(arraysize>= needLen)
goto out;
}
}
out:
memset(buf, 0, sizeof(buf));
sprintf((char*)buf, "\n};\n");
fwrite(buf, 1, strlen((char*)buf), outFile);
fclose(inFile);
fclose(outFile);
return 0;
}