2014-10-03 67 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