首页 > 解决方案 > 在结构中读取 Txt 文件 - 如何在 C#.net 中读取结构中 Cobol 的 Occur 子句

问题描述

我正在阅读一个 cobol 程序成功读取的文本文件。我正在使用 Struct 在 c#.net 中编写替换代码。这是我正在使用的参考。https://www.codeproject.com/Articles/7357/How-to-copy-a-String-into-a-struct-using-C

这是cobol

  05  NUM           PIC X(6)
  05  FLAG          PIC XX
  05  IP            PIC X(12)

这是 C#.net

    public struct ORDER
    {

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)] public string NUM;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 2)] public string FLAG;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 12)] public string CUSIP;

    }

到目前为止,我能够正确读取变量到从文本文件第一行开始的 x 位置。

我的输出也匹配;但是这个 Cobol 程序块有 OCCUR 子句,我想弄清楚;我如何将其添加到我在上面共享的 ORDER 结构中。

  05  AN-AREA.
      10  COST        OCCURS 5 TIMES.
          15 TYPE     PIC XX.
          15 ISO      PIC XXX.
          15 CODE     PIC X(6).
          15 IND-X
                      PIC XX.
          15 IND
                      REDEFINES 
                      IND-X
                      PIC 99.
          15 AMT      PIC X(20).

标签: c#cobol

解决方案


我正在阅读一个文本文件,我必须假设它的记录由 CR+LF(或 LF)分隔。我创建了一个包含三个记录的测试数据文件,并用于StreamReader处理该文件。

重要提示:创建文件的程序可能会使用截断的尾随空格。在这种情况下,有必要在记录中添加空格以达到 185 个字符,然后再将其分开。

我使用了 aClass而不是struct,因为似乎没有什么需要unmanaged类型。我曾经Substring打破记录。

由于主要关注的是如何实现该OCCURS子句,因此我将展示我是如何使用嵌套Class数组来实现的。

简单地说,我的目标是展示它是如何完成的。以此为出发点,其他人可能会建议更改如何完成。接受他们的建议。


程序:

using System;
using System.IO;

namespace ConsoleApp2
{
    class Program
    {
        static void Main(string[] args)
        {
            using (StreamReader sr = new StreamReader(File.Open(@"z:\data.txt", FileMode.Open)))
            {
                string s;
                while ((s = sr.ReadLine()) != null)
                {
                    if (s.Length != 185)
                    {
                        Console.WriteLine("Wrong length record");
                    }
                    else
                    {
                        Order c = new Order();
                        c.NUM = s.Substring(0, 6);
                        c.FLAG = s.Substring(6, 2);
                        c.IP = s.Substring(8, 12);
                        for (int i = 0, idx = 20; i < 5; i++, idx += 33)
                        {
                            c.AN_AREA[i] = new Order.COST();
                            c.AN_AREA[i].TYPE = s.Substring(idx, 2);
                            c.AN_AREA[i].ISO = s.Substring(idx + 2, 3);
                            c.AN_AREA[i].CODE = s.Substring(idx + 5, 6);
                            c.AN_AREA[i].IND_X = s.Substring(idx + 11, 2);
                            c.AN_AREA[i].AMT = s.Substring(idx + 13, 20);
                        }
                        Console.WriteLine(c.NUM);
                        Console.WriteLine(c.FLAG);
                        Console.WriteLine(c.IP);
                        for (int i = 0; i < 5; i++)
                        {
                            Console.WriteLine(c.AN_AREA[i].TYPE);
                            Console.WriteLine(c.AN_AREA[i].ISO);
                            Console.WriteLine(c.AN_AREA[i].CODE);
                            Console.WriteLine(c.AN_AREA[i].IND_X);
                            Console.WriteLine(c.AN_AREA[i].AMT);
                        }
                    }
                    Console.WriteLine("--------------------");
                }
            }
            Console.ReadLine();
        }
    }

    public class Order
    {
        public string NUM;       //05  NUM PIC X(6)
        public string FLAG;      //05  FLAG PIC XX
        public string IP;        //05  IP PIC X(12)
                                 //05  AN-AREA.
        public COST[] AN_AREA = new COST[5]; //10  COST OCCURS 5 TIMES.
        public class COST
        {
            public string TYPE;  //15 TYPE PIC XX.
            public string ISO;   //15 ISO PIC XXX.
            public string CODE;  //15 CODE PIC X(6).
            public string IND_X; //15 IND-X
                                 //    PIC XX.
                                 //15 IND
                                 //      REDEFINES
                                 //      IND-X
                                 //      PIC 99.
            public string AMT;   //15 AMT PIC X(20).
        }
    }
}

使用的数据:

AAAAAABBCCCCCCCCCCCCDDEEEFFFFFFGGHHHHHHHHHHHHHHHHHHHHIIJJJKKKKKKLLMMMMMMMMMMMMMMMMMMMMNNOOOPPPPPPQQRRRRRRRRRRRRRRRRRRRRSSTTTUUUUUUVVWWWWWWWWWWWWWWWWWWWWXXYYYZZZZZZaabbbbbbbbbbbbbbbbbbbb
aaaaaabbccccccccccccddeeeffffffgghhhhhhhhhhhhhhhhhhhhiijjjkkkkkkllmmmmmmmmmmmmmmmmmmmmnnoooppppppqqrrrrrrrrrrrrrrrrrrrrsstttuuuuuuvvwwwwwwwwwwwwwwwwwwwwxxyyyzzzzzzAABBBBBBBBBBBBBBBBBBBB
123

输出:

AAAAAA
BB
CCCCCCCCCCCC
DD
EEE
FFFFFF
GG
HHHHHHHHHHHHHHHHHHHH
II
JJJ
KKKKKK
LL
MMMMMMMMMMMMMMMMMMMM
NN
OOO
PPPPPP
QQ
RRRRRRRRRRRRRRRRRRRR
SS
TTT
UUUUUU
VV
WWWWWWWWWWWWWWWWWWWW
XX
YYY
ZZZZZZ
aa
bbbbbbbbbbbbbbbbbbbb
--------------------
aaaaaa
bb
cccccccccccc
dd
eee
ffffff
gg
hhhhhhhhhhhhhhhhhhhh
ii
jjj
kkkkkk
ll
mmmmmmmmmmmmmmmmmmmm
nn
ooo
pppppp
qq
rrrrrrrrrrrrrrrrrrrr
ss
ttt
uuuuuu
vv
wwwwwwwwwwwwwwwwwwww
xx
yyy
zzzzzz
AA
BBBBBBBBBBBBBBBBBBBB
--------------------
Wrong length record
--------------------

推荐阅读