【问题标题】:C++ Pointer to Pointer to chars in String-Array指向字符串数组中字符的指针的 C++ 指针
【发布时间】:2021-06-28 03:49:19
【问题描述】:

我要测试功能

std::vector<std::string> convert_arguments(int argc, char **argv) {
[some code]
return command_arguments;
};

它接受一个指向命令参数数组的指针并返回一个包含这些参数的向量。该功能运行良好。但是我自己构建这样的指针时遇到了麻烦。该数组是一个字符串数组,即一个字符数组。据我所知,指针应该指向指向字符串第一个字母的指针中的第一个指针(这听起来很奇怪)。我需要的是一个示例指针 **argv,我可以将它传递给函数以查看它是否有效。我知道互联网上有很多类似的问题,但我真的找不到适合我的答案。如果您能帮助我,我将不胜感激,因为我已经寻找了几个小时的答案。

【问题讨论】:

  • for (int i = 0; i
  • 问题应该说,我如何为这个函数创建一个UT?

标签: c++ arrays string pointers char


【解决方案1】:

char** argv 实际上只是一个二维数组。您可以通过创建这样的数组 char** argv = new char*[argc];。然后,您可以使用 for(int i=0;i &lt; argc; ++i) 循环遍历 argv 数组,并将您想要的任何字符串分配给每个条目。

【讨论】:

    【解决方案2】:

    命令行参数使用两种约定来传递参数的数量:

    • 它被明确地传入argc
    • argv 数组包含一个空指针作为其最后一个(有用的)元素

    您可以为const char * 构造一个字符串,代码可以很简单:

    std::vector<std::string> convert_arguments(int argc, char **argv) {
        std::vector<std::string> command_arguments;
        for (int i=0; i<argc; i++) {
            command_arguments.push_back(std::string(argv[i]));
        }
        return command_arguments;
    }
    

    或(第二个约定):

    std::vector<std::string> convert_arguments(int argc, char **argv) {
        std::vector<std::string> command_arguments;
        for (const char **ix=argv; ix!=nullptr; ix++) {
            command_arguments.push_back(std::string(*ix++));
        }
        return command_arguments;
    }
    

    如果你想为测试构建这样一个数组,你可以很容易地从文字字符串中做到这一点:

    const char *const_argv[] = { "foo", "fee", "bar", "baz", nullptr};  // add the last null
    int my_argc = sizeof(my_argv)/sizeof(*my_argv) - 1;        // but do no count it
    char ** my_argv = const_cast<char **>(const_argv);         // cast it
    

    注意:此代码正确地将 const_argv 声明为指向 const 字符的指针数组,因为字符串文字是 const,并且使用 const_cast 能够将其传递给上述函数.这是无害的,因为该函数从不尝试更改其参数,但规则是应尽可能避免使用 const_cast

    如果你真的需要一个非 const 字符串数组,你必须先构建字符串,然后再构建数组:

    char a1[] = "foo";
    char a2[] = "fee";
    char a3[] = "bar";
    char a4[] = "baz";
    char *argv[] = {a1, a2, a3, a4, nullptr};
    

    【讨论】:

    • 真的很抱歉,我认为我在表达我的问题时做得不好。我已经有了函数 convert_arguments,但是为了测试它,我需要构造一个示例数组和可以用来测试函数的指针。这就是我遇到的麻烦。
    • 非常感谢!现在说得通了:)
    【解决方案3】:

    这里 argc 存储传递的参数数量,而 argv 存储所有参数。 你可以这样做,

    std::vector<std::string> vec;
    for (int counter=1;counter<argc;counter++)   //0th argument is the program name
    {
        vec.push_back(argv[counter]); //push each string into vector
    }
    return vec;
    

    【讨论】:

      【解决方案4】:

      单行版本:

      std::vector<std::string> convert_arguments(int argc, const char **argv) {
        return std::vector<std::string>(argv + 1, argv + argc);
      }
      

      或者使用上面的 c++11 甚至更简单

      std::vector<std::string> convert_arguments(int argc, const char **argv) {
        return {argv + 1, argv + argc};
      }
      

      解释:

      我们调用std::vector的构造函数有两个迭代器范围(指针可以被视为一个迭代器),因为argv是一个指针数组,左边的范围是argv+1,右边的范围是argv + argc

      对于std::string 构造函数,const char* 被传递。

      【讨论】:

        【解决方案5】:

        您可以使用 C 风格的 char 数组指针来实现这一点:

        #include <vector>
        #include <string>
        #include <iostream>
        
        using namespace std;
        
        // borrowed from prehistoricpenguin
        std::vector<std::string> convert_arguments(int argc, const char **argv) {
          return std::vector<std::string>(argv + 1, argv + argc);
        }
        
        bool test1(void) {
            int argc = 5;
            const char *argv[] = {"program_name", "some string", "another", "command", "ok", NULL };
            std::vector<std::string> myexpectedvector =  {"some string", "another","command", "ok" };
            std::vector<std::string> s = convert_arguments(argc, argv);
            return (s == myexpectedvector);
        }
        
        int main () {
            std::cout << test1() << std::endl;
        }
        

        【讨论】:

        • 谢谢,我在外面用手机回答,不是最好的编译和测试,我用一个完整的例子调整了我的答案
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-02-08
        • 1970-01-01
        • 1970-01-01
        • 2014-11-29
        • 1970-01-01
        • 2011-04-12
        • 1970-01-01
        相关资源
        最近更新 更多