C で例外をスローする
- 例外の概要
- C プログラミング言語で例外を処理する
-
C でエラーを処理する
setjmp()
関数 -
C で
errno
を使用してエラー処理を実装する -
perror()
とstrerror()
を使用してエラー メッセージを出力する - ゼロ除算エラーの処理
この記事では、C プログラミング言語で例外またはエラーを処理する方法について説明します。
例外の概要
ゼロ除算の試行は、プログラムの実行中に発生する可能性がある異常なシナリオへの反応である例外を引き起こす可能性のある状況の例です。
例外
の助けを借りて、プログラムのあるセクションから別のセクションに制御を渡すことができます。
C プログラミング言語で例外を処理する
C はエラー処理 (例外処理とも呼ばれます) を直接サポートしていませんが、C でエラー処理を実行できるメソッドがあります。最初に問題を回避するために、プログラマは予防線を張り、関数が返す値を調べる必要があります。
エラーが発生した場合、C 関数の多くの呼び出しは値 -1
または NULL
を返します。 したがって、これらの戻り値に対する迅速なテストの実行は、たとえば if
ステートメントを使用して迅速かつ効率的に実行できます。
C でエラーを処理する setjmp()
関数
setjmp()
関数を使用して、他のプログラミング言語の例外処理機能をシミュレートすることができます。 初めて setjmp()
が呼び出されると、参照ポイントがプログラム実行中の現在のポイントに保存されます。
この参照点は、setjmp()
を含む関数が戻ったり終了したりしない限り有効です。 longjmp()
を呼び出すと、実行は対応する setjmp()
呼び出しが発生したポイントに戻ります。
setjmp() の引数は jmp buf で、実行コンテキストを持ちうる型で、最初の実行時(リターンポイントの設定時)に 0 を返す。 longjmp()
に指定された値は、longjmp()
が呼び出されたときに、プログラムが 2 回目に実行されるときに返されます。
以前に setjmp()
に提供された jmp buf
は、longjmp()
の入力として必要であり、戻り値として setjmp()
に渡されるべき値も必要です。
深くネストされた関数呼び出しでエラーが発生した場合、戻りたい場所に戻って戻り値を確認するのは面倒です。 ここで、setjmp()
と longjmp()
が最も役に立ちます。
ソースコード:
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int value;
jmp_buf environment;
value =
setjmp(environment); // value is set to 0 the first time this is called
if (value != 0) {
printf("You have just executed a longjmp call, and the return value is %d.",
value); // now, value is 1, passed from longjmp()
exit(0);
}
puts("Performing longjmp call\n");
longjmp(environment, 1);
return (0);
}
出力:
Performing longjmp call
You have just executed a longjmp call, and the return value is 1
C で errno
を使用してエラー処理を実装する
関数呼び出しが C で実行されると、errno
として知られる変数が、発生した問題を判別するために使用できるコード (値) の自動割り当てを受け取ります。 このコードを使用して、エラーが発生した場所を特定できます。
これは、関数を呼び出したときにどのようなエラーが発生したかを示すグローバル変数で、errno.h
ヘッダー ファイルで指定されています。 さまざまな種類のエラーは、errno
変数の個別のコードまたは値によって示されます。
以下は、それぞれ特定の意味に対応する多くの個別の errno
値のリストです。
errno 値 |
エラーメッセージ |
---|---|
1 | 操作は許可されていません |
2 | そのようなファイル、又はディレクトリはありません |
3 | そのようなプロセスはありません |
4 | 中断されたシステム コール |
5 | 入出力エラー |
6 | そのようなデバイスまたはアドレスはありません |
7 | 引数リストが長すぎます |
8 | 実行形式エラー |
9 | 不正なファイル番号 |
10 | 子プロセスなし |
11 | 再試行する |
12 | メモリ不足 |
13 | アクセス拒否 |
ソースコード:
#include <errno.h>
#include <stdio.h>
int main() {
FILE* fp;
fp = fopen("abc.txt", "r");
printf("The value of errno is: %d\n", errno);
return 0;
}
出力:
The value of errno is: 2
この場合、errno
は 2 に設定されます。これは、その名前のファイルもディレクトリも存在しないことを示します。
perror()
と strerror()
を使用してエラー メッセージを出力する
発生したエラーの種類は、上で取得した errno
値によって示されます。
エラーの説明を表示する必要がある場合は、error no
に関連するテキスト メッセージを表示するために 2つの関数を使用できます。
perror()
は、指定した文字列を表示し、スペースを挿入してからコロンを挿入し、最後に errno
値を記述します。 strerror()
は、errno
の現在の値の説明を参照します。
ソースコード:
#include <errno.h>
#include <stdio.h>
#include <string.h>
int main() {
FILE *fp;
fp = fopen(" abc.txt ", "r");
printf("The value of errno is: %d\n", errno);
printf("The error message is: %s\n", strerror(errno));
perror("perror Message");
return 0;
}
出力:
The value of errno is: 2
The error message is: No such file or directory
Message from perror: No such file or directory
ゼロ除算エラーの処理
エラーまたは例外を処理する場合、これは議論のために提起される最も一般的な問題です。
多くの場合、次のような数学的主張を提示します。
c = a / b;
しかし、状況によっては b
の値が ゼロ
になる可能性が高いことを忘れがちです。
zero
による整数の除算は、数学では許可されていません。 解決策には決して到達できない、つまり解決策は無限にあると人々はよく信じています。
残念ながら、そうではありません。 この特定のシナリオでは、正しい応答は指定されていません
です。 C で例外とエラーを管理する原則を使用して、この問題を解決するプログラムを次に示します。
ソースコード:
#include <stdio.h>
#include <stdlib.h>
int main() {
int dividend;
int divisor;
int quotient;
printf("Enter the value for dividend: ");
scanf("%d", ÷nd);
printf("Enter the value for divisor: ");
scanf("%d", &divisor);
if (divisor == 0) {
fprintf(stderr, "\nDivision by zero is not possible!\n");
exit(-1);
}
quotient = dividend / divisor;
fprintf(stderr, "The value of quotient: %d\n", quotient);
exit(0);
return 0;
}
出力:
ゼロ値を入力します。
Enter the value for dividend: 100
Enter the value for divisor: 0
Division by zero is not possible!
非ゼロ値を入力してください。
Enter the value for dividend: 100
Enter the value for divisor: 5
The value of quotient: 20
I am Waqar having 5+ years of software engineering experience. I have been in the industry as a javascript web and mobile developer for 3 years working with multiple frameworks such as nodejs, react js, react native, Ionic, and angular js. After which I Switched to flutter mobile development. I have 2 years of experience building android and ios apps with flutter. For the backend, I have experience with rest APIs, Aws, and firebase. I have also written articles related to problem-solving and best practices in C, C++, Javascript, C#, and power shell.
LinkedIn