Странное поведение при преобразовании байта из текстового поля в байтовый массив в символы? - PullRequest
3 голосов
/ 01 июня 2011

У меня есть текстовое поле, которое я использую для преобразования таких вещей, как:

74 00 65 00 73 00 74 00

Снова в строку, выше говорит «тест», но по какой-то причине, когда я нажимаю кнопку конвертировать, он будет отображать толькопервая буква "t" 74 00 и другие байтовые массивы работают так же, как и ожидалось, весь текст преобразуется.

Вот 2 кода, которые я пробовал, которые приводят к тому же самому поведению при неправильном преобразовании всего байтового массивак слову:

byte[] bArray = ByteStrToByteArray(iSequence.Text);
ASCIIEncoding enc = new ASCIIEncoding();
string word = enc.GetString(bArray);
iResult.Text = word + Environment.NewLine;

, который использует функцию:

private byte[] ByteStrToByteArray(string byteString)
{
    byteString = byteString.Replace(" ", string.Empty);
    byte[] buffer = new byte[byteString.Length / 2];
    for (int i = 0; i < byteString.Length; i += 2)
        buffer[i / 2] = (byte)Convert.ToByte(byteString.Substring(i, 2), 16);
    return buffer;
}

другой способ, который я использовал, это:

string str = iSequence.Text.Replace(" ", "");
byte[] bArray = Enumerable.Range(0, str.Length)
                            .Where(x => x % 2 == 0)
                            .Select(x => Convert.ToByte(str.Substring(x, 2), 16))
                            .ToArray();
ASCIIEncoding enc = new ASCIIEncoding();
string word = enc.GetString(bArray);
iResult.Text = word + Environment.NewLine;

Попытка проверки длины, чтобы увидетьесли он проходил итерацию, и это было ...

Не знаю, как отладить, почему это происходит с вышеуказанным байтовым массивом, но все остальные байтовые массивы, кажется, работали просто отлично, только этотвыводя только первую букву.

Я сделал что-то не так, что может как-то вызвать такое поведение?Что я могу попробовать, чтобы выяснить, что не так?

Ответы [ 4 ]

9 голосов
/ 01 июня 2011

Если у вас есть последовательность байтов

var bytes = new byte[] { 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00 };

и вы декодируете его в строку, используя кодировку ASCII ( Encoding.ASCII ), тогда вы получаете

var result = Encoding.ASCII.GetString(bytes);
// result == "\x74\x00\x65\x00\x73\x00\x74\x00" == "t\0e\0s\0t\0"

Обратите внимание на ноль \0 символов? При отображении такой строки в текстовом поле отображается только часть строки до первого символа Null.

Поскольку вы говорите, что результат должен читаться как "test", входные данные на самом деле кодируются не в ASCII, а в UTF-16LE ( Encoding.Unicode ).

var result = Encoding.Unicode.GetString(bytes);
// result == "\u0074\u0065\u0073\u0074" == "test"
1 голос
/ 01 июня 2011

вы конвертируете строку юникода в ascii, вы не указываете кодовую страницу на вашем компьютере для конвертации.System.Text.Encoding.GetEncoding("codepage").GetString() если память мне не изменяетТакже следует отметить, что любой элемент управления в .NET является Unicode ... Soooooo .... что вы пытаетесь вставить в текстовое поле (если преобразование выполнено правильно) может быть символом конца строки .. или eof, или любого другого видаконтрольного характера.все зависит от вашей кодовой страницы.

0 голосов
/ 08 августа 2012

у меня работает:

string outputText = "t\0e\0s\0t";
outputText = outputText.Replace("\0", " ");
0 голосов
/ 01 июня 2011

Я попытался отладить первую программу, используя точки останова в VS2010. Я узнал, что линия

string word = enc.GetString(bArray);

вывод слово как "t \ 0e \ 0s \ 0t".

Последняя строка

iResult.Text = word + Environment.NewLine;

дает iResult.Text просто " t ".

Так что я подумал, что \ 0 не является допустимой escape-последовательностью, компилятор игнорировал все после нее. Возможно, это неправильно, но попробуйте удалить все вхождения 00 во входной строке.

Я не очень люблю C #. Я только предлагаю это, потому что это похоже на C ++.

...