C++ 将char*[]传递给接受char**作为参数的函数
我已经编写了一个程序,对命令行参数进行排序。但是,当我尝试打印输出(使用函数)时,我无法执行此操作。因为我尝试在接受char**作为参数的函数中传递char*[]。经过大量的搜索,没有什么结果,因此我在这里提出我的第一个问题C++ 将char*[]传递给接受char**作为参数的函数,c++,command-line-arguments,C++,Command Line Arguments,我已经编写了一个程序,对命令行参数进行排序。但是,当我尝试打印输出(使用函数)时,我无法执行此操作。因为我尝试在接受char**作为参数的函数中传递char*[]。经过大量的搜索,没有什么结果,因此我在这里提出我的第一个问题 #include "iostream" #include "cstdlib" #include "cstring" using namespace std; void sortArgs(); int stringcomp (const void * x, const v
#include "iostream"
#include "cstdlib"
#include "cstring"
using namespace std;
void sortArgs();
int stringcomp (const void * x, const void * y);
void parse(char **argv, int argc);
void printArgs();
void setArgs(char **argv, int argc);
int size;
char** argNew;
int main (int argc, char** argv)
{
parse(argv, argc);
printArgs();
return 0;
}
int stringcomp (const void *x, const void *y)
{
return strcmp (*(char * const *)x, *(char * const *)y);
}
void parse(char **argv, int argc)
{
setArgs(argv, argc);
sortArgs();
}
void setArgs(char **argv, int argc)
{
argNew=argv;
size=argc;
}
void printArgs()
{
char *s[size-1];
cout<<size<<endl;
for (int i = 1; i < size; i++)
{
s[i-1] = argNew[i];
}
for (int i = 0; i < size-1; i++)
cout<<" "<< s[i];
cout <<endl;
}
void sortArgs()
{
int i;
char *strings[size-1];
/* assign each argument to a pointer */
for (i = 1; i < size; i++)
{
strings[i-1] = argNew[i];
}
/* sort the array of pointers alphabetically with qsort */
qsort (strings, size - 1, sizeof *strings, stringcomp);
for (int i = 0; i < size-1; i++)
cout<<" "<< strings[i]; //this prints the output just fine
setArgs(strings, size); // pass the *strings[] here
}
#包括“iostream”
#包括“cstdlib”
#包括“cstring”
使用名称空间std;
void sortArgs();
int stringcomp(常数无效*x,常数无效*y);
无效解析(字符**argv,int argc);
void printArgs();
void setArgs(字符**argv,整数argc);
整数大小;
新字符;
int main(int argc,字符**argv)
{
解析(argv,argc);
printArgs();
返回0;
}
int stringcomp(常数无效*x,常数无效*y)
{
返回strcmp(*(字符*常量*)x,*(字符*常量*)y);
}
无效解析(字符**argv,int argc)
{
设置args(argv,argc);
sortArgs();
}
void setArgs(字符**argv,整数argc)
{
argNew=argv;
尺寸=argc;
}
void printArgs()
{
字符*s[size-1];
库特
这是个错误
strings
是一个本地数组。当函数返回时,它会被删除。因此,argNew
在函数返回时将是一个悬空指针。尝试打印argNew
的内容是未定义的行为
通过将字符串的元素复制到argNew
来替换该行
for (i = 1; i < size; i++)
{
argNew[i] = strings[i-1];
}
for(i=1;i
您通过sortArgs
中的setArgs
赋值将自动变量字符串的基址存储到全局中。一旦sortArgs
退出并将控制权返回到parse
,该数组就不再存在。其中的任何计算或取消引用都会调用未定义的行为
您可以解决这个问题(松散使用的术语,请参阅下一节了解原因)只需将argv
和argc
设置到全局变量中,并对它们进行排序,而不是将一些参数传递给某些函数。或者,您可以像现在这样将指针复制到指针床上,然后对它们进行排序,然后将它们复制回argvNew
for (i = 1; i < size; i++)
{
argNew[i] = strings[i-1];
}
或者,您可以完全消除全局变量,并在这个过程中抛弃set
思想,只需在parse
中直接对argv
中的指针进行排序,您可以对其进行重新排序,但仍然可以在已定义的行为领域中发言
但<强>为什么?这是后面的,C++ + < /P>
<强>跳入C++池>/P>
<>我不打算把这个糖涂写。代码很可怕。它是拼命地在C++的C++中使用C++的标准库提供的,除了基本的IO。C是一种很好的语言,并且有一个很好的标准库,但是如果你想潜入C++,那就不要害怕它;拥抱它。< /P>
<>在C++中,使用一些基本的C++标准库提供。一个可以做得相当不同的事情。例如:
从argv
和argc
做任何你想做的事情,包括分类
该代码比您想象的要简单得多:
#include <iostream>
#include <vector>
#include <string>
std::vector<std::string> parseArgs(char **argv, int argc)
{
std::vector<std::string> args(argv+1, argv+argc);
std::sort(args.begin(), args.end());
return args;
}
int main (int argc, char** argv)
{
auto args = parseArgs(argv, argc);
// move to your own function.
for (auto const& s : args)
std::cout << s << '\n';
return 0;
}
#包括
#包括
#包括
std::vector parseArgs(字符**argv,int argc)
{
标准::向量args(argv+1,argv+argc);
排序(args.begin(),args.end());
返回args;
}
int main(int argc,字符**argv)
{
自动args=parseArgs(argv,argc);
//转到您自己的功能。
用于(自动常量和参数:args)
std::cout有很多很好的搜索,比如StackOverflow或Google上的“双指针c”。例如和
也就是说,我建议的第一件事是,您可以像打印数字一样打印指针的值。要执行此操作,请编写:
printf("Pointer is %p.\n", ptr);
或:
请注意,字符串
数组的位置对于f1
和f2
是相同的(这不是保证的,这里正好是这种情况。但是这通常是正确的,并且有助于理解您看到的SEGV错误)。请注意字符串文字“foo”、“bar”和“baz”get pooled——也就是说,即使它们被多次使用,也只有一个副本。字符串指针值的顺序与链接器在内存中的排列顺序一致
请注意,&global\u array
的值与global\u array
的值相同,但global\u ptr
的情况并非如此。char*strings[]类型的参数被调整为char**.:char*s[size-1];
和char*strings[size-1]“/CODE”是可变长度数组,它们在C++中是不标准的。FYI,您将自动对象的基地址保存在代码> > AgNeX< /COD>中。一旦代码< > Soaltgs<代码>结束,char指针的序列就消失了,因此,定义的行为。@ VladfromMoscow,如果您在我的SoTalgS.()中看到的话函数,我尝试将其传递给setArgs()函数。但是,当我尝试在打印函数中迭代它时,我无法,相反,它给了我seg fault。@WhozCraig的注释可能正确地解释了SEGV。这个问题是非常有问题的,因为代码太糟糕了。如果你问的是C/C++中的参数传递,为什么你要将值存储在全局值而不是全局值中传递它们?如果你想探索参数传递,你可以从最简单的程序开始,该程序在main中对argv进行排序和打印,然后递增地将排序和打印分为单独的函数。向前的decls是不必要的,等等。谢谢。你能给我引用一个ref来了解**指针的更多信息吗?我正在尝试ng想了解一下。@sidchawla,我没有任何关于理解指针的具体建议。你可能想看看。我理解你的观点,非常感谢你在这方面的见解。
std::cout << "Pointer is " << (void *)ptr << ".\n";
#include <iostream>
// Sometimes it's char *, sometimes const char *
template <typename T>
void print_argv_style_array(const char *label, int argc, T **argv) {
int i = 0;
std::cout << label << ": Printing argv array of size " << argc << " at " << (void *)argv << ":\n";
for (int i = 0; i < argc; i++) {
std::cout << " " << i << ": " << (void *)argv[i] << " -- " << argv[i] << "\n";
}
}
void f1() {
const char *strings[] = { "foo", "bar" , "baz" };
print_argv_style_array("f1", sizeof(strings) / sizeof(strings[0]), strings);
}
void f2() {
const char *strings[] = { "foo", "bar" , "quux" };
print_argv_style_array("f2", sizeof(strings) / sizeof(strings[0]), strings);
}
const char *global_array[] = { "foo", "bar", "baz" };
const char **global_ptr = global_array;
int main(int argc, char **argv) {
std::cout << "main: argv is at " << &argv << "\n";
print_argv_style_array("main", argc, argv);
f1();
f2();
std::cout << "global_array is at: " << (void *)global_array << "\n";
print_argv_style_array("global_array", sizeof(global_array)/sizeof(global_array[0]), global_array);
std::cout << "global_ptr is at: " << (void *)&global_ptr << "\n";
print_argv_style_array("global_ptr", sizeof(global_array)/sizeof(global_array[0]), global_ptr);
}
main: argv is at 0x7fff5a8c38f0
main: Printing argv array of size 1 at 0x7fff5a8c3928:
0: 0x7fff5a8c3ab8 -- ./pointer_help
f1: Printing argv array of size 3 at 0x7fff5a8c38a0:
0: 0x10533dedc -- foo
1: 0x10533dee0 -- bar
2: 0x10533dee4 -- baz
f2: Printing argv array of size 3 at 0x7fff5a8c38a0:
0: 0x10533dedc -- foo
1: 0x10533dee0 -- bar
2: 0x10533deeb -- quux
global_array is at: 0x10533e140
global_array: Printing argv array of size 3 at 0x10533e140:
0: 0x10533dedc -- foo
1: 0x10533dee0 -- bar
2: 0x10533dee4 -- baz
global_ptr is at: 0x10533e158
global_ptr: Printing argv array of size 3 at 0x10533e140:
0: 0x10533dedc -- foo
1: 0x10533dee0 -- bar
2: 0x10533dee4 -- baz