【问题标题】:string to struct in C++在 C++ 中构造字符串
【发布时间】:2018-06-04 09:02:11
【问题描述】:

我有一个字符串变量

string pr00("")

我想调用方法 fun1

fun1(demo *dm)

demo定义如下

typedef struct 
{
    char pr00[100];
}demo;

调用这个方法安全吗

fun1((demo*)pr00);

谢谢,BR

【问题讨论】:

  • 不,这不安全。这是非常不安全的,std::string 是一个复杂的结构,与您的demo 结构非常不同。对于初学者来说,它们的大小不同。更不用说标准明确地将不相关的结构/类之间的转换标记为 UB。不要那样做。
  • 不,将std::string 转换为char* 使用std::string::data() 是不安全的
  • 也许this SO问题对你来说可能很有趣。
  • 你认为是为什么?您不会将其他类随机转换为其他随机类吗?

标签: c++ string struct


【解决方案1】:

不,这是不安全的。因为std::string的成员和demo不一样。

但是你可以定义一个构造函数将std::string隐式转换为demo类型。

#define MAX_SIZE    100
struct demo 
{    
    demo(const std::string& str)
    {
       memset(pr00, 0, MAX_SIZE);

       if (str.length() < MAX_SIZE)
       {
           strncpy(pr00, str.c_str(), str.length());
           pr00[str.length()] = 0;
       }
    }

    char pr00[MAX_SIZE];
};

现在你可以这样写代码了:

std::string name("hello world");
demo d(name);

【讨论】:

  • @cwschmidt 好收获!但正如我在线程中读到的,它提到了用户定义的复制赋值运算符和析构函数,而不是构造函数。
  • @MartinZhai 引用具体的引用:“聚合是一个数组或一个类(第 9 条),没有用户声明的构造函数”......“一个 POD 结构是一个聚合类”跨度>
  • str.length() &gt;= MAX_SIZE 的情况下,您将离开 pr00 未初始化
  • @Caleth 是的,但我们无法知道编译时字符串的长度。为了处理任意长度的字符串,我们需要使用动态分配的 char 字符串。我不确定这是否是 OP 想要的。
【解决方案2】:

不,fun1((demo*)pr00); 是未定义的行为。您需要将 pr00 中的(最多 100 个)字符复制到 demo 中,并将指向它的指针传递给 fun1

demo dm;
std::copy_n(pr00.data(), std::min(100, pr00.size()), dm.pr00);
fun1(&dm);

【讨论】:

    【解决方案3】:

    我假设string 表示std::string

    这不仅不安全而且无效。问题有fun1((demo*)pr00)

    这是一种将结构转换为指针的尝试。非法,如果您的编译器有允许的设置,请将其关闭。

    关于fun1((demo*)&amp;pr00) 有一个更有趣的问题。 注意&amp; 的地址是pr00

    它仍然是未定义的行为,但至少它在不相关的结构之间转换指针。

    您可以定义void fun2(char*cp) 并调用fun2((char*)&amp;pr00),尽管您可以在fun2() 中安全地使用cp 执行的操作有许多限制。

    您不应该对std::string 的布局做出任何假设,因此您应该'访问cp(特别是不要写信给它)并假设您可能会找到什么。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-31
      • 2020-07-26
      相关资源
      最近更新 更多