如何阻止反斜杠取消从 QString 到 char 数组的转换?

How to stop backslashes from cancelling in conversion from QString to char array?

我正在编写一个 QT 小部件应用程序,其中包括与 Arduino 的串行通信。 I found a good header and cpp file on GitHub 这使得与 Arduino 的通信比与 QSerialPort 的通信容易得多。

然而,这带来的一个困难是端口名称必须以字符数组的形式给出,例如格式为“\\.\COM1”。所以我试图在 COM 端口名称之前添加这些反斜杠,代码如下:

QString currentPort = "\\.\" + QString(ui->serialPortDropdown->itemText(index));
portName = currentPort.toLocal8Bit().data();

在我的 cpp 文件顶部用这个初始化数组后:

char *portName;

在各处添加一些 qDebug() 之后,QString 被设置为它应该的样子,例如 "\\.\COM1"。但是 char 数组返回为 "\.\COM1"。所以反斜杠正在取消其他反斜杠。

我该如何克服这个问题?

在此先感谢您的帮助:)

QString 正在转义。也就是说,特殊字符(包括 )是使用其转义序列指定的(here 维基百科关于转义的文章)。

由于反斜杠字符的转义序列是 \\,您只需将反斜杠加倍即可:

QString currentPort = "\\\\.\\" + QString(ui->serialPortDropdown->itemText(index));

问题在于,在您的 "ordinary" 字符串文字中,反斜杠引入了 "special" 个字符,例如新行 \n。要得到一个反斜杠,你必须输入两个连续的反斜杠,即 \ 得到 \.

要解决这个问题,请输入每个反斜杠两次,或使用 raw 格式来指定字符串文字:

int main() {

    const char* raw = R"foo(\\.\)foo";
    cout << "raw: " << raw << endl;

    const char* notRaw = "\\.\";
    cout << "not raw: " << notRaw << endl;

}

输出:

raw: \\.\
not raw: \.\

请注意 "foo(" 部分是自定义的;它可以是您选择的任何内容,但不会包含在字符串文字的内部。

这是 C++ 源文件中的正常行为。还有更多:

Escape sequences are used to represent certain special characters within string literals and character literals.

The following escape sequences are available (extra escape sequences may be provided with implementation-defined semantics):

 Escape      | Description                 |Representation
sequence     |                             |
-------------+-----------------------------+-------------------------------------------------------
  \'         | single quote                |byte 0x27 in ASCII encoding
  \"         | double quote                |byte 0x22 in ASCII encoding
  \?         | question mark               |byte 0x3f in ASCII encoding
  \         | backslash                   |byte 0x5c in ASCII encoding
  \a         | audible bell                |byte 0x07 in ASCII encoding
  \b         | backspace                   |byte 0x08 in ASCII encoding
  \f         | form feed - new page        |byte 0x0c in ASCII encoding
  \n         | line feed - new line        |byte 0x0a in ASCII encoding
  \r         | carriage return             |byte 0x0d in ASCII encoding
  \t         | horizontal tab              |byte 0x09 in ASCII encoding
  \v         | vertical tab                |byte 0x0b in ASCII encoding
  \nnn       | arbitrary octal value       |byte nnn
  \xnn       | arbitrary hexadecimal value |byte nn
  \unnnn     | universal character name (arbitrary Unicode value); may result in several characters
             |                             |code point U+nnnn
  \Unnnnnnnn | universal character name (arbitrary Unicode value); may result in several characters
             |                             |code point U+nnnnnnnn

来源:Escape sequences

如果这是一个问题,那么 C++11 引入了一种新的字符串文字类型:原始字符串文字

Raw string literal. Used to avoid escaping of any character. Anything between the delimiters becomes part of the string.

语法:

prefix R " delimiter ( raw_characters ) delimiter "

  • prefix - (可选)L、u8、u、U
  • 之一
  • delimiter - 由除括号、反斜杠和空格外的任何源字符组成的字符序列(可以为空,最多 16 个字符长)
  • raw_characters - 任何字符序列,但它不能包含结束序列 ) delimiter "

来源:string literal


解决这个问题有2个方案

  1. 在每个需要反斜杠的地方插入 2 个反斜杠:"\\\\.\\"

  2. 使用原始字符串:R"(\\.\)"