将字符附加到StringBuilder C++/CLI
我试图使用StringBuilder创建通过串行端口发送的日志文件输出。输出存储在一个字节数组中,我正在递归它将字符附加到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
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("]");
}
}