我正在尝试用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中的输出。
答案 0 :(得分:4)
如果要在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]);
[...]
为了使其实际可用,您可能会使用两件事:
像
这样的东西#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
时,会变得更加复杂。
BTW:你可能想检查一下GnuCOBOL - 它将COBOL翻译成C ......
答案 1 :(得分:2)
你的工会正在发挥作用。当您显示结构字段时,问题来自于字符串中缺少NULL终止符。
如果您不想修改结构,也许可以调整格式限定符。
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);
答案 2 :(得分:1)
问题在于输出本身。在C中所有字符串(至少那些你想用printf打印的字符串(&#34;%s&#34;,...))最后需要一个0字节。因为你的&#34;字符串&#34;意味着具有2或6个字节的固定长度,这将不起作用,因为每个2字节&#34;字符串&#34;需要第三个字节来完成字符串。
所以,实际上它&#34;工作&#34;,但结果是一个字符数组,这与C中的字符串不同,所以你不能使用通常的字符串操作。
这不是你想听到的,但我建议忘记字符串并使用整数并使用转换函数。例如
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="accordion">
<div class="accordion-heading">heading</div>
<div class="accordion-content">body</div>
<div class="accordion-heading">heading</div>
<div class="accordion-content">body</div>
<div class="accordion-heading">heading</div>
<div class="accordion-content">body</div>
</div>