Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将字符附加到StringBuilder C++/CLI_String_Visual C++_C++ Cli_Ascii - Fatal编程技术网

将字符附加到StringBuilder C++/CLI

将字符附加到StringBuilder C++/CLI,string,visual-c++,c++-cli,ascii,String,Visual C++,C++ Cli,Ascii,我试图使用StringBuilder创建通过串行端口发送的日志文件输出。输出存储在一个字节数组中,我正在递归它 ref class UART_G { public: static array<System::Byte>^ message = nullptr; static uint8_t message_length = 0; }; static void logSend () { StringBuilder^ outputsb = gcnew Str

我试图使用StringBuilder创建通过串行端口发送的日志文件输出。输出存储在一个字节数组中,我正在递归它

ref class UART_G {
   public:
     static array<System::Byte>^ message = nullptr;
     static uint8_t message_length = 0;
};

static void logSend ()
{
  StringBuilder^ outputsb = gcnew StringBuilder();
  outputsb->Append("Sent ");
  for (uint8_t i = 0; i < UART_G::message_length; i ++)
  {
    unsigned char mychar = UART_G::message[i];
    if (
      (mychar >= ' ' && mychar <= 'Z') || //Includes 0-9, A-Z.
      (mychar >= '^' && mychar <= '~') || //Includes a-z.
      (mychar >= 128 && mychar <= 254)) //I think these are okay.
    {
      outputsb->Append(L""+mychar);
    }
    else
    {
      outputsb->Append("[");
      outputsb->Append(mychar);
      outputsb->Append("]");
    }
  }
  log_line(outputsb->ToString());
}
相反,我看到:

Sent 6580807669[13]

我已经尝试了所有可以想象的方法让它正确地显示字符,包括类型转换、将其连接到字符串、更改变量类型等等。。。如果有人知道怎么做,我将不胜感激。如果没有此函数,我的日志文件基本上无法读取。

您将收到字符串的ascii值

请参见Ascii图表

 65 = A
 80 = P
 80 = P
 76 = L
 69 = E

只需编写一个函数,将ascii值转换为字符串

以下是我提出的解决问题的代码:

static void logSend ()
{
  StringBuilder^ outputsb = gcnew StringBuilder();
  ASCIIEncoding^ ascii = gcnew ASCIIEncoding;
  outputsb->Append("Sent ");
  for (uint8_t i = 0; i < UART_G::message_length; i ++)
  {
    unsigned char mychar = UART_G::message[i];
    if (
      (mychar >= ' ' && mychar <= 'Z') || //Includes 0-9, A-Z.
      (mychar >= '^' && mychar <= '~') || //Includes a-z.
      (mychar >= 128 && mychar <= 254)) //I think these are okay.
    {
      outputsb->Append(ascii->GetString(UART_G::message, i, 1));
    }
    else
    {
      outputsb->Append("[");
      outputsb->Append(mychar);
      outputsb->Append("]");
    }
  }
  log_line(outputsb->ToString());
}
static void logSend()
{
StringBuilder^outputsb=gcnew StringBuilder();
ascienceoding^ascii=gcnew ascienceoding;
outputsb->Append(“Sent”);
对于(uint8\u t i=0;i=''&&mychar='^'&&mychar=128&&mychar-Append(ascii->GetString(UART_G::message,i,1));
}
其他的
{
outputsb->Append(“[”);
outputsb->Append(mychar);
outputsb->Append(“]”);
}
}
日志行(outputsb->ToString());
}

我仍然很欣赏任何更有效或更易于阅读的替代方案。

您获得ASCII值是因为编译器正在选择一个接受某种整数的值。要解决此问题,您可以显式转换到
System::Char
,以强制执行

但是,对于128-255,这不一定会给出正确的结果。您可以在
Byte
Char
的范围内强制转换一个值,它会给出一些东西,但不一定是您所期望的。首先,0x80到0x9F是控制字符,从中获取字节的位置可能并不表示相同的字符与Unicode一样,对0xA0到0xFF进行加密

在我看来,最好的解决方案是使用“[value]”语法,您正在为0x80到0xFF的其他控制字符使用该语法。但是,如果您确实想将这些字符转换为字符,我将使用,而不是
编码::ASCII
。ASCII仅定义0x00到0x7F,0x80及更高版本将显示为“?”.
Encoding::Default
是为您在Windows中选择的语言定义的任何代码页

将所有这些结合起来,您将得到以下结果:

for (uint8_t i = 0; i < UART_G::message_length; i ++)
{
  unsigned char mychar = UART_G::message[i];

  if (mychar >= ' ' && mychar <= '~' && mychar != '[' && mychar != ']')
  {
    // Use the character directly for all ASCII printable characters, 
    // except '[' and ']', because those have a special meaning, below.
    outputsb->Append((System::Char)(mychar));
  }
  else if (mychar >= 128)
  {
    // Non-ASCII characters, use the default encoding to convert to Unicode.
    outputsb->Append(Encoding::Default->GetChars(UART_G::message, i, 1));
  }
  else
  {
    // Unprintable characters, use the byte value in brackets.
    // Also do this for bracket characters, so there's no ambiguity 
    // what a bracket means in the logs. 
    outputsb->Append("[");
    outputsb->Append((unsigned int)mychar);
    outputsb->Append("]");
  }
}
for(uint8\u t i=0;i=''&&mychar-Append((系统::字符)(mychar));
}
else if(mychar>=128)
{
//非ASCII字符,使用默认编码转换为Unicode。
outputsb->Append(Encoding::Default->GetChars(UART_G::message,i,1));
}
其他的
{
//不可打印字符,请使用括号中的字节值。
//对括号字符也要这样做,这样就不会有歧义
//括号在日志中的含义。
outputsb->Append(“[”);
outputsb->Append((unsigned int)mychar);
outputsb->Append(“]”);
}
}

我知道我得到了什么。这样的转换函数会是什么样子?我当然不需要创建包含255个字符串的数组或switch语句吗?这是针对Java的。当我在C++/CLI中执行此操作时,字符没有定义。不幸的是,这不适用于扩展ASCII字符。即(ø或¾将转换为?).我已经在HexD中确认,这些符号在实际文件中都是以?(代码0x3F)的形式写入的。这不是关键任务,但我想知道如何解决这个问题。如果您确定设备发送的字符集和编码,并使用它而不是ASCII,这将起作用。(ASCII很少是正确答案。)注意:扩展ASCII不是特定的字符集,因此这也不是正确的答案。感谢您的帮助。为了澄清,我想了解实际编码(文本文件中的字节)的原因不匹配此范围内数组中的字节。理想情况下,我希望文本文件的输出与数组完全匹配,但如我所示显示的有限控制字符集除外。因此,当我在HexD中打开文件时,我看到的是数组中的字节,而不是(?)0x3F不明确。文本文件的接收者想要解释/显示这些字节的实际方式将取决于它们。日志文件中的编码由“log_line”的实现决定。如果没有看到它,我猜很可能是UTF-8。这很可能是正确的。我需要正确地转换它David Yaw提供的数据。非常感谢!只有一个小问题我相信我很快就会解决:错误1错误C2039:“GetChars”:不是“System::Text::Encoding::Default”的成员。我正在使用命名空间System::Text。还有什么我需要使用的吗?Encoding::Default->GetChars似乎工作得更好!所有的bytes是我想要的!再次感谢您的帮助。默认字符集可能不支持256个字符。例如,Windows-1252只有251个字符。当然,默认字符集因系统而异。
for (uint8_t i = 0; i < UART_G::message_length; i ++)
{
  unsigned char mychar = UART_G::message[i];

  if (mychar >= ' ' && mychar <= '~' && mychar != '[' && mychar != ']')
  {
    // Use the character directly for all ASCII printable characters, 
    // except '[' and ']', because those have a special meaning, below.
    outputsb->Append((System::Char)(mychar));
  }
  else if (mychar >= 128)
  {
    // Non-ASCII characters, use the default encoding to convert to Unicode.
    outputsb->Append(Encoding::Default->GetChars(UART_G::message, i, 1));
  }
  else
  {
    // Unprintable characters, use the byte value in brackets.
    // Also do this for bracket characters, so there's no ambiguity 
    // what a bracket means in the logs. 
    outputsb->Append("[");
    outputsb->Append((unsigned int)mychar);
    outputsb->Append("]");
  }
}