我正在尝试用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/