2016-09-02 4 views
1

fopenとifstream.open()の両方でディレクトリをファイルとして開くときに、正しいエラーコードをerrnoから取得しようとしています。私はEISDIRを期待して、EACCESを取得します。ウィンドウ上のディレクトリでfopenを使用する

Windows 7 x64でMSVC 12.0ツールチェーンをコンパイル(および実行)しています。

著者は「ストリームフェイルビット(またはbadbit)。エラー状態:ディレクトリです」という記事を読んでいます(https://gehrcke.de/2011/06/reading-files-in-c-using-ifstream-dealing-correctly-with-badbit-failbit-eofbit-and-perror/)。

私は、GCC 4.6(またはこれ以上、atm)でauthorsファイルをコンパイルし、ディレクトリを引数として渡すとEACCESも取得します。

私は、ディスクオブジェクトがWindows上のディレクトリであるかどうかを簡単に伝える方法がないことを知っています。そのため、EISDIRを取得してもあまり驚くことではありません。

これについて何かできることはありますか(ウィンドウ上でEISDIRを取得する、つまり)? 同様の(予期しない)方法で動作する他のerrnoがありますか?

+1

いつものように[MCVE]を提供してください。また、ダイレクトをファイルとして開くこともできません。 –

+0

私はあなたが運が悪いと思う - 私は、Microsoft Cライブラリで参照されている 'EINVAL'と' is_a_directory'シンボル(私はVS 12.0とユニバーサルCRTをVS 14.0で使用したものをチェックした)定義自体、つまりそれらはそこにありますが、使用されていません。代わりのもの(MinGWなど)はmsvcrt.dllにリンクしていますが、あなたはどちらかの方法で動作しないことを既に確認しています。 – cynic

+0

私は、デバイスオブジェクトがファイルかディレクトリかどうかをチェックするのにerrnoを使うのは良い選択ではないと思います。このメソッドはプラットフォームとコンパイラに依存するため不安定で、C++標準ではifstreamエラーの処理の動作を記述していません。 –

答えて

3

MicrosoftのCランタイムライブラリは、EISDIRシンボルを定義しますが、使用しません。だからあなたはそれらのエラーコードを取得しません。あなたの他の質問への答えを得るには、Cライブラリのソースコードを調べる必要があります。これはVisual Studioと、Visual Studio 2015以降の場合はWindows SDKと共に出荷されます。

ユニバーサルCRTを使用するVisual Studio 2015(14.0)では、希望のファイルはerrno.cppと呼ばれ、Windows SDKに含まれています。c:\Program Files (x86)\Windows Kits\10\Source\10.0.10586.0\ucrt\misc\errno.cppにあります。

Visual Studio 2013(12.0)では、希望のファイルはdosmap.cと呼ばれ、Visual StudioのインストールディレクトリのVCサブディレクトリに含まれています。C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\crt\src\dosmap.cにあります。

これらのファイルの両方に、OSエラーコードをCライブラリエラーコードにマッピングするエラーテーブルが含まれています。特定のマッピングが期待通りのものかどうかを確認するために使用することができます。

+0

Windows上でEISDIRを使用していないので...明確にしていただきありがとうございます。 –

-1

fopen関数はWindows APIの一部ではありません。 CまたはC++開発環境のランタイムサポートライブラリから提供されます。この言語で

c:\users\kaz>txr 
This is the TXR Lisp interactive listener of TXR 148. 
Use the :quit command or type Ctrl-D on empty line to exit. 
1> (open-file ".") 
#<file-stream . 6fffff00738> 
2> (get-string *1) 
** error reading #<file-stream . 6fffff00738>: 21/"Is a directory" 
** during evaluation at expr-2:1 of form (get-string *1) 
3> 

open-file機能がfopenを使用し、get-stringは、最終的にはC stdio.hの機能に依存しています:

このEISDIRエラーはCygnalとCygwin用に構築され、出荷されたCアプリケーションで動作します。 fopenは成功しますが、その後の入力試行ではEISDIRエラーが発生します。 (Linuxや他のプラットフォームと同じ伝統的な21コードにマップされています)。それは例外に変わります。 "Is a directory"文字列はstrerrorです。

Microsoft Visual Studioで提供されているよりも優れたPOSIXサポートを備えた、より豊かな機能を備えたCランタイムライブラリが必要です。

関連する問題