COBOLプログラムから呼び出され、ファイルのレコードを一行読んでレコードの内容を返すというcサブルーチンを作っているのですが、COBOL←→c間でのインタフェースの扱いかたがよくわからなくて困っています。(ちなみにこのモジュールはcからも呼ばれる事がある)
COBOLはコピー句(test001.cbl, test002.cbl)に値を入れて、cサブルーチンにそれを渡しています。
テストはCOBOL85を使用してるので、cサブルーチンの中のデータを見ることができません。なので、返ってくるコピー句の中身を見るのですが、とにかく値が設定されてかえってこないのです。ただ単にロジックのバグと言う可能性もあるけど(^^;

私はインタフェース環境の事がまだ良く解っていないので、今回こちらに質問した次第です。経験者の方がいましたら、どうかおしえてください。

あ、それからCOBOLから渡される値は、c側では全てchar型で受け取らなければいけないような話しを聞いたのですが、本当でしょうか?

もう一つ。
コピー句の中で「F-CODE PIC X(2)」のようにハイフンがあるのですが、cではハイフンが使えないからダメなんでしょうか?

たくさん質問してしまいましたが、どうかよろしく。

/COBOL側/
--------------------------------------------------

CALL 'TEST1' USING BY VALUE TEST001 TEST002.

--------------------------------------------------

/cサブルーチン側/
--------------------------------------------------
int TEST1(test001, test002)

char *test001;
char *test002;
{
    ・
    ・
    ・
return (0);
}
--------------------------------------------------

このQ&Aに関連する最新のQ&A

A 回答 (2件)

「マニュアルを読め」と言う No.1 の回答が本質だとは思いますが、想像できる範囲で。



> 返ってくるコピー句の中身を見るのですが、とにかく値が設定されてかえってこない

引数で指定した変数の内容を、C の関数で設定して、それを COBOL 側で参照したい、
ということですよね。であれば、

> CALL 'TEST1' USING BY VALUE TEST001 TEST002.

CALL 'TEST1' USING BY REFERENCE TEST001 TEST002.

ということだと思いますよ。詳細は、マニュアルの CALL 文のところを読むと
わかる(かもしれない)でしょう。


> COBOLから渡される値は、c側では全てchar型で受け取らなければいけない

その言い方は正確ではないですが、だいたいの場合に当てはまるはずです。
C には、変数に対する桁数の指定、という概念がありません。

USAGE 句で BINARY とか指定した変数は、C 側では short で受取れるはずです。


> コピー句の中で「F-CODE PIC X(2)」のようにハイフンがあるのですが、cではハイフンが使えないからダメなんでしょうか?

仮引数と実引数の変数名は一致している必要はありません。呼び側と受け側で一致
している必要があるのは、その型と順序です。


# 実は、COBOL をやった事がありません (^^;
# 仕事で COBOL のソースを読むはめになりそうなので、自分の勉強に利用させて
# もらいます。「専門家」のチェックは「計算機屋」だ、という意味でチェックしました。
    • good
    • 0
この回答へのお礼

ありがとうございます。
とても参考になりました。
計算機屋も大変でね。(^^;
作る人にもよりますが、他人の書いたソースはわかりずらいですよね。(笑
がんばってください。

お礼日時:2001/10/23 13:22

言語間インタフェースは規格化されていないケースがほとんどだと思いますし、


仮に規格化されていても、お使いの言語処理系がそれに準拠しているとも
限りませんから、まずはお使いの言語処理システムのマニュアルを参照された
方がよいと思います。その上で、なお分からないということでしたら、お使いの
環境(OS・言語処理ソフト等)を示した上で質問されれば、あるいは知っている
人がいるかもしれません。
    • good
    • 0
この回答へのお礼

聞く前にまず自分で調べるのは当然ですよね。(^^;
今回は、切羽詰っていたので皆さんに頼ってしまいました。
でも、こちらのサイトは本当に頼りになります。
アドバイスありがとうございます。

お礼日時:2001/10/23 13:16

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qchar c = 'a'; char h[1] = c; エラー

char型のものを char[]型に代入したいです。

char c = 'a';
char h[1] = c;

として、

h[0] は \x97
h[1] は \x00

にしたいです。
型変換の方法を教えてください。

Aベストアンサー

とりあえず、確認を。

C では、'a'の表す値は 0x61 = 97 であって、 \x97 ではないと思います。
(\xnnn を、十六進数の意味に取りましたが、あってますでしょうか?
この場合、C では通常 0xnnn のように書くと思います。)
ので、 これは 0x61 のことをおっしゃっていると仮定します。

> char h[1] = c;
っと、これではたぶんコンパイルが通りません。

char h[1] = {c};

のように、配列であることを明示して代入してください。
この式では、前半でh という名前の、*長さ1 の* char の配列変数を確保します。
後半で、その中を初期化しています。
添え字は 0 からはじまるので、この場合、h[0] に c の内容が代入されます。
1個しか場所を確保していないので、 h[1] の位置のデータは内容が不定です。
文字列として h を扱いたいのであれば、 C の文字列には終端として 0 が必要ですから、
char c = 'a';
char h[2] = { c, '\0'};

のような書き方が必要になります。
これで、お望みのデータになると思います。

とりあえず、確認を。

C では、'a'の表す値は 0x61 = 97 であって、 \x97 ではないと思います。
(\xnnn を、十六進数の意味に取りましたが、あってますでしょうか?
この場合、C では通常 0xnnn のように書くと思います。)
ので、 これは 0x61 のことをおっしゃっていると仮定します。

> char h[1] = c;
っと、これではたぶんコンパイルが通りません。

char h[1] = {c};

のように、配列であることを明示して代入してください。
この式では、前半でh という名前の、*長さ1 の* char の配列変数...続きを読む

QCからFortrunサブルーチンをコールする方法

以前Fortrunで作ったサブルーチンを新たにCからコールする方法がわかりません
Cの方でFortrunのサブルーチン名を宣言すればいいと思うのですが。。。
よろしくお願いします

Aベストアンサー

一般的にCからフォトランのサブルーチンを使うことはできません。そのため無理だと思います(もしかしたらインラインフォトランに対応したCコンパイラとかあるのかもしれませんが、その可能性は低いと思います)。
普通はフォトランで作ったソースコードをC言語に変換して使います。つまりフォトランのサブルーチンを完全に書き換えることになります。例える英語から日本語に翻訳するようなものです。

Qchar型+char型ってint型? if(char型==int型)?

C言語の「汎整数拡張(インテグラルプロモーション)」というものに関するものだと思います。

char型とchar型を加えた結果は、char型でしょうか。それともint型でしょうか。
(下のプログラムの
printf("sizeof(a[0]+a[1])は%d\n", sizeof(a[0]+a[1])); /* char型+char型 */
という部分の結果は4なので、int型と考えるべきなのかな。)

私は、char型とint型の加算の結果はint型だと思っていましたが、
char型とchar型の加算の結果はやはりchar型だと思っていました。
(それが間違えているのでしょうか。)


if(a[0]==i) /* char型とint型の比較(?) */
の部分では、左辺はchar型、右辺はint型ですが、このように型の違う変数を比較しても文法上構わないのでしょうか。
(私は、「比較は必ず型の同じもの同士でしかできない」と思っていました。)
左辺はchar型のように見えて、じつはint型ですか。


#include <stdio.h>
int main(void)
{
char a[4];
int i=77;
printf("sizeof(int)は%d\n", sizeof(int));
printf("sizeof(char)は%d\n", sizeof(char));
printf("sizeof('M')は%d\n", sizeof('M'));
printf("sizeof(a[0])は%d\n", sizeof(a[0]));

a[0]='M';
a[1]=7+6;
a[2]=a[0]+a[1];
printf("sizeof(a[0]+a[1])は%d\n", sizeof(a[0]+a[1])); /* char型+char型 */
printf("sizeof(+a[0])=%d\n", sizeof(+a[0]));

if(a[0]==i) /* char型とint型の比較(?) */
puts("a[0]==i");
else
puts("a[0]!=i");

return(0);
}

ちなみにワーニングもエラーもなんにもでません。

C言語の「汎整数拡張(インテグラルプロモーション)」というものに関するものだと思います。

char型とchar型を加えた結果は、char型でしょうか。それともint型でしょうか。
(下のプログラムの
printf("sizeof(a[0]+a[1])は%d\n", sizeof(a[0]+a[1])); /* char型+char型 */
という部分の結果は4なので、int型と考えるべきなのかな。)

私は、char型とint型の加算の結果はint型だと思っていましたが、
char型とchar型の加算の結果はやはりchar型だと思っていました。
(それが間違えているのでしょう...続きを読む

Aベストアンサー

「sizeof 単項式」について補足です。

これは sizeof 演算子が「単項演算子」であるために書かれたものだと思われます。
例えば同様に単項演算子である ++ も、「++ 単項式」です。

では単項式とは何なのかというと、これは以下のようなものを指します。(抜けがあるかもしれませんが。)
・定数
・名前(変数名や関数名など)
・( 式 )
・後置式

( 式 ) はおなじみの「式の結果を返す」ものですが、実はこれ全体で単項式です。
本来「sizeof 単項式」では ( ) を必要としないので、sizeof より優先順位の低い演算子を含む式を裸で渡すことはませんが、( ) で囲めばどんな式でも書けるわけです。

後置式は「配列構文によるアドレス参照式」や「関数呼び出し式」、「メンバ参照式」「後置型インクリメント/デクリメント式」です。
なので、
> sizeof(a[0])
> と書いたら、[ ] という演算子は2項演算子だから、a[0]は単項式になっていない
は、わざわざ ( ) で囲まず sizeof a[0] と書いても、正しい単項式なので問題ありません。
(これらの演算子は、全て sizeof より優先順位が上になっています。)

先に ++ も単項式を取る、ということを書きましたが、++ だって
  ++*(p + n)
のような記述が通るのだから、sizeof でも問題がなくて当然です。

また、例えば ++ では「オペランドは左辺値でなければならない」という原則があり、左辺値でない式に ++ を適用するとコンパイルエラーが発生します。
しかし、sizeof に「オペランドはオブジェクトでなければならない」などという原則を聞いたことがありません。
無論コンパイルエラーも起きませんし、期待通りに式の値のサイズが返ります。
「式の値のサイズ」というのはコンパイル時に判明しているものなので、取得できて当然といえば当然ですが、これがCで定められた仕様かどうかというのは残念ながら見つけることはできませんでした。
ただし、質問にあるような sizeof の文法は全て正しく、警告が出ないのは仕様通りだというのは間違いありません。

「sizeof 単項式」について補足です。

これは sizeof 演算子が「単項演算子」であるために書かれたものだと思われます。
例えば同様に単項演算子である ++ も、「++ 単項式」です。

では単項式とは何なのかというと、これは以下のようなものを指します。(抜けがあるかもしれませんが。)
・定数
・名前(変数名や関数名など)
・( 式 )
・後置式

( 式 ) はおなじみの「式の結果を返す」ものですが、実はこれ全体で単項式です。
本来「sizeof 単項式」では ( ) を必要としないので、sizeof より優...続きを読む

Q文字列配列をサブルーチンにアドレス渡ししてscanf入力

main関数内で
char strarray[3][21]
という文字列配列を宣言し、
サブルーチンvoid input(・・・)内でscanfを使って
strarray[0]~strarray[2]の各行に入力を行うとします。
ここでポインタを引数としてstrarrayをmainとinputで共有する場合、
strarrayに関して以下の項目はどう記述すればよいのでしょうか?

1)inputを宣言する際の仮引数の書式
2)main内でinputを呼び出す際の引数の書式
3)input内でscanfする際の引数の書式

いろいろ組み合わせを試してはみたのですが、
どうにもSegmentationFaultを回避できません。
いい加減混乱してきたので、そろそろすっきりと整理したいと思っています。
よろしくお願いします。

…まあ「構造体使えばいいじゃないか」と言われてしまえばそれまでなのですが…

Aベストアンサー

まず、配列とポインタの関係から説明します。

C 言語の場合、配列はコンパイラによって、その「先頭要素を指すポインタ」に読み替えられます。

つまり、int hoge[10]; と定義した配列に対して、式の中で hoge と書くと、これは int*型の変数として扱われて、それは &hoge[0] と同じ意味になります。
# 一部例外はあります。
# たとえば、sizeof(hoge) とした場合、ポインタサイズではなくて、配列のサイズが
# 取得できます。

で、これをそのまま配列の配列に適用してみれば良いわけです。

どうなるかというと、char piyo[3][10]; と定義した変数に対して、式の中で piyo と書けば char(*)[10]型の変数として扱われて、それは &piyo[0] と同じ意味になります。

char(*)[10] 型と書きましたが、これは「char型配列(要素数10)を指すポインタ型」のことです。
配列を指すポインタ型の変数を定義する場合には、次のように書きます。
char (*p_piyo)[10];

つまり、piyo はもともと「char型配列(要素数10)の配列(要素数5)」だったわけですよね。
これが、コンパイラによって「char型配列(要素数10)を指すポインタ」として扱われるようになるわけです。

注意点としては、この配列→ポインタの読替え規則は再帰的には行われないことですね。
どういうことかというと、配列の配列は、ポインタのポインタにはならず、配列のポインタにしかならない、ということです。

さて、前置きが長くなりましたが、話を etendard さんのご質問に戻します。

1) これまでの話で、char strarray[3][21] に対してコンパイラが読み替える等価な型が char (*str_ptr)[21] となることはおわかりいただけると思います。

関数の引数に配列を渡す場合は、必ずポインタに読みかえられますので、仮引数の宣言もポインタに読み替えられた方の型で書くことになります。
# というよりも、配列を渡すことができないので、配列の先頭要素を指すポインタを
# 渡している、という言い方のほうが正しいのですけどね。

つまり、プロトタイプは

void input( char (*str_ptr)[21] );

のようになります。
できれば、配列の要素数も一緒に渡せるようにするのが良いでしょう。

その場合は、こんな感じです。

void input( char (*str_ptr)[21], int num );

2) 関数コールする場合は次のようにします。

input( strarray );

要素数付きの場合は、次のようにします。

input( strarray, 3 );

要素数付きにしたほうが良い理由は、ポインタに読み替えられた方の配列の要素数が、関数に渡らないためです。

標準関数では、gets() なんかはその典型ですよね。
# バッファオーバーランの原因となるということで、WARNING を吐くコンパイラも
# あるとか。。。

それに対して fgets() は文字列の数も渡せるので、より安全だといえます。
要するに、それと同じことです。

3) input() の中で scanf() する場合には、次のようにすれば良いです。

for ( i=0; i<3; i++ )
{
scanf( "%s", str_ptr[i] );
}

# なぜこれで良いのかは、よく考えてみてください。

同様に、要素数付きの場合には次のようにします。

for ( i=0; i<num; i++ )
{
scanf( "%s", str_ptr[i] );
}

ちなみに、関数の仮引数の場合に限り、ポインタ宣言と配列宣言は同じ物になります。
# というよりも、いずれもポインタ宣言になります、といった方が正しいです。

つまり、以下の表記はいずれも同じ物になります。

void input( char (*array_ptr)[21] );
void input( char array_ptr[][21] );
void input( char array_ptr[3][21] );

ただし、3番目の表記をした場合であっても、[3] の部分の要素数は無視されます。
# コンパイラが勝手にポインタに読み替えてしまいますからね。

宣言や定義について、このような読替えが起こるのは関数の仮引数宣言の場合だけです。
通常の、宣言や定義ではこのような読替えは起こりませんのでご注意ください。

かなり長くなってしまいましたが、こんな感じでいかがでしょうか。

まず、配列とポインタの関係から説明します。

C 言語の場合、配列はコンパイラによって、その「先頭要素を指すポインタ」に読み替えられます。

つまり、int hoge[10]; と定義した配列に対して、式の中で hoge と書くと、これは int*型の変数として扱われて、それは &hoge[0] と同じ意味になります。
# 一部例外はあります。
# たとえば、sizeof(hoge) とした場合、ポインタサイズではなくて、配列のサイズが
# 取得できます。

で、これをそのまま配列の配列に適用してみれば良いわけです。

どうな...続きを読む

QC(char *s1)の文字列をObjective-Cの文字列(NSS

C(char *s1)の文字列をObjective-Cの文字列(NSString *s2)にするにはどうしたらよいのでしょうか?

char s1[] = "abc";
NSString *s2 = [[NSString alloc] initWithUTF8String:s1];  // (A)

NSLog(@"s2=[%s]", s2);

結果がabcかなと思っていましたが、読めない変な文字が表示されました。
(A)を NSString *s2 = [NSString stringWithFormat:@"%s", s1]; に変えても同じでした。

s1のC文字列は日本語を含まないアルファベットの文字列なのになぜ?と
困っています。

Objective-Cの初心者で申し訳ありません。

Aベストアンサー

> NSLog(@"s2=[%s]", s2);

「initWithUTF8String:」も正しくないけど、直接のまちがいはこちらですね。
正しくは「NSLog(@"s2=[%@]", s2);」です。

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html%23//apple_ref/doc/uid/TP40004265


人気Q&Aランキング

おすすめ情報