getopt_long_only return -1 第二次调用
getopt_long_only return -1 on second call
我正在为接受参数的过程编写 C++ 到 tcl 的转换。它使用 getop_long_only。我第一次能够加载创建的共享库和 运行。然而,我第二次调用时,getop_long_only 总是给我 -1,这导致 proc 出现故障。调用快照如下。我还包括代码部分。你能帮忙解释一下是怎么回事吗?
********************* 呼叫 ************************ ****
enter code here
$ tclsh
% load area.so area
% area --area --length 4.0 --breadth 4.0
OPT ==> 97
OPT ==> 108
OPT ==> 98
OPT ==> -1
Area0: 1
Perimeter0: 0
Length0: 4
Breadth0: 4
Area: 16
Area: 16
Perimeter: 0
% area --area --length 4.0 --breadth 5.0
OPT ==> -1
rea0: 0
Perimeter0: 0
Length0: -1
Breadth0: -1
-area: Return the area
-perimeter: Return the perimeter
-length <val>: Specify the length
-breadth <val>: Specify the width
-help: Show help
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <iostream>
#include <tcl.h>
// Program to calculate the area and perimeter of
// a rectangle using command line arguments
//----------------------------------------------------
void PrintHelp() {
std::cout <<
"-area: Return the area\n"
"-perimeter: Return the perimeter\n"
"-length <val>: Specify the length\n"
"-breadth <val>: Specify the width\n"
"-help: Show help\n";
exit(1);
}
// area --
// This implements the random Tcl command. With no arguments
// the command returns a random integer.
// With an integer valued argument "range",
// it returns a random integer between 0 and range.
//--------------------------------------------------------------
extern "C" int AreaCmd(ClientData clientData, Tcl_Interp *interp, int argc, const char **argv) {
int opt= 0;
int area = 0, perimeter = 0, breadth = -1, length =-1;
while (1) {
//Specifying the expected options
//The two options l and b expect numbers as argument
static struct option long_options[] = {
{"area", no_argument, 0, 'a' },
{"perimeter", no_argument, 0, 'p' },
{"length", required_argument, 0, 'l' },
{"breadth", required_argument, 0, 'b' },
{"help", no_argument, 0, 'h' },
{0, 0, 0, 0 }
};
int long_index =0;
char* const* new_argv = const_cast<char * const *>(argv);
opt = getopt_long_only(argc, new_argv,"", long_options, &long_index );
printf("OPT ==> %d\n",opt);
if (opt == -1) {
break;
}
switch (opt) {
case 'a' : area = 1;
break;
case 'p' : perimeter = 1;
break;
case 'l' : length = atoi(optarg);
break;
case 'b' : breadth = atoi(optarg);
break;
case 'h': // -h or --help
case '?': // Unrecognized option
default: PrintHelp();
exit(EXIT_FAILURE);
}
}
printf("Area0: %d\n",area);
printf("Perimeter0: %d\n",perimeter);
printf("Length0: %d\n",length);
printf("Breadth0: %d\n\n",breadth);
if (length == -1 || breadth ==-1) {
PrintHelp();
exit(EXIT_FAILURE);
}
// Calculate the area
if (area == 1) {
area = length * breadth;
printf("Area: %d\n",area);
}
// Calculate the perimeter
if (perimeter == 1) {
perimeter = 2 * (length + breadth);
printf("Perimeter: %d\n",perimeter);
}
//char* result;
//sprintf(result,"%d",rand);
//Tcl_SetResult(interp, result, TCL_VOLATILE);
printf("Area: %d\n",area);
printf("Perimeter: %d\n",perimeter);
return TCL_OK;
}
如果我们查看 documentation for getopt_long_only()
,我们会看到这些关键行:
The variable optind is the index of the next element to be processed in argv. The system initializes this value to 1. The caller can reset it to 1 to restart scanning of the same argv, or when scanning a new argument vector.
还有:
Notes
A program that scans multiple argument vectors, or rescans the same vector more than once, and wants to make use of GNU extensions such as '+' and '-' at the start of optstring, or changes the value of POSIXLY_CORRECT between scans, must reinitialize getopt()
by resetting optind to 0, rather than the traditional value of 1. (Resetting to 0 forces the invocation of an internal initialization routine that rechecks POSIXLY_CORRECT and checks for GNU extensions in optstring.)
你的代码在解析一组新的参数之前不会重置 optind(不是 getopt()
和朋友通常提到的东西,因为他们的正常情况是一次性的解析命令行参数)。对于这种情况,您应该更改它。如果你打算从多个线程使用你的扩展,你应该切换到一个不同的解析解决方案,它更多地使用 Tcl 的内置函数;他们没有在线程之间共享状态。
我正在为接受参数的过程编写 C++ 到 tcl 的转换。它使用 getop_long_only。我第一次能够加载创建的共享库和 运行。然而,我第二次调用时,getop_long_only 总是给我 -1,这导致 proc 出现故障。调用快照如下。我还包括代码部分。你能帮忙解释一下是怎么回事吗?
********************* 呼叫 ************************ ****
enter code here
$ tclsh
% load area.so area
% area --area --length 4.0 --breadth 4.0
OPT ==> 97
OPT ==> 108
OPT ==> 98
OPT ==> -1
Area0: 1
Perimeter0: 0
Length0: 4
Breadth0: 4
Area: 16
Area: 16
Perimeter: 0
% area --area --length 4.0 --breadth 5.0
OPT ==> -1
rea0: 0
Perimeter0: 0
Length0: -1
Breadth0: -1
-area: Return the area
-perimeter: Return the perimeter
-length <val>: Specify the length
-breadth <val>: Specify the width
-help: Show help
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <iostream>
#include <tcl.h>
// Program to calculate the area and perimeter of
// a rectangle using command line arguments
//----------------------------------------------------
void PrintHelp() {
std::cout <<
"-area: Return the area\n"
"-perimeter: Return the perimeter\n"
"-length <val>: Specify the length\n"
"-breadth <val>: Specify the width\n"
"-help: Show help\n";
exit(1);
}
// area --
// This implements the random Tcl command. With no arguments
// the command returns a random integer.
// With an integer valued argument "range",
// it returns a random integer between 0 and range.
//--------------------------------------------------------------
extern "C" int AreaCmd(ClientData clientData, Tcl_Interp *interp, int argc, const char **argv) {
int opt= 0;
int area = 0, perimeter = 0, breadth = -1, length =-1;
while (1) {
//Specifying the expected options
//The two options l and b expect numbers as argument
static struct option long_options[] = {
{"area", no_argument, 0, 'a' },
{"perimeter", no_argument, 0, 'p' },
{"length", required_argument, 0, 'l' },
{"breadth", required_argument, 0, 'b' },
{"help", no_argument, 0, 'h' },
{0, 0, 0, 0 }
};
int long_index =0;
char* const* new_argv = const_cast<char * const *>(argv);
opt = getopt_long_only(argc, new_argv,"", long_options, &long_index );
printf("OPT ==> %d\n",opt);
if (opt == -1) {
break;
}
switch (opt) {
case 'a' : area = 1;
break;
case 'p' : perimeter = 1;
break;
case 'l' : length = atoi(optarg);
break;
case 'b' : breadth = atoi(optarg);
break;
case 'h': // -h or --help
case '?': // Unrecognized option
default: PrintHelp();
exit(EXIT_FAILURE);
}
}
printf("Area0: %d\n",area);
printf("Perimeter0: %d\n",perimeter);
printf("Length0: %d\n",length);
printf("Breadth0: %d\n\n",breadth);
if (length == -1 || breadth ==-1) {
PrintHelp();
exit(EXIT_FAILURE);
}
// Calculate the area
if (area == 1) {
area = length * breadth;
printf("Area: %d\n",area);
}
// Calculate the perimeter
if (perimeter == 1) {
perimeter = 2 * (length + breadth);
printf("Perimeter: %d\n",perimeter);
}
//char* result;
//sprintf(result,"%d",rand);
//Tcl_SetResult(interp, result, TCL_VOLATILE);
printf("Area: %d\n",area);
printf("Perimeter: %d\n",perimeter);
return TCL_OK;
}
如果我们查看 documentation for getopt_long_only()
,我们会看到这些关键行:
The variable optind is the index of the next element to be processed in argv. The system initializes this value to 1. The caller can reset it to 1 to restart scanning of the same argv, or when scanning a new argument vector.
还有:
Notes
A program that scans multiple argument vectors, or rescans the same vector more than once, and wants to make use of GNU extensions such as '+' and '-' at the start of optstring, or changes the value of POSIXLY_CORRECT between scans, must reinitialize
getopt()
by resetting optind to 0, rather than the traditional value of 1. (Resetting to 0 forces the invocation of an internal initialization routine that rechecks POSIXLY_CORRECT and checks for GNU extensions in optstring.)
你的代码在解析一组新的参数之前不会重置 optind(不是 getopt()
和朋友通常提到的东西,因为他们的正常情况是一次性的解析命令行参数)。对于这种情况,您应该更改它。如果你打算从多个线程使用你的扩展,你应该切换到一个不同的解析解决方案,它更多地使用 Tcl 的内置函数;他们没有在线程之间共享状态。