2014-10-03 75 views
1

我想将此pascal代码转换为C#以便与连接到通信端口的外围设备进行通信。这段代码应该计算控制字节,但是我没有得到正确的十六进制值因此我想知道如果我以正确的方式转换代码。 帕斯卡尔:帕斯卡到C#转换

begin 
    check := 255; 
    for i:= 3 to length(sequence)-4 do 
    check := check xor byte(sequence[i]); 
end; 

C#:

int check = 255; 
for (int x = 3; x < (sequence.Length - 4); x++) 
{ 
    check = check^(byte)(sequence[x]); 
} 

Pascal函数:

{ *** conversion of number into string ‘hex’ *** } 
function word_to_hex (w: word) : string; 
    var 
    i : integer; 
    s : string; 
    b : byte; 
    c : char; 
begin 
    s := ‘’; 
    for i:= 0 to 3 do 
    begin 
    b := (hi(w) shr 4) and 15; 
    case b of 
    0..9 : c := char(b+$30); 
    10..15 : c := char(b+$41-10); 
    end; 
    s := s + c; 
    w := w shl 4; 
end; 
word_ to_hex := s; 
end; 

C#等效:

 public string ControlByte(string check) 
    { 
     string s = ""; 
     byte b; 
     char c = '\0'; 
     //shift = check >> 4 & 15; 
     for (int x = 0; x <= 3; x++) 
     { 
      b = (byte)((Convert.ToInt32(check) >> 4) & 15); 

      if (b >= 0 && b <= 9) 
      { 
       c = (char)(b + 0x30); 
      } 
      else if (b >= 10 && b <= 15) 
      { 
       c = (char)(b + 0x41 - 10); 
      } 
      s = s + c; 
      check = (Convert.ToInt32(check) << 4).ToString(); 
     } 
     return s; 
    } 

而在去年帕斯卡:

function byte_to_hex (b:byte) : string; 
begin 
byte_to_hex := copy(word_to_hex(word(b)),3,2); 
end; 

我不知道如何substringing函数的结果。所以,请让我知道代码转换是否存在问题,以及是否需要将函数结果转换为字节。我很感谢你的帮助,用友。

更多信息编辑:最初我发送一个字符串序列,其中包含打印机应打印的命令和信息。由于每个序列都有一个唯一的控制字节(以十六进制表示),我必须从序列(序列=“P1; 1 $ l201PrinterPrinterPrinter1B/100.00/100.00/0/\”)计算出来,这是上层代码根据POSNET => “cc - 控制字节,按照PASCAL语言中的以下算法(见第一个代码块)”。=> 1“编码为2 HEX数字(在ESC P之后的所有字符的EXOR,以#255初始数量为该字节)。在构成控制字节的上述循环中计算的校验码应重新编码为两个HEX字符(范围内的ASCII字符'0','9','A','F','a','f' ),利用以下byte_to_hex函数:(见第三个代码块)。 => {*转换字节到2个字符*}(见第五代码块)

+3

您不会告诉我们数据类型是什么。我们不知道Pascal数组是否为零或一个基础。而且你不会告诉我们你使用什么输入数据。也不是你得到什么输出。你有没有考虑过做一些调试?这是你应该真正获得的核心技能。请使用您的IDE调试器,或添加跟踪调试。弄清楚这些节目相互分歧的地方。然后解决问题。重复,直到程序行为相同的方式。 – 2014-10-03 09:38:43

+0

此外,这两个函数转换为十六进制字符串是虚假的。有更简单的方法来完成它,并且库至少为Pascal起作用。 – 2014-10-03 09:43:22

+0

感谢David的快速回复。循环中的'序列'是一个字符串'1; 1 $ l201PrinterPrinterPrinter1B/100.00/100.00/0 /',而'check'被转换为一个字符串并作为参数传递给返回Hex值的'ControlByte'函数。就虚假而言,我从热敏打印机的Posnet手册中获得了pascal代码。我希望这些信息有助于理解问题。 – user1961008 2014-10-03 10:06:59

回答

1

最明显的问题,我可以看到的是,帕斯卡代码运行在基于1的8个编码的字符串,和C#代码在基于0的16位编码字符串上运行。要将您使用的Pascal/Delphi代码转换为C#,您需要解决不匹配问题。也许是这样的:

byte[] bytes = Encoding.Default.GetBytes(sequence); 
int check = 255; 
for (int i = 2; i < bytes.Length-4; i++) 
{ 
    check ^= bytes[i]; 
} 

现在,为了写这个,我不得不作出相当多的假设,因为你没有在附近的问题足够的代码的任何地方包括。这是我认为:

  1. 帕斯卡sequence变量是一个基于1 8位ANSI编码德尔福AnsiString
  2. Pascal check变量是德尔福32位有符号的Integer
  3. 该C#sequence变量是一个C#string

如果任何这些假设被证明是错误的,那么上面的代码将是不好的。例如,也许Pascal check确实是Byte。在这种情况下,我猜C#代码应该是:

byte[] bytes = Encoding.Default.GetBytes(sequence); 
byte check = 255; 
for (int i = 2; i < bytes.Length - 4; i++) 
{ 
    check ^= bytes[i]; 
} 

我希望这可以说明您提供完整信息的重要性。

这真是这个问题的全部内容。代码的其余部分涉及到在C#代码中将值转换为十六进制字符串。 Stack Overflow在这里一再被覆盖。例如:

有很多很多这样的问题。

+0

谢谢大卫,我会检查编码类型。我想从这个问题中解脱出来就是知道我是否正确地将Pascal转换为C#,因为这是我第一次处理这种语言。 – user1961008 2014-10-03 10:48:12

+0

David,Ansi不能在C#上工作,而Default对于'check'变量给出了和以前一样的结果。但是,我的假设是pascal中的函数word_to_hex和C#中的ControlByte不等价,并且存在问题。 – user1961008 2014-10-03 11:19:21

+0

'ControlByte'显然不等于'word_to_hex'。前者取一个字符串,后者是一个16位无符号整数,“Word”。在C#中,整个'word_to_hex'可以写成:'val.ToString(“X4”)'其中'val'是'ushort'。在Delphi中它会被写成'IntToHex(val,4)'。所有的十六进制转换代码都是假的。我建议你在我的答案结尾处阅读链接。 – 2014-10-03 11:31:42