ページ 1 / 1
エラーの意味がわかりません。
Posted: 2012年2月08日(水) 16:27
by おならちゃん。
サンプルプログラムを打ち込みました。
http://www.ncad.co.jp/~komata/c-kouza14.htm
コード:
#include<stdio.h>
#include<stdio.h>
#include<dirent.h>
void main(argc,argv)
int argc; //exefileにしたときにコマンドラインからコマンドをとって文字の総数と文字のポインタの配列を取得する。
char *argv[];
{
DIR *dir;
struct dirent *dp;
char path[512];
if(argc<=1){//もし取得した文字数が1以下なら(argcはもともと何かが入っているから1からでしたっけ?)pathにカレントディレクトリを渡す。
strcpy(path,".");
}else{//それ以外なら配列をパスにコピー
strcpy(path,argv[1]);
}
if((dir=opendir(path))==NULL){//もしdirがNULLならエラーを表示して終了。
perror("opendir");
exit(-1);
}
for(dp=readdir(dir);dp!=NULL;dp=readdir(dir)){//構造体に次のファイルをいれる;dpがNULL以外;なぜ二回同じことをやってるのでしょうか?
printf("%s\n",dp->d_name);//構造体を順々に変えていき名前を表示
}
closedir(dir);//opendirを終了
}
出てきたエラーがこの三つです。
1>c:\game\dxlibtest\dxlibtest\test.cpp(4) : error C2065: 'argc' : 定義されていない識別子です。
1>c:\game\dxlibtest\dxlibtest\test.cpp(4) : error C2065: 'argv' : 定義されていない識別子です。
1>c:\game\dxlibtest\dxlibtest\test.cpp(5) : error C2448: 'main' : 関数の定義が間違っています
ですが、ちゃんとint argcとchar argvは定義しているのにこのエラーがでますし、int main のどこが間違っているのかがわかりませんでした。
僕はこの関数をWINAPIで使いたいのですがそのときに使うargcとargvはどこにあるのでしょうか?
もうひとつこのサンプルプログラムの僕の解釈があっているのかが心配なので、違うところがあったら教えてください。
僕の解釈はプログラムの中に書き込みます。
ご回答よろしくお願いします。
Re: エラーの意味がわかりません。
Posted: 2012年2月08日(水) 17:14
by softya(ソフト屋)
残念ながらopendirやreaddirはC言語の標準規格ではありません。
「BohYoh.com【C言語講座】標準ライブラリ」
http://www.bohyoh.com/CandCPP/C/Library/
gccやBCCなら有るみたいですが、VC++の場合使えません。参考サイトもUNIXと書いてありますね。
ここは、素直にWin32APIを使って下さい。FindFirstFile,FindNextFileなどを使います。
「指定したディレクトリ以下のファイルを列挙」
http://www14.big.or.jp/~ken1/tech/tech5.html
ファイルとディレクトリが列挙されるのでFILE_ATTRIBUTE_DIRECTORYで区別して下さい。
WEBサイトを参考にする場合は対応OSや環境を確認して下さいね。確か前回も勘違いされていたと思います。
あと
void main(argc,argv)
int argc; //exefileにしたときにコマンドラインからコマンドをとって文字の総数と文字のポインタの配列を取得する。
char *argv[];
の書き方は非常に古い規格の書き方ですので使わないほうが良いです。
今の書き方です。
「コマンドライン引数」
http://www9.plala.or.jp/sgwr-t/c/sec11-4.html
Re: エラーの意味がわかりません。
Posted: 2012年2月08日(水) 17:16
by h2so5
コード:
void main(argc,argv)
int argc; //exefileにしたときにコマンドラインからコマンドをとって文字の総数と文字のポインタの配列を取得する。
char *argv[];
{
このような関数定義はC言語の古い規格なので今のコンパイラでは使えません。
void main(int argc,char *argv) {
でOKです。
Re: エラーの意味がわかりません。
Posted: 2012年2月08日(水) 19:39
by beatle
細かいことですが,main関数の戻り値はintが正式です.
Re: エラーの意味がわかりません。
Posted: 2012年2月08日(水) 22:49
by かずま
h2so5 さんが書きました:
このような関数定義はC言語の古い規格なので今のコンパイラでは使えません。
ISO/IEC 9899:2011 のファイナルドラフトN1570 を見ても、まだその書き方は廃止されていません。
http://www.open-std.org/jtc1/sc22/wg14/ ... /n1570.pdf の Annex A のここです。
コード:
(6.7.6) declarator:
pointeropt direct-declarator
(6.7.6) direct-declarator:
...
direct-declarator ( identifier-list opt )
(6.9.1) function-definition:
declaration-specifiers declarator declaration-list opt compound-statement
最初の質問者は、エラーメッセージからわかるように、test.cpp としていますから
コンパイラは、これを C++ としてコンパイルしています。
C++ は C とは違う言語です。
Re: エラーの意味がわかりません。
Posted: 2012年2月08日(水) 23:34
by softya(ソフト屋)
どちらにしても古い規格には違いないので、最近は余り見ない書き方ですしC++との互換もなく避けたほうが良いというのはみなさんの意見の一致するところだと思います。
旧来のソースコードの互換性という意味では必要だと思いますが、新しい書き方で書きましょうとと言うことで。
Re: エラーの意味がわかりません。
Posted: 2012年2月09日(木) 00:07
by おならちゃん。
たくさんのご回答ありがとうございます。
softya様
h2so5様
beatle様
かずま様
そして、もう一度
softya様
本当にありがとうございます。
実は最初にご返信を見させていただき、ほぉなるほど!と見ていてできたらまた返信させていただこうと思っていました。
そしてもう一度参考にさせてもらおうときてみたら、たくさんのご返信があることがわかりました。
本当に感謝感激です@w@!!!
誠にありがとうございます。
今から取り組ませていただきます。
Re: エラーの意味がわかりません。
Posted: 2012年2月09日(木) 12:32
by おならちゃん。
softya様 ご迷惑をかけてすみません
http://www14.big.or.jp/~ken1/tech/tech5.html
ここのサンプルプログラムの理解に苦しんでいます。どうかお力を御貸し下さい。
コード[C++]: 全て選択
12
strcpy(temp,path);
HANDLE h=FindFirstFile(temp,&lp);
これはなぜFindFirstFile(path,&lp);としていないのでしょうか?
サイズの大きさをMAX_PATHに統一するためですか?
コード[C++]: 全て選択
12
if((lp.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
&& strcmp(lp.cFileName,"..")!=0 && strcmp(lp.cFileName,".")!=0)
なにをしているのでしょうか?lp.dwFileAttributes & FiLE_ATTRIBUTE_DIRECTORY
これはファイルの属性?とlpをANDして何がおこるのでしょうか?
そのつぎの".."をstrcmpするのはわかるような気がします。次の深層かをしらべているんですよね?
しかし"."これも同じときにやってしまうのはなぜなのでしょうか?これは今いる階層の場所ですよね?
どちらか0以外ならどちらかが0にならないとまったく指定したところ意外を探していることになりませんか?
そして、そこのif分が成功したときに、もう一度Directory(subpath);しているのが、よくわかりません。
サブパスの中にフォルダを見つけたときにさらにそのフォルダの中にいくということでしょうか?
wsprintfとは、いったいどのように使うのでしょうか?調べてみたのですが、三つ引数が書いてありました。
http://msdn.microsoft.com/ja-jp/library/cc364872.aspx
しかし、このサンプルプログラムは4つ引数を持たせているきがするのですが、この使い方もできるのでしょうか?
実際この関数はsprintfのようなものらしいのですが、文字列の表示が目的なのでしょうか?それとも、文字列をバッファに格納するのが目的なのでしょうか?バッファで調べてみたところプリンターなどの時間の差を埋めるために一度情報をためておくところがバッファらしいのですが、深層いく前にバッファにハンドルをとっておいて、後から呼び出すということでしょうか?
コード[C++]: 全て選択
1
if((lp.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)!=FILE_ATTRIBUTE_DIRECTORY)
これは、フォルダとファイルの分別?をするのがFILE_ATTRIBUTE_DIRECTORYですよね?
これと、これをANDしたのを違うかをしらべているんですか?
それでなにが・・・
本当に質問だらけですみません。
ご回答よろしくお願いします。
Re: エラーの意味がわかりません。
Posted: 2012年2月09日(木) 12:38
by おならちゃん。
。。あ
Re: エラーの意味がわかりません。
Posted: 2012年2月09日(木) 12:39
by おならちゃん。
同じ質問ですが、
で囲みわすれてしまったのでもう一度書かせて下さい。
softya様ご迷惑をかけてすみません。
http://www14.big.or.jp/~ken1/tech/tech5.html
ここのサンプルプログラムの理解に苦しんでいます。どうかお力を御貸し下さい。
コード:
strcpy(temp,path);
HANDLE h=FindFirstFile(temp,&lp);
これはなぜFindFirstFile(path,&lp);としていないのでしょうか?
サイズの大きさをMAX_PATHに統一するためですか?
コード:
if((lp.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
&& strcmp(lp.cFileName,"..")!=0 && strcmp(lp.cFileName,".")!=0)
なにをしているのでしょうか?lp.dwFileAttributes & FiLE_ATTRIBUTE_DIRECTORY
これはファイルの属性?とlpをANDして何がおこるのでしょうか?
そのつぎの".."をstrcmpするのはわかるような気がします。次の深層かをしらべているんですよね?
しかし"."これも同じときにやってしまうのはなぜなのでしょうか?これは今いる階層の場所ですよね?
どちらか0以外ならどちらかが0にならないとまったく指定したところ意外を探していることになりませんか?
そして、そこのif分が成功したときに、もう一度Directory(subpath);しているのが、よくわかりません。
サブパスの中にフォルダを見つけたときにさらにそのフォルダの中にいくということでしょうか?
wsprintfとは、いったいどのように使うのでしょうか?調べてみたのですが、三つ引数が書いてありました。
http://msdn.microsoft.com/ja-jp/library/cc364872.aspx
しかし、このサンプルプログラムは4つ引数を持たせているきがするのですが、この使い方もできるのでしょうか?
実際この関数はsprintfのようなものらしいのですが、文字列の表示が目的なのでしょうか?それとも、文字列をバッファに格納するのが目的なのでしょうか?バッファで調べてみたところプリンターなどの時間の差を埋めるために一度情報をためておくところがバッファらしいのですが、深層いく前にバッファにハンドルをとっておいて、後から呼び出すということでしょうか?
コード[C++]: 全て選択
コード:
if((lp.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)!=FILE_ATTRIBUTE_DIRECTORY)
これは、フォルダとファイルの分別?をするのがFILE_ATTRIBUTE_DIRECTORYですよね?
これと、これをANDしたのを違うかをしらべているんですか?
それでなにが・・・
本当に質問だらけですみません。
ご回答よろしくお願いします。
Re: エラーの意味がわかりません。
Posted: 2012年2月09日(木) 13:00
by softya(ソフト屋)
引用しづらいので番号を振って見ました。
http://www14.big.or.jp/~ken1/tech/tech5.html
ここのサンプルプログラムの理解に苦しんでいます。どうかお力を御貸し下さい。
(1)
コード:
strcpy(temp,path);
HANDLE h=FindFirstFile(temp,&lp);
これはなぜFindFirstFile(path,&lp);としていないのでしょうか?
サイズの大きさをMAX_PATHに統一するためですか?
(2)
コード:
if((lp.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
&& strcmp(lp.cFileName,"..")!=0 && strcmp(lp.cFileName,".")!=0)
なにをしているのでしょうか?lp.dwFileAttributes & FiLE_ATTRIBUTE_DIRECTORY
これはファイルの属性?とlpをANDして何がおこるのでしょうか?
そのつぎの".."をstrcmpするのはわかるような気がします。次の深層かをしらべているんですよね?
しかし"."これも同じときにやってしまうのはなぜなのでしょうか?これは今いる階層の場所ですよね?
どちらか0以外ならどちらかが0にならないとまったく指定したところ意外を探していることになりませんか?
(2-2)
そして、そこのif分が成功したときに、もう一度Directory(subpath);しているのが、よくわかりません。
サブパスの中にフォルダを見つけたときにさらにそのフォルダの中にいくということでしょうか?
(2-3)
wsprintfとは、いったいどのように使うのでしょうか?調べてみたのですが、三つ引数が書いてありました。
http://msdn.microsoft.com/ja-jp/library/cc364872.aspx
しかし、このサンプルプログラムは4つ引数を持たせているきがするのですが、この使い方もできるのでしょうか?
実際この関数はsprintfのようなものらしいのですが、文字列の表示が目的なのでしょうか?それとも、文字列をバッファに格納するのが目的なのでしょうか?バッファで調べてみたところプリンターなどの時間の差を埋めるために一度情報をためておくところがバッファらしいのですが、深層いく前にバッファにハンドルをとっておいて、後から呼び出すということでしょうか?
コード[C++]: 全て選択
(3)
コード:
if((lp.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)!=FILE_ATTRIBUTE_DIRECTORY)
これは、フォルダとファイルの分別?をするのがFILE_ATTRIBUTE_DIRECTORYですよね?
これと、これをANDしたのを違うかをしらべているんですか?
それでなにが・・・
本当に質問だらけですみません。
ご回答よろしくお願いします。
Re: エラーの意味がわかりません。
Posted: 2012年2月09日(木) 13:12
by softya(ソフト屋)
私が振った番号を元に回答しています。
(1) そのあとで書き換える為ですね。元は書きかえれませんので。
(2)に関してはディレクトリの種類を判定しています。
このプログラより簡単にして、FindFirstFileとFindNextFileだけにしてprintfしてみると分かると思います。
(2-2)に関しては、サブディレクトリを再帰的に処理しています。
(2-3)wsprintfはsprintfのワイド文字版WindowsAPIで、ワイド文字についてはUNICODEとマルチバイト文字を調べてみてください。sprintfは文字列を作り出ためのprintfです。
(3)dwFileAttributes が複数の情報を含むビット情報のデータだからです。
ビット演算でFILE_ATTRIBUTE_DIRECTORYの情報だけを取り出してFILE_ATTRIBUTE_DIRECTORYビットがONかOFFをかをチェックしています。
Re: エラーの意味がわかりません。
Posted: 2012年2月09日(木) 13:13
by non
(1)
再帰呼び出しでサブディレクトリを探索するときに、探索するパスが変更になるからです。
(2)
..は親のディレクトリです。親と自分自身のディレクトリは探索しないという意味になります。
(2-2)
サブディレクトリの探索です。再帰呼び出しってわかりますか?
wsprintfの引数ですが、printfと同じように可変長引数です。
また、これはサブディレクトリのパスを作っています。
後はまた。
追伸:ダブったがまあ、良いか。
Re: エラーの意味がわかりません。
Posted: 2012年2月09日(木) 13:42
by YuO
ちょっと補足。
softya(ソフト屋) さんが書きました:(2-3)wsprintfはsprintfのワイド文字版WindowsAPIで、ワイド文字についてはUNICODEとマルチバイト文字を調べてみてください。sprintfは文字列を作り出ためのprintfです。
wsprintfは「sprintfまたはswprintf相当のWindowsAPI」ですね。
wsprintfAがsprintf,wsprintfWがswprintf (size_t引数無し)に対応します。
# WindowsのAPIの例に漏れず,UNICODEの有無で切り替わるような#defineが書かれています。
Re: エラーの意味がわかりません。
Posted: 2012年2月09日(木) 14:46
by softya(ソフト屋)
YuO さんが書きました:ちょっと補足。
softya(ソフト屋) さんが書きました:(2-3)wsprintfはsprintfのワイド文字版WindowsAPIで、ワイド文字についてはUNICODEとマルチバイト文字を調べてみてください。sprintfは文字列を作り出ためのprintfです。
wsprintfは「sprintfまたはswprintf相当のWindowsAPI」ですね。
wsprintfAがsprintf,wsprintfWがswprintf (size_t引数無し)に対応します。
# WindowsのAPIの例に漏れず,UNICODEの有無で切り替わるような#defineが書かれています。
失礼しました。swprintfと混同しました。swprintfがC言語標準ライブラリのワイド文字用でwsprintfはWindowsAPI用sprintfですね。略してwsprintf。
Re: エラーの意味がわかりません。
Posted: 2012年2月22日(水) 04:45
by おならちゃん。
みなさま、たくさんのご回答ありがとうございました 。
大変参考になりました。
本当にありがとうございます。