在C中实现COBOL重定义

在C中实现COBOL重定义,c,struct,cobol,unions,C,Struct,Cobol,Unions,我试图用C语言实现COBOL中使用的重定义逻辑 以下是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).

我试图用C语言实现COBOL中使用的重定义逻辑

以下是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;
}
你能分享一些想法吗

更新1:

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

#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;
}

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

问题在于输出本身。在C语言中,所有字符串(至少是要使用printf(“%s”,…)打印的字符串)的结尾都需要0字节。由于“字符串”的固定长度为2或6个字节,这将不起作用,因为每个2字节的“字符串”都需要第三个字节来完成字符串

因此,实际上它是“工作”的,但是结果是一个字符数组,这与C中的字符串不同,因此不能使用通常的字符串操作

这不是你想听到的,但我建议你忘记字符串,使用整数,使用转换函数。比如说

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

struct Date {
    int day, month, year;
};

void dateFromString(char* input, struct Date* output) {
    char tmp[3];
    tmp[2] = '\0';
    memcpy(tmp, &input[0], 2);
    output->day = atoi(tmp);
    memcpy(tmp, &input[2], 2);
    output->month = atoi(tmp);
    memcpy(tmp, &input[4], 2);
    output->year = atoi(tmp);
}

void stringFromDate(struct Date* input, char* output) {
    sprintf(output,"%02i%02i%02i",input->day,input->month,input->year);
}

int main() {
    char text[] = "120456";
    struct Date d;
    dateFromString(text, &d);

    printf("%i\n",d.day);
    printf("%i\n",d.month);
    printf("%i\n",d.year);

    char buffer[7];
    stringFromDate(&d,buffer);
    printf("%s\n",buffer);
}
#包括
#包括
#包括
结构日期{
整数日、月、年;
};
void dateFromString(字符*输入,结构日期*输出){
char-tmp[3];
tmp[2]='\0';
memcpy(tmp,&input[0],2);
输出->日=atoi(tmp);
memcpy(tmp和输入[2],2);
输出->月=atoi(tmp);
memcpy(tmp和输入[4],2);
输出->年=atoi(tmp);
}
void stringFromDate(结构日期*输入,字符*输出){
sprintf(输出,“%02i%02i%02i”,输入->天,输入->月,输入->年);
}
int main(){
字符文本[]=“120456”;
结构日期d;
dateFromString(文本,&d);
printf(“%i\n”,d.day);
printf(“%i\n”,d.month);
printf(“%i\n”,d.year);
字符缓冲区[7];
stringFromDate(&d,缓冲区);
printf(“%s\n”,缓冲区);
}

您的工会正在运作。该问题源于显示结构字段时字符串中缺少空终止符字符

如果你不想修改你的结构,也许你可以修改格式限定符

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

如果要使用C中COBOL的
重定义
逻辑,只有一个选项:不要将C字符串用于COBOL存储,因为COBOL数据只使用字符数组作为数据结构。
以及:
注意(对于未声明为
PICX
的任何项目)

这将导致类似于

#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]);
        [...]
#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;
}
#包括
联合雷德夫
{
结构日期_mmddyy{
字符日期_mm[2];
char date_dd[2];
char date_yy[2];
}日期_mmddyy;
字符系统_date_mmddyy[6];
};
typedef union redef redef 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”;
//或:
memcpy((无效*)redef.date_mmddyy,(无效*)“011817”,6);
printf(“%c%c\n”,redef.date\u mmddyy.date\u mm[0],
重新定义日期(年月日[1]);
[...]
要使其实际可用,您可能需要使用两种方法:

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

#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]);
        [...]
#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;
}
#包括
枚举cob_类型{
T_显示=0,
数字显示
};
结构cob_字段{
字符*数据;
整数大小;
枚举cob_类型;
};
/*一个用于实际存储—可以是一个简单的未命名字符数组*/
结构日期_mmddyy{
字符日期_mm[2];
char date_dd[2];
char date_yy[2];
}日期_mmddyy;
/*带有指向存储和大小的指针的字段*/
cob_字段date_mmddyy={&date_mmddyy,6,T_DISPLAY};
cob_字段date_mm={&date_mmddyy.date_mm,2,T_NUMERIC_DISPLAY};
cob_字段date_dd={&date_mmddyy.date_dd,2,T_NUMERIC_DISPLAY};
cob_字段date_yy={&date_mmddyy.date_yy,2,T_NUMERIC_DISPLAY};
cob_字段系统_date_mmddyy={&date_mmddyy,6,T_DISPLAY};
int main(){
设置字段数据(系统日期“011817”);
printf(“SYSTEM-DATE-MMDDYY:%s\n”,获取字段数据(SYSTEM-DATE-MMDDYY));
printf(“日期-MM:%s\n”,获取字段数据(日期-MM));
printf(“日期-DD:%s\n”,获取字段数据(日期-DD));
printf(“日期-YY:%s\n”,获取字段数据(日期-YY));
看跌期权(“变更日期-YY=18”);
设置字段数据(日期“18”);
printf(“SYSTEM-DATE-MMDDYY:%s\n”,获取字段数据(SYSTEM-DATE-MMDDYY));
返回0;
}
考虑到COBOL有许多不同的类型,您需要在助手函数中编写大量的逻辑-这里需要的是
void set_字段(cob_字段*f,char*data)
char*get_字段(cob_字段*f)
非常简单,当使用COBOL拥有的所有类型时,这一点会发生变化,当使用比从文本(添加隐式类型转换)和显示
更多的
时,会变得更加复杂


你想检查一下,它把COBOL翻译成C…/P>没有语言,叫做C/C++。C或C++。你写的(和问的是C。是的,我知道:)。我提到它只是为了标记目的。谢谢。RHIT不要垃圾邮件标签。只标注相关的。C++与你的问题无关。(SourceForge.Net)编译为C。您可以获得一个副本,为您的COBOL程序生成C代码,然后看看如何处理更现实的重新定义。第一个联合是正确的,但COBOL PIC X(nn)字段不是以NUL结尾的,因此使用strcpy将无法正常工作。您可以使用memcpy而不是strcpy,以便可以复制