我正在尝试用C语言实现在COBOL中使用的REDEFINES逻辑。

以下是COBOL程序:

   IDENTIFICATION DIVISION.
   ENVIRONMENT DIVISION.
   DATA DIVISION.
   WORKING-STORAGE SECTION.

   01  DATE-MMDDYY.
       10  DATE-MM               PIC 9(02).
       10  DATE-DD               PIC 9(02).
       10  DATE-YY               PIC 9(02).
   01  SYSTEM-DATE-MMDDYY REDEFINES DATE-MMDDYY PIC X(6).

   PROCEDURE DIVISION.

       MOVE '011817' TO SYSTEM-DATE-MMDDYY.
       DISPLAY 'SYSTEM-DATE-MMDDYY: ' SYSTEM-DATE-MMDDYY.
       DISPLAY 'DATE-MM: ' DATE-MM.
       DISPLAY 'DATE-DD: ' DATE-DD.
       DISPLAY 'DATE-YY: ' DATE-YY.

       DISPLAY 'CHANGING DATE-YY = 18'
       MOVE '18' TO DATE-YY.
       DISPLAY 'New SYSTEM-DATE-MMDDYY: ' SYSTEM-DATE-MMDDYY.

       STOP RUN.


下面是上面程序的执行:

SYSTEM-DATE-MMDDYY: 011817
DATE-MM: 01
DATE-DD: 18
DATE-YY: 17
CHANGING DATE-YY = 18
New SYSTEM-DATE-MMDDYY: 011818


我知道C语言中的UNION可以用来实现类似的功能。但这对我不起作用。

下面是我写的C程序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

union redef
{
        struct date_mmddyy{
                char date_mm[2];
                char date_dd[2];
                char date_yy[2];
        }date_mmddyy;
        char system_date_mmddyy[6];
};
typedef union redef redef;
int main(){
        redef redef;
        strcpy(redef.date_mmddyy.date_mm, "01");
        strcpy(redef.date_mmddyy.date_dd, "18");
        strcpy(redef.date_mmddyy.date_yy, "17");
        printf("%s\n",redef.date_mmddyy.date_mm);
        printf("%s\n",redef.date_mmddyy.date_dd);
        printf("%s\n",redef.date_mmddyy.date_yy);
        printf("%s\n",redef.system_date_mmddyy);

        strcpy(redef.system_date_mmddyy, "021918");
        printf("%s\n",redef.date_mmddyy.date_mm);
        printf("%s\n",redef.date_mmddyy.date_dd);
        printf("%s\n",redef.date_mmddyy.date_yy);
        printf("%s\n",redef.system_date_mmddyy);

        return 0;
}


它运行如下:

011817
1817
17
011817
021918
1918
18
021918


能否请您分享一些想法?

更新1:

我已经用\0终止了所有char数组。以下是更改后的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

union redef
{
        struct date_mmddyy{
                char date_mm[3];
                char date_dd[3];
                char date_yy[3];
        }date_mmddyy;
        char system_date_mmddyy[7];
};
typedef union redef redef;
int main(){
        redef redef;
        redef.date_mmddyy.date_mm[2] = '\0';
        redef.date_mmddyy.date_dd[2] = '\0';
        redef.date_mmddyy.date_yy[2] = '\0';
        redef.system_date_mmddyy[6] = '\0';

        strcpy(redef.date_mmddyy.date_mm, "01");
        strcpy(redef.date_mmddyy.date_dd, "18");
        strcpy(redef.date_mmddyy.date_yy, "17");
        printf("%s\n",redef.date_mmddyy.date_mm);
        printf("%s\n",redef.date_mmddyy.date_dd);
        printf("%s\n",redef.date_mmddyy.date_yy);
        printf("%s\n",redef.system_date_mmddyy);

        strcpy(redef.system_date_mmddyy, "021918");
        printf("%s\n",redef.date_mmddyy.date_mm);
        printf("%s\n",redef.date_mmddyy.date_dd);
        printf("%s\n",redef.date_mmddyy.date_yy);
        printf("%s\n",redef.system_date_mmddyy);

        return 0;
}


下面是执行:

01
18
17
01
021918
918

021918


输出与COBOL中的输出相去甚远。

最佳答案

如果要在C中使用COBOL中的REDEFINE逻辑,则只有一个选择:不要将C字符串用于COBOL存储,因为COBOL数据仅使用字符数组作为数据结构。
和:
注意structure padding(对于未声明为PIC X的任何项目)!

这将导致类似

#include <stdio.h>

union redef
{
        struct date_mmddyy{
               char date_mm[2];
               char date_dd[2];
               char date_yy[2];
        }date_mmddyy;
        char system_date_mmddyy[6];
};
typedef union redef redef;
int main(){
        redef redef;
        redef.date_mmddyy.date_mm[0] = '0';
        redef.date_mmddyy.date_mm[1] = '1';
        redef.date_mmddyy.date_dd[0] = '1';
        redef.date_mmddyy.date_dd[1] = '8';
        redef.date_mmddyy.date_yy[0] = '1';
        redef.date_mmddyy.date_yy[1] = '7';
        // or:
        memcpy((void *)redef.date_mmddyy, (void *)"011817", 6);

        printf("%c%c\n",redef.date_mmddyy.date_mm[0],
                        redef.date_mmddyy.date_mm[1]);
        [...]


为了使此功能实际可用,您可能会使用两件事:


除了包含数据的结构外,还添加一个字段结构,该字段结构至少包含一个指向存储的指针,大小和类型(在示例中,“ x”和“ numeric-display”就足够了)
添加辅助函数以设置/获取字段值


就像是

#include <stdio.h>

enum cob_type {
    T_DISPLAY = 0,
    T_NUMERIC_DISPLAY
};

struct cob_field{
       char *data;
       int size;
       enum cob_type;
};

/* one for the actual storage - could be a simple unnamed char array */
struct date_mmddyy{
       char date_mm[2];
       char date_dd[2];
       char date_yy[2];
} date_mmddyy;

/* fields with pointers to the storage and the size */
cob_field date_mmddyy = {&date_mmddyy, 6, T_DISPLAY};
cob_field date_mm     = {&date_mmddyy.date_mm, 2, T_NUMERIC_DISPLAY};
cob_field date_dd     = {&date_mmddyy.date_dd, 2, T_NUMERIC_DISPLAY};
cob_field date_yy     = {&date_mmddyy.date_yy, 2, T_NUMERIC_DISPLAY};
cob_field system_date_mmddyy = {&date_mmddyy, 6, T_DISPLAY};

int main(){
        set_field_data(system_date_mmddyy, "011817");
        printf("SYSTEM-DATE-MMDDYY: %s\n', get_field_data(system_date_mmddyy));
        printf("DATE-MM: %s\n', get_field_data(date_mm));
        printf("DATE-DD: %s\n', get_field_data(date_dd));
        printf("DATE-YY: %s\n', get_field_data(date_yy));

        puts("CHANGING DATE-YY = 18");
        set_field_data(date_yy, "18");
        printf("SYSTEM-DATE-MMDDYY: %s\n', get_field_data(system_date_mmddyy));

        return 0;
}


鉴于COBOL具有许多不同的类型,您需要在辅助函数中编写很多逻辑-这里void set_field (cob_field *f, char *data)char *get_field (cob_field *f)所需的逻辑非常简单,当使用所有COBOL具有的类型时,这种变化会变得更加复杂。使用超过原义的MOVE(添加隐式类型转换)和DISPLAY

顺便说一句:您可能要检查GnuCOBOL-它会将COBOL转换为C ...

关于c - 在C中实现COBOL REDEFINES,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41724735/

10-11 20:57