[英]getopt() in C not working correctly after if statement
我想實現 Linux 方法頭命令的副本。 如果用戶輸入./cprogram head -(option here)
我希望該選項出現,但由於某種原因,我的代碼從不輸入選項switch
語句。 例如命令行代碼./cprogram head -n
從不進入case 'n':
語句。 該代碼在if
語句之前運行以檢查argv[1]
是否為"head"
。
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv) {
int b;
int c;
int nflag = 0;
int Vflag = 0;
int hflag = 0;
int eflag = 0;
int oflag = 0;
char str[] = "head";
if (strcmp(argv[1], str) == 0) {
while ((c = getopt(argc, argv, "nVheo")) != -1) {
switch (c) {
case 'n':
if (nflag||Vflag||hflag||eflag||oflag) {
printf("only one option\n");
exit(1);
} else {
nflag++;
printf("n option\n");
}
break;
case 'V':
if (nflag||Vflag||hflag||eflag||oflag) {
printf("only one option\n");
exit(1);
} else {
Vflag++;
}
break;
case 'h':
if (nflag||Vflag||hflag||eflag||oflag) {
printf("only one option\n");
exit(1);
} else {
hflag++;
}
break;
case 'e':
if (nflag||Vflag||hflag||eflag||oflag) {
printf("only one option\n");
exit(1);
} else {
eflag++;
}
break;
case 'o':
if (nflag||Vflag||hflag||eflag||oflag) {
printf("only one option\n");
exit(1);
} else {
oflag++;
}
break;
default:
printf("invalid options\n");
abort();
}
}
} else {
}
}
我將非常感謝專家的眼睛來看看並發現我所缺少的東西。 提前致謝。
結合頂部評論中的所有建議:
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
main(int argc, char **argv)
{
int b;
int c;
int nflag = 0;
int Vflag = 0;
int hflag = 0;
int eflag = 0;
int oflag = 0;
char str[] = "head";
if (argc < 2) {
printf("not enough arguments\n");
exit(1);
}
if (strcmp(argv[1], str) != 0) {
printf("1st argument is not '%s'\n",str);
exit(1);
}
// skip over the [matched] str
--argc;
++argv;
while ((c = getopt(argc, argv, "nVheo")) != -1) {
if (nflag || Vflag || hflag || eflag || oflag) {
printf("only one option\n");
exit(1);
}
switch (c) {
case 'n':
nflag++;
printf("n option\n");
break;
case 'V':
Vflag++;
break;
case 'h':
hflag++;
break;
case 'e':
eflag++;
break;
case 'o':
oflag++;
break;
default:
printf("invalid options\n");
abort();
break;
}
}
return 0;
}
要進行測試,請使用這些 [a shell 腳本test
] 調用:
./myprogram
./myprogram foo
./myprogram head
./myprogram head -n
./myprogram head -n -n
這是sh -x./test
output:
+ ./myprogram
not enough arguments
+ ./myprogram foo
1st argument is not 'head'
+ ./myprogram head
+ ./myprogram head -n
n option
+ ./myprogram head -n -n
n option
only one option
更新:
上面的代碼有點“作弊”。 它通過將str
(例如"head"
)移動到作為程序名稱(例如./myprogram
)的argv[0]
中來消除它。 實際的程序名稱被丟棄。
更正確的方法是“滑動” argv
以消除字符串並保留程序名稱:
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
main(int argc, char **argv)
{
int b;
int c;
int nflag = 0;
int Vflag = 0;
int hflag = 0;
int eflag = 0;
int oflag = 0;
char str[] = "head";
if (argc < 2) {
printf("not enough arguments\n");
exit(1);
}
if (strcmp(argv[1], str) != 0) {
printf("1st argument is not '%s'\n",str);
exit(1);
}
// skip over the [matched] str
for (int avidx = 1; avidx < argc; ++avidx)
argv[avidx] = argv[avidx + 1];
--argc;
while ((c = getopt(argc, argv, "nVheo")) != -1) {
if (nflag || Vflag || hflag || eflag || oflag) {
printf("only one option\n");
exit(1);
}
switch (c) {
case 'n':
nflag++;
printf("n option\n");
break;
case 'V':
Vflag++;
break;
case 'h':
hflag++;
break;
case 'e':
eflag++;
break;
case 'o':
oflag++;
break;
default:
printf("invalid options\n");
abort();
break;
}
}
return 0;
}
要讓getopt()
跳過argv[1]
並從下一個元素解析選項,您應該在調用getopt()
之前設置optind
:
optind = 2;
另請注意,在將argv[1]
與"head"
進行比較之前,您還應該檢查argc > 1
。
這是修改后的版本:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char **argv) {
int b;
int c;
int nflag = 0;
int Vflag = 0;
int hflag = 0;
int eflag = 0;
int oflag = 0;
char str[] = "head";
if (argc > 1 && strcmp(argv[1], str) == 0) {
optind = 2; // skip argv[1]
while ((c = getopt(argc, argv, "nVheo")) != -1) {
if (nflag | Vflag | hflag | eflag | oflag) {
fprintf(stderr, "only one option\n");
exit(1);
}
switch (c) {
case 'n':
nflag++;
printf("n option\n");
break;
case 'V':
Vflag++;
break;
case 'h':
hflag++;
break;
case 'e':
eflag++;
break;
case 'o':
oflag++;
break;
default:
fprintf(stderr, "invalid option `%c'\n", c);
abort();
}
}
/* perform head on files starting at argv[optind] */
} else {
/* test some other command */
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.