初めまして。分からないところがあったので質問させていただきます。
以下のプログラムは引数から値を取得し、その値で生データの切り出しを
行うプログラムです。
read関数のところなのですが、argv[1]に格納されたファイル(パス名)が0byteでもエラーが出力されずに、コンパイルされてしまいます。
どうすればよいのでしょうか?
さらに、上司にreadとwriteにエラーチェックのメッセージをつけろ。と言われたのですが、どうやれば良いのかよく分かりませんでした。if()~とすれば良いのでしょうか?初心者なので分かりにくい質問かと思いますが、どうぞよろしくお願いします。
#pragma warning ( disable : 4996 )
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <io.h>
#include <sys/stat.h>
#define ONESEGSIZE 2048
void main ( argc, argv )
int argc;
char *argv[];
{
int fd, fd2;//ファイルハンドル
int segment;//列数
int raw_n;//切り出す生データの数
int tviews;//総ビュー数
int start_view;//切り出し開始ビュー
int size_view;//切り出しサイズ
int pitch_view;//切り出しピッチ
char *Rawdivit;//コマンド
char *raw_file;//生データファイル名
char *outraw_file;//生データ出力ファイル名
char *mem;//メモリ変数
/* パラメータの個数チェック*/
if ( argc != 9 ) {
printf( "usage : Rawdivit raw_file outraw_file segment raw_n"
" tviews start_view size_view pitch_view \n" );
exit ( 1 );
}
/* 引数の取得char型*/
Rawdivit = argv[0];
raw_file = argv[1];
outraw_file = argv[2];
/* 引数の取得int型*/
segment = atoi ( argv[3] );
raw_n = atoi ( argv[4] );
tviews = atoi ( argv[5] );
start_view = atoi ( argv[6] );
size_view = atoi ( argv[7] );
pitch_view = atoi ( argv[8] );
/* 生データファイルオープン*/
fd = open ( raw_file, O_RDONLY | O_BINARY );
if ( fd == -1 ) {
printf ( "Fileopen error : read\n" );
exit ( -1 );
}
/* 生データ読み込み用メモリ確保*/
mem = ( char * ) malloc ( ONESEGSIZE * segment * size_view );//単位 = byte
if ( mem == NULL ) {
printf ( "Memorysecure error\n" );
exit ( -1 );
}
/* 切り出し開始位置までファイルポインタをシーク*/
lseek ( fd, ONESEGSIZE * segment * start_view, SEEK_SET );
/* 切り出しサイズ分読み込み*/
read ( fd, mem, ONESEGSIZE * segment * size_view );
/* 出力ファイルオープン*/
fd2 = open ( outraw_file, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IREAD | S_IWRITE );
if ( fd2 == -1 ) {
printf ( "Fileopen error : write\n" );
exit ( -1 );
}
/* 読み込んだデータを出力ファイルに書き込み */
write ( fd2, mem, ONESEGSIZE * segment * size_view );
/* メモリの開放*/
free ( mem );
/* ファイルクローズ*/
close ( fd );
close ( fd2 );
exit ( 0 );
}
A 回答 (5件)
- 最新から表示
- 回答順に表示
No.5
- 回答日時:
★回答者 No.3 です。
・数値が違う理由は、他のエラー場所で『exit( -1 );』にしているので分けただけ。
同じ値を返してもエラー判定できないため、-2 という数値で分けたのです。
回答者 No.4 さんのアドバイスも参考にして下さい。
・なお、-1 の場合は OS 側には 255 の値が返され、-2 では 254 という数になります。
分かりやすく記号定数で定義することをお勧めします。
下にそのサンプルを載せます。
サンプル:
/* エラー定数の定義 */
#define ERR_SUCCESS (0) // 正常
#define ERR_OPEN (-1) // オープンエラー
#define ERR_READ (-2) // 読み込みエラー
#define ERR_MEMORY (-3) // メモリ不足エラー
int main( int argc, char *argv[] ) ←この1行に定義を変更しましょう。外に書くのは古い形式です。注意!
{
:
宣言部
:
/* 生データファイルオープン */
if ( (fd = open(raw_file,O_RDONLY|O_BINARY)) == ERR_OPEN ){
printf( "Fileopen error : read\n" );
exit( ERR_OPEN ); ←(1)
}
/* 生データ読み込み用メモリ確保 */
mem = (char *)malloc( ONESEGSIZE * segment * size_view ); // 単位 = byte
if ( mem == NULL ){
printf( "Memorysecure error\n" );
exit( ERR_MEMORY ); ←(2)
}
/* 切り出し開始位置までファイルポインタをシーク */
lseek( fd, (ONESEGSIZE * segment * start_view), SEEK_SET );
/* 切り出しサイズ分読み込み */
if ( read(fd,mem,(ONESEGSIZE * segment * size_view)) < 0 ){
printf( "切り出しサイズでエラーが発生しました。" );
exit( ERR_READ ); ←(3)
}
:
出力ファイルも同じ要領で記述
:
return( ERR_SUCCESS ); ←(4)
}
解説:
・ヘッダ部の『#define』でエラー定数を定義しています。
ここの数値は、私が勝手に付けていますので teru3128 さんが自由に決めて変更しても構いません。
・teru3128 さんのソースでエラーが起こると exit( -1 ); していますが、全部同じ数値ですよね。
これだと OS には全部同じ数値(255)がエラーコードとして返されます。するとエラーが起きたか、
正常に動作したかの判定は出来ますが、エラーの種類は判定できなくなります。このため、エラーの
数値を -1、-2、-3 …と分ければエラーコードでエラーの種類を特定できて便利になります。
上の(1)、(2)、(3)、(4)は記号定数でエラーコードの種類を分けて返しています。
・このようにエラー数値を分ければ、エラーが起きたときに printf() 関数で表示しないオプションを
つけてもエラーコードで取得して判定できます。→特に他のプログラムから呼び出したときにも
エラーコードを参照できるため便利になりますよ。
・また、エラーコードは Windows の OS では、if errorlevel 数値 命令という感じでバッチファイルなど
から参照できます。つまり、今作っている プログラム名が read.exe の場合は、
-------------------------------
@echo off
read.exe
if errorlevel 255 goto error1
if errorlevel 254 goto error2
if errorlevel 253 goto error3
echo 正常!
goto end
:error1
echo オープンエラー
goto end
:error2
echo 読み込みエラー
goto end
:error3
echo メモリ不足エラー
:end
-------------------------------
というバッチファイルを作って実行させると、実行後にエラーレベルの数値で正常か、エラーかの判定が
行えることになります。このため、エラーコードを OS に返すのならば、エラーの数値は分けたほうが
便利なことになります。特に DOS コマンドを作成する場合はそのような仕組みを取り入れるべきですね。
・以上。わかりますか?→バッチファイルとか。エラーレベルとか。
バッチファイルは存じあげていたのですが、
エラーレベルについては調べて理解することが出来ました。
この仕事は未経験で出来るかかなり不安だったのですが、やりがいもあると
思うので頑張っていこうと思います。
丁寧な回答本当にありがとうございました。
また機会がありましたらよろしくお願いします。
No.3
- 回答日時:
★『read』関数の引数は必要ですよ。
・下のようにします。
/* 切り出しサイズ分読み込み */
if ( read(fd,mem,ONESEGSIZE * segment * size_view) < 0 ){
printf( "切り出しサイズでエラーが発生しました。" );
exit( -2 );
}
レスありがとうございます。
ちなみになぜ戻り値が-2なのでしょうか?
エラーの場合は-1では無いのでしょう?
質問ばかりで申し訳ありません。
No.2
- 回答日時:
> >>エラーを検出したときにメッセージを出すということでよいのでしょうか?
> はいそうです。今一記述の仕方がよく分からないです。
何をもってエラーとするかにもよりますが、単に入出力のエラーを返すだけであれば、
if (read(...) < 0)
{
fprintf(stderr, ...);
/* ここでreturn, exitまたはabortしてもよい */
}
のようにするだけだと思うのですが...
No.1
- 回答日時:
> read関数のところなのですが、argv[1]に格納されたファイル(パス名)が0byteでもエラーが出力されずに、コンパイルされてしまいます。
ファイルのサイズは、実行時にファイルを調べるまでわからないので、コンパイル時に検出することは原理的に不可能です。
> どうすればよいのでしょうか?
どうすることもできません。
実行時にサイズを調べるしかないのでは?
> さらに、上司にreadとwriteにエラーチェックのメッセージをつけろ。と言われたのですが、どうやれば良いのかよく分かりませんでした。if()~とすれば良いのでしょうか?初心者なので分かりにくい質問かと思いますが、どうぞよろしくお願いします。
エラーチェックならわかりますが、「エラーチェックのメッセージ」というのが何を期待されているのかよくわかりません。エラーを検出したときにメッセージを出すということでよいのでしょうか?
レスありがとうございました。
>>エラーを検出したときにメッセージを出すということでよいのでしょうか?
はいそうです。今一記述の仕方がよく分からないです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- C言語・C++・C# C言語のファイル入力が分かりません 2 2022/05/22 06:35
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# 並列プログラミングのπ計算について 1 2022/07/16 22:30
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# C言語 共用体について コマンドライン引数で値を2つ入力したときに、argv[2]の値をUNI u1 4 2022/04/25 20:34
- C言語・C++・C# Cのdoubleの浮動小数点表示について 3 2023/04/17 13:14
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
python エラー
-
エクセルのエラーメッセージ「4...
-
fortranでプログラムを実行する...
-
visual C++ でビルドの中止がで...
-
適切な変換関数が存在しない???
-
バッチからsqlplusの接続エラー...
-
vbaのインポートでエラー
-
Excelのエラーで困ってます。
-
LPCWSTRとchar
-
エクセルでマクロを実行すると...
-
fopen() がたまにNULLを返す
-
HEWを使用しているのですが、こ...
-
BC30002: 型 'ListItem' が定義...
-
VB2008で定数に色の設定をした...
-
デバッグ中のエラーのことで教...
-
Microsoft Visual Studio Profe...
-
WindowsからLinuxへの移植
-
VBScriptによるExecuteExcel4Ma...
-
ビルドが失敗してしまいます
-
コンパイルできません。
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
python エラー
-
エクセルのエラーメッセージ「4...
-
適切な変換関数が存在しない???
-
Excelのエラーで困ってます。
-
バッチからsqlplusの接続エラー...
-
fortranでプログラムを実行する...
-
HEWを使用しているのですが、こ...
-
コンパイルできません。
-
デバッグ中のエラーのことで教...
-
visual C++ でビルドの中止がで...
-
BC30002: 型 'ListItem' が定義...
-
Handlesについて
-
sys/time.hのインクルードがで...
-
ビルド失敗 指定されたファイ...
-
VB2008で定数に色の設定をした...
-
RightとLeft関数のライブ...
-
multiple definitionというエラー
-
WindowsからLinuxへの移植
-
HANDLEの宣言でのエラー
-
レコードセットをcloseする所で...
おすすめ情報