【问题标题】:C++ string to fixed sized char array possible?C++ 字符串到固定大小的字符数组可能吗?
【发布时间】:2012-07-24 07:15:28
【问题描述】:

您好,我有以下代码:

char msg[10000];
string mystr = "hello";

我想将 mystr 放入 msg。有没有办法做到这一点?我尝试了各种方法,但不断得到:

incompatible types in assignment of 'const char*' to char [10000]'

我试过了:

msg = mystr.c_str();

msg = (char[10000])mystr;

无济于事。

【问题讨论】:

标签: c++ string std cstring


【解决方案1】:

您可以为此尝试std::copy。比如:

std::copy(mystr.begin(), mystr.end(), msg);

我会避免使用 C++ 中的 C 字符串函数,例如 mempcystrcpy

【讨论】:

  • 大概,msg 应该是零终止的。
  • @MikeSeymour 是的,如果msg 必须是正确的cstring,则需要第二步。
  • 如果 strcpy 可以一步完成,你为什么要避免它?
  • @BenjaminLindley 一种直觉。但不要相信我的话,我只是 C++ 的初学者。
【解决方案2】:

看看string::copy - 它接受一个字符串并将其放入一个数组中。

在你的情况下是:

std::size_t length = mystr.copy(msg,10000);
msg[length]='\0';

【讨论】:

  • 但请注意,它不会以零终止结果;如果你需要,你必须自己做。
  • 如果 copy 返回 10000 你有问题
【解决方案3】:
char msg[10000];
string mystr = "hello";

strcpy(msg, mystr.c_str());
cout<<msg;

【讨论】:

    【解决方案4】:

    使用std::string的复制成员函数:

    size_t len = mystr.copy(msg, (sizeof msg)-1);
    msg[len] = 0;
    

    【讨论】:

    • copy(msg, (sizeof msg)-1) 会避免缓冲区溢出。
    【解决方案5】:

    C 中的字符串赋值是不同的。您必须将字节复制到目标字符串中。

    memcpy_s(msg, 1000, mystr.c_str(), mystr.length()) // safe windows version

    memcpy(msg, mystr.c_str(), mystr.length()) // unix version

    【讨论】:

    • 如果消息超过 10000 个字符,这将导致缓冲区溢出,对吗?它可能应该是 mystr.length() > 10000 ? 10000 : mystr.length() 用于最后一个参数或类似的东西。
    【解决方案6】:

    使用 strcpy 函数: http://www.cplusplus.com/reference/clibrary/cstring/strncpy/

    strncpy(msg, mystr.c_str(), sizeof msg / sizeof msg[0]);
    msg[sizeof msg / sizeof msg[0] - 1] = 0; // null-terminate in case of truncation
    

    【讨论】:

    • 或者strncpy,如果你不喜欢缓冲区溢出的话。
    • 肯定 strncpy 会更好。
    • 为了防止缓冲区溢出,您需要将目标的最大大小传递给 strncpy,而不是源的大小。
    • @Paul R. 感谢您的建议
    【解决方案7】:

    编译器有时会为数组类型生成奇怪的错误消息。

    这是将以前的答案汇总到粘贴和编译程序中。

    #include <string>
    #include <iostream>
    
    #if 1
    
    int main(int argc, char **argv)
    {
        using std::cout;
        using std::endl;
    
        char msg[1000] = {0};    // initialize to 0 here since we're printing below
                                // the <type> <array-name>[<size>] = {0} just fills a POD struct or an array with 0s
    
        std::string mystr = "hello";
    
        // if, at some point, you have things changing "mystr"
        // you'll need to make sure that it will fit in msg[]
    
        cout << "Before strcpy: \"" << msg << "\"" << endl;
    
        // I'll just finish the statement in mystr...
        mystr += " world!";
    
        if(mystr.length() < sizeof(msg)){
            strcpy(
                msg,            // <- put in here until we find a '\0'
                mystr.c_str()    // <- take from here (which could be a temporary buffer)
                );
        }
    
        //MSC will complain about strcpy being unsafe
        //
        // you can use the below instead (if you really feel the need to), which is
        // the MS-specific equivalent to the above.
        /*
            strcpy_s(
                msg,            // <- put in here until we find a '\0' or the size limit is reached
                sizeof(msg),    // <- don't put any more than this many chars in msg
                mystr.c_str()    // <- take from here
                );
        */
    
        cout << "After strcpy: \"" << msg << "\"" << endl;
    
        return 0;
    }
    
    #else
    
    // Similarly, using wchar_t (a usually non-byte-sized character type)
    //
    // note where the divisions occurr
    
    int main(int argc, char **argv)
    {
        using std::wcout;
        using std::endl;
    
        wchar_t msg[1000] = {0};
        std::wstring mystr = L"hello";
    
        wcout << "Before strcpy: \"" << msg << "\"" << endl;
    
        mystr += L" world";
    
        if(mystr.length() < (sizeof(msg)/sizeof(wchar_t))){
            // mystr wil fit!
            wcscpy(
                msg,            // <- put in here until we find a '\0'
                mystr.c_str()    // <- take from here (which could be a temporary buffer)
                );
        }
    
        // Similar to the char case in the first preprocessor block
        /*
            wcscpy_s(
                msg,                            // <- put in here until we find a '\0' or the size limit is reached
                sizeof(msg)/sizeof(wchar_t),    // <- don't put any more than this many wchar_ts in msg
                mystr.c_str()                    // <- take from here
                );
        */
    
        wcout << "After strcpy: \"" << msg << "\"" << endl;
    
        return 0;
    }
    
    #endif
    

    我将留给您阅读有关所有相关功能的文档。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-05
      • 2014-04-24
      • 1970-01-01
      • 1970-01-01
      • 2018-03-31
      • 2018-05-25
      • 1970-01-01
      • 2021-10-30
      相关资源
      最近更新 更多