【问题标题】:Converting a temporary character array to a string in D将临时字符数组转换为 D 中的字符串
【发布时间】:2015-08-26 07:37:30
【问题描述】:

我正在学习 D 语言(我很了解 C++)...我想做一些 Windows 特定的东西,所以我写这个只是为了尝试 API:

import core.sys.windows.windows;
import std.stdio;

string name()
{
    char buffer[100];
    uint size = 100;

    GetComputerNameA(&buffer[0], &size);

    return buffer;
}

void main()
{
    writeln(name());
}

我收到了我的退货声明:

test.d(11): Error: cannot implicitly convert expression (buffer) of type char[100] to string

好的,在 C++ 中它会调用构造函数来创建一个字符串。它说是隐式的,所以让我们用 C 风格的转换来转换它:return (string)buffer;

test.d(11): Error: C style cast illegal, use cast(string)buffer

嗯,好的,我记得,不同的语法。

return cast(string)buffer;

现在它编译了,但我得到了垃圾。

我认为这是因为它在字符串中存储了一个指向临时缓冲区的指针。我不想这样做,我想将字符复制到一个字符串中,但烦人的是我似乎找不到如何做到这一点?

所以问题:

  1. 如何从正确分配存储的 char 数组构造实际字符串? (复制字符)

  2. 像这样分配随机大小的缓冲区并转换为字符串似乎很难看。在 D 中是否有适当的方法来做到这一点? (我说的是一般性问题,而不是专门针对这个 API 以防万一有另一个 API 来获取计算机名称)。

  3. 如果手册中回答了其中任何一个问题,我应该在哪里查找详细信息?

感谢您的帮助和建议。

【问题讨论】:

  • 你能不能在转换之前检查buffer的实际值,因为转换应该不会失败。
  • 转换工作......如果我在函数中打印它......如果我返回字符串它会失败,大概是因为它仍然引用临时缓冲区。
  • @Bauss,不,不应该。事实上 2.068 中止编译:Error: escaping reference to local variable buffer
  • @sigod 使用 2.068 在 windows 上编译原始代码没有任何错误或警告...

标签: d


【解决方案1】:

我认为你需要:

string name()
{
   char buffer[100];
   uint size = 100;

   GetComputerNameA(buffer.ptr, &size);

   return buffer[0 .. size].idup;
}

【讨论】:

  • 但还是忽略了ERROR_BUFFER_OVERFLOW & GetLastError。正确的代码应该检查size 是否小于buffer.length,否则分配新的更大的缓冲区
  • 是的,当然,我的原始样本只是我可以写的最短的样本来证明我的问题。它并不打算完整。
【解决方案2】:

buffer.idup 是获取不可变副本的标准方法。对于这种情况,由于您想要一个动态大小的string(并记得string 实际上只是immutable(char)[] 的简写),因此您需要buffer[0..size].idup,使用D 的数组切片。

更多信息请参见http://dlang.org/arrays.html

(这有点挑剔,但您可能想使用buffer.ptr 而不是&buffer[0],主要是为了便于阅读。)

【讨论】:

  • 非常感谢,这行得通。好的,现在信息很清楚了。当您不熟悉一种语言时,可能很难知道在文档中寻找什么。感谢您的挑剔!这正是我刚接触 D 时需要的那种建议 :)
猜你喜欢
  • 2014-01-19
  • 1970-01-01
  • 2011-06-18
  • 2017-11-27
  • 2011-02-15
相关资源
最近更新 更多