質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

UNIX

UNIXとは、AT&Tのベル研究所で開発されたコンピューター用のマルチユーザー・マルチタスクのオペレーションシステム(OS)です。政府や教育機関や研究所で広範囲に採用されています。

Q&A

解決済

4回答

1243閲覧

UNIX/Cファイル入出力と分割

9S0_B1

総合スコア9

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

UNIX

UNIXとは、AT&Tのベル研究所で開発されたコンピューター用のマルチユーザー・マルチタスクのオペレーションシステム(OS)です。政府や教育機関や研究所で広範囲に採用されています。

0グッド

0クリップ

投稿2018/07/24 05:47

編集2018/07/24 06:33

###環境
環境:Teraterm/LINUX
使用言語:C言語、Cシェル
初心者かつ書きかけのため、見にくかったりご不明点が多かった場合、申し訳ありません。

前提・実現したいこと

1.func.c(機能を担う)をpull.c(ファイルの入出力を担う)で呼び出して一つのexeを作りたい。2.extern関数か他の方法があるのかわからない。
3.exeを作るmakefileを完成させたい。

該当のソースコード

func.c

C

1#include <stdio.h> 2#include <stdlib.h> 3#include <ctype.h> 4 5 6int count[26]; 7 8int func(int argc, char *argv[]){ 9 FILE *fp; 10 char ch; 11 int i; 12/*文字を探す*/ 13 while (( ch = fgetc(fp)) != EOF){ 14 15/*英字の大文字小文字を変換*/ 16 ch = toupper(ch); 17/*探す範囲*/ 18 if(ch >='A' && ch <= 'z') 19 20 count[ch - 'A']++; 21 22 } 23 24 for (i = 0; i < 26; i++) 25 26 printf("%C の出現は %d 個目です。\n", i + 'A',count[i]); 27return 0; 28 29} 30

pull.c

c

1#include <stdio.h> 2 3 4int main(int argc, char *argv[]) 5{ 6 FILE *fp; 7 char ch; 8 int i; 9/*ファイル名が正しいか調べる*/ 10 11 if (argc != 2){ 12 printf("ファイル名が正しくありません。\n"); 13 exit(1); 14 } 15 16 17/*入力用にファイルを開きます*/ 18 if((fp = fopen(argv[1], "r")) == NULL){ 19 printf("ファイルを開くことができません\n"); 20 exit(1); 21 } 22 23/*exterm書き直し*/ 24extern int func{ 25 26} 27 28 29fclose(fp); 30return 0; 31 32}

makefile(csh)

csh

1#!/bin/csh -f 2 3pull.c: func.c pull.c 4 gcc -o pull.exe func.c pull.c

//ファイル名を修正いたしました。混乱を招いてしまい申し訳ありません。

発生している問題・エラーメッセージ

func.c(コンパイルエラー)

/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/crt1.o: In function `_start': (.text+0x20): undefined reference to `main' collect2: ld はステータス 1 で終了しました make: *** [func] エラー 1

pull.cコンパイルエラー

pull.c: In function ‘main’: pull.c:13: 警告: incompatible implicit declaration of built-in function ‘exit’ pull.c:20: 警告: incompatible implicit declaration of built-in function ‘exit’ pull.c:24: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token make: *** [pull] エラー 1

※コンパイルにはmakefileを使っています
何が悪いのかわからなくなってしまい、迷子状態で情けない限りです。
なにかお助けを頂けましたら幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ソースプログラムが複数ある場合、

  • 全部を一気にコンパイルする
  • 個別にコンパイルしてリロケータブルオブジェクトを作り、最後にリンクする

の二つのやり方があります。ファイル個数が多いのなら前者は無理になりますが。

前者だとだいたいこんな感じ

cc -o hoge func.c pull.c

後者だとこういう手順

cc -c func.c cc -c pull.c ld -o hoge func.o pull.o

実機テストはしていませんが、こういうmakefileで行くんじゃないかなぁ。

hoge: pull.o func.o <TAB>cc -o $* $>

最後の行はccではなくまじめにldを呼び出すのが本筋。

投稿2018/07/27 06:18

a_saitoh

総合スコア702

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

9S0_B1

2018/08/03 10:14

ご回答ありがとうございました!いままでに無い知見でした。参考にさせていただきます。
guest

0

ベストアンサー

func.c(コンパイルエラー)

こちらで出ているのはコンパイルエラーではなくリンクエラーです。

collect2: ld はステータス 1 で終了しました

ここに出てるldというのがリンカのコマンドになります。
リンカがリンクして実行モジュールを作成しようとした結果、main関数が見つからないというエラーになっています。

ではなぜmain関数が見つからないか。
main関数を含むpull.cで以下のエラーが発生しているためです。

pull.cコンパイルエラー
functionalA.c:13: 警告: incompatible implicit declaration of built-in function ‘exit’
functionalA.c:20: 警告: incompatible implicit declaration of built-in function ‘exit’
functionalA.c:24: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘attribute’ before ‘{’ token

最初の2つは警告です。
exit関数を宣言なしで使おうとしているためです。
冒頭でstdlib.hをインクルードしましょう。

最後のエラーはexternの行です。
これはexternの書き方ではないです。
main関数の外で、次のように書きます。
(正確にはmain関数の中でもどちらでもよいです。説明は省きます)

c

1extern int func(int argc, char *argv[]);

そしてfunc関数を呼び出したいところ(エラーになっているところ)では次のように書きます

c

1func(argc, argv);

これでpull.cのコンパイルが通るのでリンクでエラーにはならなくなるはずです。

ところでfunc関数にはmain関数でオープンしたファイルポインタを受け渡していないので、正しく処理できていません。
また一般的にUNIXの実行モジュールファイル名にEXEはつけないのでご注意を。

投稿2018/07/24 06:11

ttyp03

総合スコア16996

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

9S0_B1

2018/08/03 10:13

丁寧なご回答ありがとうございました。こちらのアドバイスでかいけつすることができました!
guest

0

func.cで1つの実行ファイルを作るなら、関数名をmainにしてください。

あと、pull.cの方は、#include <stdlib.h>を追加して、extern int func{}という意味不明記述を削除。

Makefileはコピペミスでしょうか?

投稿2018/07/24 05:59

otn

総合スコア84423

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

9S0_B1

2018/08/03 10:15

ご回答ありがとうございました!おっしゃる通りでございます。
guest

0

advanced02.c というソースファイルはなんでしょうか。

エラーメッセージは、main関数が定義されていないために発生しているエラーです

投稿2018/07/24 05:52

y_waiwai

総合スコア87719

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

9S0_B1

2018/07/24 06:13

失礼しました。ファイル名の相違はネット上に載せるので一応変えただけで、advanced02.cはfunc.cと考えていただければと思います。 externを使用したいとき、mainの扱いがどうなるのか理解できません。(質問があいまいかもしれませんが…)
y_waiwai

2018/07/24 06:16

ならpull.c はどこにいったのかとw ということで、他の回答を参考にして修正してみてください
9S0_B1

2018/07/24 06:40

すみません、こちらの言葉足らずと不注意で混乱をまねいてしまいました。ご回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問