• 締切済み

C言語の標準関数のエラー

現在ソケット通信でデータを送受信するプログラムを作っています。 通信してデータのやり取りする部分はできたので、関数のエラーチェック、異常が発生したときの処理を追加しているところです。 異常時の処理は、エラーの通知・メモリの解放など行っている感じです。 今エラーの判断を行うのに関数の戻り値を利用しているのですが、ふと疑問が浮かんできました。 それは、関数がエラーを返すときはどういうときなのか、つまり、エラーが発生する原因はなんなのか?ということです。 関数について解説しているHPを見ても、戻り値は載っていてもなぜその戻り値が返ってくるのか、といった原因まで解説してくれているところがありません。 標準関数について、エラーが返る原因を解説しているHPはあるでしょうか。もし知っている方がいれば教えていただけると幸いです。 HPでなくても、他に調べる方法があればご教授お願いします。 特に通信用の関数について知りたいというわけでなく、エラーについて興味があるといった感じです。 ・・・といいつつも、ソケット関数について教えていただければ例外処理も考え易いかなと思っています^^;

みんなの回答

  • a-saitoh
  • ベストアンサー率30% (524/1722)
回答No.4

>   戻り値 -1:~に失敗した時 >っていうのがあったとして、失敗した時に-1が返るのは見れば当然わかる >ことですが、 >なぜ失敗するのかまでがわからない、といった感じです。 マニュアルを最後まで全部読んでますか? いちいち書かなくても常識的(TCP/IPを知っていれば)に理解できる事もありますし、マニュアルに書いてあることもあります。 たとえばconnectだと、 RETURN VALUES   成功したら0、失敗したら1を返します (略) のあとに、 ERRORS The connect() system call fails if: [EBADF] The s argument is not a valid descriptor. [ENOTSOCK] The s argument is a descriptor for a file, not a socket. [EADDRNOTAVAIL] The specified address is not available on this machine. (以下略) みたいに、細かい原因がずらずらと列挙されていますが。

nanayarawa
質問者

お礼

横着者の質問に2度も答えていただけるなんて・・・・。 (回答の)質問は↑の補足の通りです。 予想通りのクレクレ厨かって感想だと思いますが(^-^; 知識不足っていうより、やる気不足ですね・・・。 マニュアルがあるということを教えて(?)いただきありがとうございます。 意図したことではないと思いますが、知らなかったもので(正確には知る気がなかったですね)。 引き続きの回答ありがとうございました。 ・・・マニュアルがないわけないじゃん!!!というツッコミやらお叱りやらは覚悟の上です^^;

nanayarawa
質問者

補足

>マニュアルを最後まで全部読んでますか? えぇっと・・・ごめんなさい、読んでないです。 というかマニュアルと呼ばれるものを知りませんでした。 ・・・なんて言ったら怒りますよね(^-^; ろくに調べもせずに楽して知りたいっていう甘い考えを持ってました。 >常識的(TCP/IPを知っていれば)に理解できる事もありますし TCP/IPについては素人なんで勉強と平行しつつ調査したいと思います。

  • a-saitoh
  • ベストアンサー率30% (524/1722)
回答No.3

マニュアルに書いてあるエラーコードを見れば、それ自体がどういう時にエラーが起きるかの説明に十分なっているはずなのですが。 TCP/IP通信について勉強されたらどうでしょうか。

nanayarawa
質問者

お礼

回答ありがとうございます。 >TCP/IP通信について勉強されたらどうでしょうか。 ごもっともです。 勉強した上で質問するべきでしたね。 プログラミングのことばかり意識していたもので、 TCP/IP自体の勉強が疎かになってしまいました。 >マニュアルに書いてあるエラーコードを見れば、 >それ自体がどういう時にエラーが起きるかの説明に十分なっているはずなのですが 例えば     戻り値 -1:~に失敗した時 っていうのがあったとして、失敗した時に-1が返るのは見れば当然わかることですが、 なぜ失敗するのかまでがわからない、といった感じです。 私の調べ方と知識の足りなさが問題だと思うので、引き続き調査・勉強を行い、 それでも不明な点があれば再度質問するといった感じにします。

  • _himajin_
  • ベストアンサー率65% (128/195)
回答No.2

戻り値の説明(お使いの開発環境のマニュアル または http://www.linux.or.jp/JM/html/LDP_man-pages/man2/socket.2.html など)だけでは不足と言うことでしょうか。 Linuxや*BSDなどフリーな環境限定かつ実装依存になってしまいますが、glibcなどライブラリのソースを見る、と言う手はどうでしょう? # と、おもったら http://ftp.gnu.org/gnu/glibc/glibc-2.7.tar.bz2 の socket/socket.c には中身がないなぁ… すべてを網羅してるわけではないようですが、標準Cライブラリを実装したものを公開している方などもいらっしゃいます。 http://libc.blog47.fc2.com/

nanayarawa
質問者

お礼

回答ありがとうございます。 >戻り値の説明だけでは不足ということでしょうか。 現時点でこの知識が必要か、と言われたら返答に詰まりますね^^; 課題程度のプログラムであれば戻り値だけみれば問題ないと思いますし・・・。 ただ、これからプログラムで飯を食っていく、ということで興味があることは調べていこうかなと思っています。 ちなみに自分は高校卒業したばかりのピカピカの社会人一年生です(笑) 参考URLの「標準Cライブラリの実装」ですが、軽く目を通した感じだと解説もあり、自分で解読するより理解できそうです。

  • bardfish
  • ベストアンサー率28% (5029/17765)
回答No.1

通信関連の関数というとsockets.libを真っ先に思い浮かべます。 まっとうなコンパイラを使用していればLIBのソースコードがついているはずです。そのソースを読めばエラーの原因が特定できます。 各種libのソースがあるわけですから、それを詳細に解説したHPや書籍など皆無です。少なくとも私は見たことありませんし、ソースを見れば理解できます。 と言っても低レベルI/Oの集まりなので、I/Oエラーの場合はハードに起因したり、ネットワーク系だとネットワーク構成に起因するエラーもあります。 ソースが読めるだけでは解決に至らない場合もあるのでそれなりに広い知識が必要です。

nanayarawa
質問者

お礼

回答ありがとうございます。 >まっとうなコンパイラを使用していればLIBのソースコードがついているはずです。 >そのソースを読めばエラーの原因が特定できます。 なるほど。 そういった手があるのですね。参考になります。 っといっても私は知識があるほうではないので、理解には苦しむと思います^^; 関数のエラーの原因解明を目的として、システムやハードウェアについても学ぶことにします。 迅速な回答ありがとうございました。

関連するQ&A

  • wave系関数のエラーについて

    引き続きwave系のプログラムについての質問をさせて頂きます。  waveInUnPrepared関数で戻り値に5つまりMMSYSERR_INVALHANDLEが返ってくる原因について。  APIによる録音再生プログラムを作っています。 マイクによる録音をしている途中で停止ボタンを押すと waveInResetを呼び出し、MM_WIM_DATAを受け取ったら waveInCloseをし、最後にMM_WIM_CLOSEでwaveInUnPreparedを行い録音終了とするようにました。 ですがwaveInReset、waveInCloseはともに戻り値が0なのですがwaveInUnPreparedは戻り値が5でした。MMSYS.hによると5はMMSYSERR_INVALHANDLEということでした。 現在このプログラムは録音を開始してバッファがいっぱいになったら(3秒)録音を終了する、そのバッファ分再生する。ということはできるですが録音中(3秒以内)に停止ボタンを押してその分だけ再生すると言うことができません。 MMSYSERR_INVALHANDLEが発生する原因についてどのようなものが考えられるのでしょうか。 なおバッファ分の録音&再生時にも戻り値は5でした。 手順 録音ボタン→録音処理→(3秒以内に)停止ボタン→MM_WIM_DATAでwaveInClose→MM_WIM_CLOSEでwaveInUnPrepared 環境 VC+6.0 win2000

  • ”select”,”FD_ISSET”という関数はMicrosoft Visual C++ 2008 Express Editionで使えますか?

    今、Microsoft Visual C++ 2008 Express Editionでソケット通信のサーバ、クライアントプログラムを作りたくていろいろ調べていて、特に複数クライアントが接続できるサーバを作りたいと思っています。 ただ、どうしてもrecv関数に入ると、1台の端末からのデータ受け取りでステップが停止してしまって、通信を占有してしまい、他のクライアントからのデータを受け付けることができないので、どうすればよいのかと思い、 ググッていたら http://x68000.q-e-d.net/~68user/net/c-echo-2.html このページにselect関数とFD_ISSET関数というのがあって、select関数の引数にデータを設定すれば、FD_ISSET関数の戻り値で作成したソケットに読み取り可能なデータがあるのかを検知できて、検知したらrecv関数でとれるので、これでrecv関数での立ち止まりがないので、複数のクライアントからのデータを行えるというプログラムを見つけました。 ただ、このFD_ISSET関数、select関数はまさにマルチスレッドのやり方だと思うので、Microsoft Visual C++ 2008 Express EditionではMFCがないとのことなのですが、使用することはできるのでしょうか?

  • error C2712: オブジェクト アンワインディングが...について

    VC++の勉強中です。例外処理に対してあまり詳しくないですが。 問題が発生しました。VS2005 の環境です。分かったかたは ご指摘お願いします。 今書いているソースには、 error C2712: オブジェクト アンワインディングが必要な関数内で __try を使用できません。というメッセージが出ていますが、今いろいろ調べています。Win32のAPIを使っているところ__try __leaveなどのSEHの機構の例外処理のやり方です。 これをプロパティ-C/C++-コード生成/C++の例外を無効にすると、問題が なく動くですが。 具体的に、どういう解決すればいいですが、C++の例外を無効にするわけに いけないし。 よろしくお願いします。

  • recvfrom関数の戻り値について

    初めて質問させて頂きます。 現在、LinuxのUnixドメインを使用した内部通信プログラムを 作成しているのですが、recvfrom関数の戻り値で-512という値が 返ってきて頭を悩ませています。 いろいろなHP等でrecvfrom関数の戻り値について記述されている内容は 受信サイズか-1となっているのですが・・・-512という値については さっぱりでした。 -1の場合は、errnoが入るようなのですが、-512の場合、errnoが0のままで何もはいっていないように見えます。 どの様な問題が発生しているかの見当もつかない状態です。 すみませんが、宜しくお願い致します。

  • a[i]とa[i+1]を入れ替えるような関数を作成するC言語の問題

    以下のように配列aとそのサイズsとインデックスiを引数 にとり、a[i]とa[i+1]を入れ替えるような関数を作成する問題。 但し、この関数内で配列の外側をアクセスしないようにエラー チェックをすること。正常に処理が終了した場合は0を返し、 そうでない場合は-1を返すようにする。 main関数では、10個分の整数を入れる配列を宣言し、 データをユーザに入力させる。 次に、ユーザに1個整数を入力させ、0からその番号まで順に iをずらしてswap_array関数を読んだ後、配列に入っているデータを 表示させる。 ・配列にデータを入力でき、交換が正しくできている ・ユーザが配列の外側を指定した場合は、エラーである旨を 表示して終了する。 取りあえずこうゆうかんじになるのですが、//の前などをどうにすればいいか分かりません。分かる方は知恵を貸してください。 int swap_array(int a[], int s, int i) { //a[i]番目とa[i+1]番目を入れ替え処理をする //正しく交換できた場合はreturn(0); //エラーが発生した場合はreturn(-1); } int main() { //サイズ10の配列の宣言 int a[10]; //ユーザに10個のデータの入力をさせる int i; for(i=0;i<10;i++){ scanf("%d",&a[i]); } //0番目から何番目まで入れ替えるかユーザに聞く: (ユーザがnと入力) int n; ...... //繰り返し構造を使って、0番目からn番目まで隣同士を交換 for(i=0;i<=n;i++){ int v; // swap_arrayを繰り返し呼び出すが、毎回戻り値が0であることを         //チェックしてエラーが発生していないことを確かめる v=swap_array(a,10,i); // エラーが発生していたら エラーが発生したことを表示して //break;文で繰り返し構造から外にでる。 if(v==-1) break; } //エラーが発生しなかった場合に、入れ替えられた配列の内容を表示 if(v!=-1){ ..... 配列の内容を表示 } return(0);

  • C言語につて、教えてください!!

    C言語について教えてください テキストファイル CD_DATA|45 DVD_DATA|601 MD_DATA|24 メイン関数と読み込み関数で、テキストファイルの'|'より後ろを構造体に書き込み エラー処理でテキストファイルに'|'が無い時エラーメッセージをだす。 テキストファイルの中の行数が違った時エラーメッセージをだす。 以上です、教えてくださいお願いします。

  • RS232C非同期通信初期化でエラー

    通信相手の装置が500ms周期で永久的に送信していた場合、当方のパソコン を再起動して通信ソフト(WIN32API)を起動すると"CREATEFILE"でエラーが発生して接続できません。戻り値は0xFFF...FF(-1)です。 通信相手を停止した状態でパソコンを再起動して通信ソフトを起動すると 正常に接続できます。どの様に対処すれば良いのかどなたか教えて下さい。 OS:WindowsXP 通信手順は無手順、100BYTEデータ

  • 引き数がポインタでない関数の戻り値はなぜint型なのか?

    最近、疑問に思っていることがあって質問したいんですが、一般的にc言語 で使われる関数っていうのは、引き数としてポインタをとる関数以外は全て 戻り値はint型なのですがこれはなぜでしょう。私自身の結論としては、も し関数の戻り値がchar型だとしたらchar型で表せる範囲の値は全てasciiコー ドとして使われているので、もしエラーがあって戻り値としてEOF(-1)を返す 際に1byteでは同じビット配列になる255が既に使われていてEOFとして-1を定 義できないために、-1と255が同じビット配列ではない1byte以上のデータ型 つまりint型(たぶん、int型がコンピュータが一番効率良く処理できるデータ型なのでたぶんint型を使ったと思いますが)を使ったのではないかと言う 結論に達したのですがこれは正しいのでしょうか。どなたか御教授お願い致 します。

  • 関数引数に対する制限値チェック方法

    引数に対する制限値チェック方法  プログラミング(組み込み系C言語)関数作成時にいつも私が迷ところなのですが、  関数の引数に対する制限値(範囲外)チェックどうするか、次の(1)、(2)で悩んでます。。   【1】関数内で制限値チェックで行い、制限値外であれば戻り値でエラーコードを返す。   【2】関数呼び出し時に、引数となる値(変数)をチェックし、制限値内であることを確認してから、関数を呼び出す。  上記の【1】、【2】の方法どちらがよいでしょうか?  状況にもよるとは思うのですが、その場合はどういった状況時に(1)||(2)がよいのか教えてください。  (【3】もあればお願いします。)  --【1】がお勧めの場合の質問  (1)本関数での"結果"を返したいときどうすればよいかアドバイスください。     戻り値("結果")と、エラーコードを兼用するのはなんかイヤです。。     エラーコード付き関数は、全て同じ戻り値(1:OK時、-1:NG時 みたいに)     としてまとめたいからです。  (2)極端にほとんどの関数の戻り値を、OK/NG とす。これってどうですか?、 ///////////////////////  【1】、【2】の利点、欠点を僕なりに考えてみました。  ##【1】の利点/欠点  利点:   ・本関数呼び出し時に、毎回制限チェックをしなくてよくなる。    (汎用的に様々な場面で、使用するのであればこれは良い利点だと思います。)  欠点:   ・戻り値のとして、エラーコードを返さなくてはならないため、本関数での結果を返したい場合、    以下方法をとらないといけない。      1、引数をポインタとして、その引数で値を返す。      2、戻り値として、エラーコードと兼用して返す。        (例:エラー時の戻り値 = 0、正常にの戻り値 = 1~ 255)  ##【2】の利点/欠点  利点:   ・エラーコードを返す必要がなくなるため、戻り値が有効利用できる。  欠点:   ・関す呼び出し毎に、制限チェックが発生し、制限チェック忘れが発生する。    (汎用的に使うにのであればなお・・・)

  • 複数関数からの戻り値returnの指定

    いつもお世話になります。 ActionScrip3に関する質問です。 処理1が終わった段階で戻り値をreturnするという処理を 作成したく下記のように作りました。 流れとしては、関数func1の中に複数の処理があると仮定して、その一連の処理を完了させた 時点でevent.complete(処理完了)によりfunc2に移動し、func2から戻り値の値を 指定したいと考えております。 下記の処理を行ってもfunc1の中でreturnを指定していないので「関数は戻り値をかえしません」 というエラーになってしまいますが、下記の処理以外でも結構ですので、 「一定の処理完了後に戻り値(return)を発生」させる手段をご教授いただけないでしょうか? お手数ではありますが、何卒宜しくお願いいたします。 var bln:Boolean; bln = func1(); function func1():Boolean {  // ここに複数の処理があると仮定する  // 終了後イベント  addEventListener(event.COMPLETE, finish);    function finish() {   return false;  } }

    • ベストアンサー
    • Flash

専門家に質問してみよう