【问题标题】:convert from string to char* - passing function pointer从字符串转换为 char* - 传递函数指针
【发布时间】:2013-02-09 13:52:04
【问题描述】:

这篇文章基于here 给出的解决方案,一个关于 SO 的帖子

我编写了一个函数来获取给定的文件扩展名(字符串类型),例如:

void GetFileExtension(string filename, char* extension)
{
    vector<string> rec;

    StrDelimit(filename, '.', rec);

    //cout << rec[rec.size()-2].c_str()[1] << endl;

    //extension = rec[rec.size()-2].c_str()[0];

    //extension = &rec[rec.size()-2].c_str()[0];

    string str = rec[rec.size()-2];

    // conversion from string to char*
    vector<char> writable(str.size() + 1);

    std::copy(str.begin(), str.end(), writable.begin());

    //cout << writable << endl;

    extension = &writable[0];
}

StrDelimit 工作正常,它接收一个字符串并通过给定的分隔符分隔子字符串向量

我使用"//conversion from string to char*" 将结果返回给调用主程序

没有编译错误,但结果是一串无意义的字符。这是什么问题?

任何帮助将不胜感激!

谢谢!

【问题讨论】:

    标签: c++ string pointers parameter-passing


    【解决方案1】:

    char *extension 是字符串地址的临时副本。要真正将新数据放入其中,您必须将数据复制到它保存的地址。

    这有帮助吗?

    #include <stdio.h>
    #include <string.h>
    
    void getStringInoExistingBufer(char* existingBufferOut)
    {
        strcpy(existingBufferOut, "someData");
    }
    
    void getStringIntoNonExistingBuffer(char **newBufferOut)
    {
        *newBufferOut = strdup("someOtherData");
    }
    
    int main()
    {
        char buffer1[100] = {};
        char *buffer2 = NULL;
    
        printf("buffer1 (before): '%s'\n", buffer1);
        getStringInoExistingBufer(buffer1);
        printf("buffer1 (after): '%s'\n", buffer1);
    
        printf("\n\n");
        printf("buffer2 (before): '%s'\n", buffer2);
        getStringIntoNonExistingBuffer(&buffer2);
        printf("buffer2 (after): '%s'\n", buffer2);
    }
    

    输出:

    buffer1 (before): ''
    buffer1 (after): 'someData'
    
    
    buffer2 (before): '(null)'
    buffer2 (after): 'someOtherData'
    

    【讨论】:

      【解决方案2】:

      您的问题是您在堆栈上创建数据成员writable,然后用extension 指向它但是可写的范围是函数,这意味着当函数返回时writable 被清除而留下@987654324 @指点什么。

      您可以为 char* 分配一个动态缓冲区,但这更像是 C 方法而不是 C++。 如果可能的话,我建议将函数类型更改为返回字符串或向量,这样会更容易,您可以在需要时将这些类型更改为 char*。

      【讨论】:

        【解决方案3】:

        为什么不直接将扩展名返回为std::string

        例如:

        std::string GetFileExtension(std::string filename)
        {
            std::vector<string> rec;
        
            StrDelimit(filename, '.', rec);
        
            std::string extension = rec[rec.size() - 2];
            return extension;
        }
        

        【讨论】:

          【解决方案4】:

          首先,你并没有真正返回任何东西;

          void GetFileExtension(string filename, char* extension)
          {
              ...
              extension = &writable[0];  // Assignment to local variable
          }
          

          如果您打算更新 extension 中传递的 char*,则需要将其作为 char** 传递(即指向您的 char* 的指针)。

          其次,即使你解决了这个问题,你也试图返回一个指向局部变量中数据的指针;

          void GetFileExtension(string filename, char* extension)
          {
              ...
              vector<char> writable(str.size() + 1);   // Local variable
              ...
              extension = &writable[0];       // writable disappears after this line
                                              // and extension will point to invalid memory
          }
          

          只返回一个std::string 会大大简化您的代码。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-01-02
            • 2021-09-07
            • 2015-04-29
            • 1970-01-01
            • 1970-01-01
            • 2011-05-22
            • 2023-03-13
            相关资源
            最近更新 更多