在COBOL程序轉換爲C#中,我遇到了COMP:如何將Cobol COMP字段輸出轉換爲C#中的可讀小數?
03 Var1 PIC X(4).
03 Var2 PIC X(3).
03 Var3 PIC X(3).
03 Var4 PIC X(4).
03 Var5 PIC X(16).
03 Var6 PIC X(4).
03 Var7 PIC X(2).
03 Var8 PIC X.
03 Var9 PIC X(4).
03 Var10 PIC X(16).
03 Var11 PIC S9(7)V9(2) COMP.
03 Var12 PIC S9(7)V9(2) COMP.
03 Var13 PIC S9(7)V9(2) COMP.
03 Var14 PIC S9(7)V9(2) COMP.
03 Var15 PIC S9(7)V9(2) COMP.
03 Var16 PIC S9(7)V9(2) COMP.
03 Var17 PIC S9(7)V9(2) COMP.
03 Var18 PIC S9(7)V9(2) COMP.
03 Var19 PIC S9(7)V9(2) COMP.
03 Var20 PIC S9(7)V9(2) COMP.
03 Var21 PIC S9(7)V9(2) COMP.
03 Var22 PIC S9(7)V9(2) COMP.
03 Var23 PIC S9(7)V9(2) COMP.
03 Var24 PIC S9(7)V9(2) COMP.
我已經花了幾個小時尋找到COMP。大多數搜索會產生一些關於COMP-3的信息,或者提到COMP是二進制轉換。然而,COBOL程序的COMP輸出是非COMP場之後(之間括號):
( F 」 " )
而實際值均爲0.00,除了var13爲64.70
注意:這些是從Notepad ++複製的值。另外,請注意,我對cobol知之甚少。
如何將COMP從COMP轉換爲decimal?理想情況下,我也可以將小數轉換爲COMP,因爲我需要將事物重新放回相同的格式。
我曾嘗試閱讀作爲二進制數據提供:
public static void ReadBinaryFile(string directoryString)
{
using (BinaryReader reader = new BinaryReader(File.Open(directoryString, FileMode.Open)))
{
string myString = Encoding.ASCII.GetString(reader.ReadBytes(113));
Console.WriteLine(myString);
}
}
編輯:在正確的軌道
感謝@ piet.t和@jdweng的幫助。
雖然仍然有這個測試代碼的問題,這應該幫助任何人在我的位置上與他們的解決方案:
public static void ReadBinaryFile(string directoryString)
{
using (BinaryReader reader = new BinaryReader(File.Open(directoryString, FileMode.Open)))
{
string asciiPortion = Encoding.ASCII.GetString(reader.ReadBytes(57)); // Read the non-comp values
Console.Write(asciiPortion); // Test the ascii portion
Console.WriteLine("var11: " + reader.ReadInt32());
Console.WriteLine("var12: " + reader.ReadInt32());
Console.WriteLine("var13: " + reader.ReadInt32());
Console.WriteLine("var14: " + reader.ReadInt32());
Console.WriteLine("var15: " + reader.ReadInt32());
Console.WriteLine("var16: " + reader.ReadInt32());
Console.WriteLine("var17: " + reader.ReadInt32());
Console.WriteLine("var18: " + reader.ReadInt32());
Console.WriteLine("var19: " + reader.ReadInt32());
Console.WriteLine("var20: " + reader.ReadInt32());
Console.WriteLine("var21: " + reader.ReadInt32());
Console.WriteLine("var22: " + reader.ReadInt32());
Console.WriteLine("var23: " + reader.ReadInt32());
Console.WriteLine("var24: " + reader.ReadInt32());
}
}
編輯2:試圖找到問題
問題:每個值看起來都跟着一些垃圾值,它被打印爲下一個int32。
實際值:
var11 = var12 = 0.00
var13 = 58.90
var14 = 0.00
var15 = -0.14
var16 = 0.00
var17 = var18 = var19 = var20 = 0.00
var21 = var22 = var23 = var24 = 0.00
輸出(與填充):
Var11: 0 HEX: 00000000 BIN: 00000000000000000000000000000000
Var12: 0 HEX: 00000000 BIN: 00000000000000000000000000000000
Var13: 5890 HEX: 00001702 BIN: 00000000000000000001011100000010
Var14: 368 HEX: 00000170 BIN: 00000000000000000000000101110000
Var15: -14 HEX: FFFFFFF2 BIN: 11111111111111111111111111110010
Var16: -1 HEX: FFFFFFFF BIN: 11111111111111111111111111111111
Var17: 0 HEX: 00000000 BIN: 00000000000000000000000000000000
Var18: 0 HEX: 00000000 BIN: 00000000000000000000000000000000
Var19: 0 HEX: 00000000 BIN: 00000000000000000000000000000000
Var20: 0 HEX: 00000000 BIN: 00000000000000000000000000000000
Var21: 0 HEX: 00000000 BIN: 00000000000000000000000000000000
Var22: 0 HEX: 00000000 BIN: 00000000000000000000000000000000
Var23: 0 HEX: 00000000 BIN: 00000000000000000000000000000000
Var24: 0 HEX: 00000000 BIN: 00000000000000000000000000000000
記事本++(複印)表示:
p òÿÿÿÿÿÿÿ
記事本++(視覺)表示:
[NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL][STX][ETB][NUL][NUL]p[SOH]
[NUL][NUL]òÿÿÿÿÿÿÿ[NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL]
[NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL]
[NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL][LF]
編輯3:解決方案!
@ piet.t說得沒錯。感謝我的第一個問題的有用答案!這個問題是cobol計劃特有的。我帶領相信Var14總是0,但:
Var14 = SomeCalculationIHadNoIdeaAbout(Var13, SomeOtherNumber);
我用RecordEdit更輕鬆地調整數據(警告:程序中有些地方有點怪),發現在「垃圾」一個奇怪的趨勢值。
我的問題的真正解決方案是第一次編輯中的代碼,這是我在前幾天編寫的:/。
注意:我還必須使用一個換行符,我沒有在該代碼中放入。要做到這一點,只需添加另一個reader.ReadBytes(1);
。注2:您可能需要查看EBDCDIC和/或Endianness,這可能會使您的解決方案比我的更難一些。
使用BitConverter。可能需要使用Big或Little Endian,因爲IBM通常是從Microsoft退後。它看起來像Cobol使用標準的4/8字節IEEE格式的浮點數。請參閱IBM:https://www.ibm.com/support/knowledgecenter/en/SS6SG3_3.4.0/com.ibm.entcobol.doc_3.4/cpari09.htm – jdweng
如果我的理解正確,那麼您的意思是我想要一次讀取我的數據4(或8)個字節,將Little Endian轉換爲Big Endian,然後轉換爲十進制? – JinC
我假設你有4個字節,你是二進制的。由於它在文件中,所以必須將ascii解析爲字節。然後使用BitConverter將字節轉換爲float/double。 – jdweng