ASCII到十六进制的C#代码问题。需要洞察

ASCII到十六进制的C#代码问题。需要洞察,c#,visual-studio-2010,C#,Visual Studio 2010,我正在做我的大学项目,面临一个大问题。我正在C#visual studio 2010上开发UI。我需要打开一个串行连接,并将一些值输入微控制器。基本上我有24位地址(3字节)的节点,例如0x78A26F 我在GUI中的文本框中获取用户的输入。用户应输入此78A26F,我希望串行端口发送以下数据0x6F 0xA2 0x78 但是用户输入保存为字符串,当我通过串行连接发送它时,会发送ASCII,例如0x37 0x38 0x41 0x32 0x36 0x46。我可以在uC中进行处理,并执行一些检查,以

我正在做我的大学项目,面临一个大问题。我正在C#visual studio 2010上开发UI。我需要打开一个串行连接,并将一些值输入微控制器。基本上我有24位地址(3字节)的节点,例如0x78A26F

我在GUI中的文本框中获取用户的输入。用户应输入此78A26F,我希望串行端口发送以下数据0x6F 0xA2 0x78

但是用户输入保存为字符串,当我通过串行连接发送它时,会发送ASCII,例如0x37 0x38 0x41 0x32 0x36 0x46。我可以在uC中进行处理,并执行一些检查,以在0x30和0x39之间减去0x30,或者在0x41和0x46之间减去0x37。但我不想使用uC进行这种计算。我想在GUI c#中实现一些算法来发送正确的十六进制值。所以我写了下面的程序。但是我犯了一个错误。“值对于无符号字节来说太大或太小。”在代码行声明(数据[2-i]=Convert.ToByte(x*16+y))

我无法理解这个问题,现在已经受够了,因为这在任何情况下都不应该发生。 如果有人能在这方面帮助我,无论是用这段代码还是任何其他算法/方法,我都会非常感激。拜托,我宁愿不要在uC上实现一些algo

谢谢

马莱哈

    /***********************************************************************/
    /*The code for opening the serial connection and converting it appropriately*/
    /***********************************************************************/
    byte[] conversion()
    {
        string text = label16.Text.ToUpper(); // if user enters not capital letters
        byte[] data = new byte[3];

        int x, y;
        bool valid;

        for (int i = 2; i >= 0; i--)
        {
            valid = true;
            x = (Convert.ToInt32(Convert.ToChar(text[2 * i + 1]))); 
            y = (Convert.ToInt32(Convert.ToChar(text[2 * i]))); // I want to first send the 0x6F then 0xA2 and finally 0x78. ToChar is so that i can check for A-F

            if(x >= 48 || x <= 57) // i,e it is already a number
                x = Convert.ToInt32(text[2 * i + 1]);
            else if (x >= 65 || x <= 70) // it is between A-F
                x = x - 55; // in case of A, i get 10
            else // any other value i.e greater than F or any other.
            {
                valid = false;
                break;
            }

            if (y >= 48 || y <= 57) // same for y
                y = Convert.ToInt32(text[2 * i]);
            else if (y >= 65 || y <= 70)
            y = y - 55;
            else
            {
                valid = false;
                break;
            }

            if (valid == true)
               data[2 - i] = Convert.ToByte(x*16 + y); // max will be 15*16 + 15 = 255 which should be OK for convert.ToByte.  
        }
        return data;
    }

    void serial(byte[] text)
    {
        SerialPort serialPort1 = new SerialPort();
        //configuring the serial port
        serialPort1.PortName = "COM1";
        serialPort1.BaudRate = 9600;
        serialPort1.DataBits = 8;
        serialPort1.Parity = Parity.None;
        serialPort1.StopBits = StopBits.One;

        //opening the serial port
        serialPort1.Open();

        //write data to serial port
        serialPort1.Write(text, 0, 3);

        //close the port
        serialPort1.Close();
    }
    /***********************************************************************/

    private void button3_Click(object sender, EventArgs e)
    {
        byte[] data = conversion();
        serial(data);
    }
/***********************************************************************/
/*用于打开串行连接并进行适当转换的代码*/
/***********************************************************************/
字节[]转换()
{
string text=label16.text.ToUpper();//如果用户输入的不是大写字母
字节[]数据=新字节[3];
int x,y;
布尔有效;
对于(int i=2;i>=0;i--)
{
有效=真;
x=(Convert.ToInt32(Convert.ToChar(text[2*i+1]));
y=(Convert.ToInt32(Convert.ToChar(text[2*i]));//我想先发送0x6F,然后发送0xA2,最后发送0x78。ToChar是为了检查A-F

如果(x>=48 | | | x=65 | | x=48 | | y=65 | | y您对Convert.ToInt32()的调用没有执行您认为它正在执行的操作

下面概述Convert.ToInt32()的不同用法:


逻辑有三个问题:

请看你的if语句,确定x和y是否落在一定的数字范围内。考虑x=100时会发生什么。记住“是”或“”。< /P>
  • 如果x或y是使用Convert.ToInt32()表示数字的字符,则转换需要采用字符串,而不是字符,才能获得所需的转换

  • 一旦通过这两个步骤,检查conversion()方法的输出。您应该注意最后一个问题

  • 你能用这个吗

    byte[]转换()
    {
    字符串text=label16.text;
    对于(int i=0;i
    不是最干净的代码,但你知道了。 您应该将
    data[i/2]=Convert.ToByte(hex,16);
    行包装在try-catch中,但我不确定您是要对该行进行包装,还是只在try-catch中调用该方法


    代码中的问题似乎是将字符直接转换为int的
    x=Convert.ToInt32(text[2*i+1]);
    y=Convert.ToInt32(text[2*i]);
    行。要使解决方案起作用,应该执行类似
    x=(byte)text[2*i+1]的操作-48;

    .NET framework已经支持转换十六进制字符串。请使您的代码如下所示:

            uint value;
            if (!uint.TryParse(label16.Text,     // Ought to be a text box
                   System.Globalization.NumberStyles.HexNumber, null, out value)) {
                MessageBox.Show("Invalid hex value");
                return;
            }
            serialPort1.Write(BitConverter.GetBytes(value), 0, 3);
    

    嗨。但这并没有纠正它。当我写的时候,16。还有一个whish表示无效参数。@Malehatabasam,这是因为您可能仍在转换为Char作为第一个参数。请注意,该方法需要一个字符串,而不是Char。这里的其他答案指向您更有效的解决方案,但了解您拥有的代码比简单地获取一个固定的解决方案更有价值。我建议您先让您的解决方案工作,然后在这里探索其他答案,看看如何简化此转换。我从您提供的链接中获得了一个示例,该链接拆分字符串,然后转换为字符串。但我无法拆分我的字符串因为我的字符串中没有delimeter,所以每对字符都是delimeter.lolx。有什么建议吗?不管怎样,我设法让它工作了(我想是的)由hans编写的代码。但正如你所说,我也想提高对我的代码的理解,无论我是否编写了正确的算法。非常感谢。@Malehatabasam我已经用一些具体的提示更新了答案,以帮助你编写代码。嗨,hans。非常感谢。对此非常满意。只是为了确保我编写了它…当用户输入此代码时,78A26F,我处理这个coe,并将结果打印在conole中,还按顺序输入。控制台输出是“7905903”,这对我来说没有意义。但输出到另一台pc的超级终端是“o¢x”这是有道理的。因为x代表78,o代表6F,中间的字符可能代表A2。有没有办法检查A2是否对应?我认为这也是正确的。因为扩展ASCII对应于我在超级终端上看到的A2的相同字符。谢谢你的帮助。将0x78a26f转换为十进制。是的,它是7905903。嗨,汉斯,工作正常,但发生了一些奇怪的事情。控制台仍显示相同的7905903。但现在超级终端显示为o“x.即中间字符已更改。它对应于22,而不是A2。您是否遇到过此类问题?避免将二进制数据视为字符串。对于未映射到ASCII值的字节,您将获得非常任意的字符。22是
            uint value;
            if (!uint.TryParse(label16.Text,     // Ought to be a text box
                   System.Globalization.NumberStyles.HexNumber, null, out value)) {
                MessageBox.Show("Invalid hex value");
                return;
            }
            serialPort1.Write(BitConverter.GetBytes(value), 0, 3);