【问题标题】:How to assemble a string of wide characters with some null ones inserted in the middle of it?如何组装一串宽字符,中间插入一些空字符?
【发布时间】:2018-07-29 18:55:25
【问题描述】:

让我们从背景开始。我需要为 ODBC 命令设置一串属性:

SQLConfigDataSource(hwndParent, ODBC_ADD_DSN, sDriver, wcAttrs);

属性必须以严格的方式格式化才能起作用:

LPCWSTR wcAttrs = L"DSN=NiceDB\0DBQ=C:\\Users\\who\\AppData\\Local\\NiceApp\\niceDB.accdb\0";

以这种方式对其进行硬编码是可行的,但我实际上需要动态设置 accdb 文件 (DBQ) 的路径。问题是分隔字符串中的属性所需的空字符,而我主要使用 wcscat_s 的 string-fu 技能失败了,因为空字符会使任何东西在它之后消失。

用中间的空字符组装/连接字符串的最佳技术是什么?

【问题讨论】:

  • std::string 完全支持嵌入的空(或任何其他)字符。
  • 这个问题是windows独有的吗?
  • 你是问这个问题的人,不是我,所以你应该知道。 std::string 的特性是标准化的。
  • 是的,但是有人添加了 windows 标签。虽然 ODBC 与 Windows 相关联,但我只是出于说明目的提及它,而不是主要主题。

标签: c++ windows odbc wstring


【解决方案1】:

您可以在构建时将一个空字符 push_back 转换为 std::wstring。

例子:

std::wstring str;
str += L"DSN=NiceDB";
str.push_back(L'\0');
str += L"DBQ=C:\\Users\\who\\AppData\\Local\\NiceApp\\niceDB.accdb";
str.push_back(L'\0');

您还可以使用 += 运算符手动附加空字符:

std::wstring str;
str += L"DSN=NiceDB";
str += L'\0';
str += L"DBQ=C:\\Users\\who\\AppData\\Local\\NiceApp\\niceDB.accdb";
str += L'\0';

您也可以只告诉 append 方法使用字符串文字的 +1 字符。这将使用源中已经存在的空字符隐式填充 std::string:

std::wstring str;
const wchar_t* header = L"DSN=NiceDB";
const wchar_t* footer = L"DBQ=C:\\Users\\who\\AppData\\Local\\NiceApp\\niceDB.accdb";

str.append(header, wcslen(header) + 1);
str.append(footer, wcslen(footer) + 1);

然后获取指向最终字符串开头的指针:

LPCWSTR wcAttrs = str.c_str();

.c_str() 返回的指针的有效性仅在支持 wstring 的生命周期内有效。不要让 wstring 实例超出范围,同时还有一些引用 wcAttrs 的东西。

【讨论】:

  • 为什么在 str.push_back(L'\0');双引号不起作用?
  • 因为(w)string::push_back 只接受字符,不接受字符串。
  • 那个,"\0" 形式的文字 C 字符串与空字符串 "" 没有什么不同。因此,任何附加空字符串的尝试都将被视为无操作。这就是为什么append(L"\0"); 是无操作的。但它知道将push_back(L'\0') 视为空字符的附加
  • 嗯,我仍然收到异常错误。 c_str() 命令是否也将字符串截断为第一个空字符?
  • "c_str() 命令是否也将字符串截断为第一个空字符?" - 不,它没有,但是任何像 strlen() 这样期望单个空终止符的函数似乎都会这样做。但 SQLConfigDataSource 不是这样的函数——它期望在属性字符串中看到多个空字符。
猜你喜欢
  • 2022-01-08
  • 2021-03-07
  • 2013-03-04
  • 2012-09-25
  • 1970-01-01
  • 2012-08-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多