将字符追加到 StringBuilder C++/CLI
Append Char To StringBuilder C++/CLI
我正在尝试使用 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());
}
我希望所有纯文本字符(例如 A、:)都作为文本发送,而功能字符(例如 BEL、NEWLINE)将像 [7][13] 一样发送。
发生的事情是,在所有情况下,StringBuilder 都将字符输出为数字。例如,A 被发送为 65。
例如,如果我的字节数组中有字符串 'APPLE' 和换行符,我想看到:
Sent APPLE[13]
相反,我看到:
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());
}
我仍然欣赏任何更有效或更易于阅读的替代方案。
您正在获取 ASCII 值,因为编译器正在选择 Append overloads that takes an integer of some sort. To fix this, you could do a explicit cast to System::Char
, to force the correct overload 之一。
但是,这不一定会给出 128-255 的正确结果。您可以在从 Byte
到 Char
的范围内输入一个值,它会给出 某些东西 ,但不一定是您所期望的。首先,0x80 到 0x9F 是控制字符,无论您从哪里获取字节,都可能不会像 Unicode 那样使用 0xA0 到 0xFF 的相同表示。
在我看来,最好的解决方案是对 0x80 到 0xFF 的其他控制字符也使用“[value]”语法。但是,如果您确实想将它们转换为字符,我会使用 Encoding::Default
,而不是 Encoding::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("]");
}
}
我正在尝试使用 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());
}
我希望所有纯文本字符(例如 A、:)都作为文本发送,而功能字符(例如 BEL、NEWLINE)将像 [7][13] 一样发送。
发生的事情是,在所有情况下,StringBuilder 都将字符输出为数字。例如,A 被发送为 65。
例如,如果我的字节数组中有字符串 'APPLE' 和换行符,我想看到:
Sent APPLE[13]
相反,我看到:
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());
}
我仍然欣赏任何更有效或更易于阅读的替代方案。
您正在获取 ASCII 值,因为编译器正在选择 Append overloads that takes an integer of some sort. To fix this, you could do a explicit cast to System::Char
, to force the correct overload 之一。
但是,这不一定会给出 128-255 的正确结果。您可以在从 Byte
到 Char
的范围内输入一个值,它会给出 某些东西 ,但不一定是您所期望的。首先,0x80 到 0x9F 是控制字符,无论您从哪里获取字节,都可能不会像 Unicode 那样使用 0xA0 到 0xFF 的相同表示。
在我看来,最好的解决方案是对 0x80 到 0xFF 的其他控制字符也使用“[value]”语法。但是,如果您确实想将它们转换为字符,我会使用 Encoding::Default
,而不是 Encoding::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("]");
}
}