こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

fopen関数について

-----------------------------------------
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE *fp;
char filename[80],ss[256];

printf("ファイル名=");
gets(filename);

if((fp=fopen(filename,"r"))==NULL){
printf("ファイルをオープンできません.\n");
exit(1);
}

while(fgets(ss,256,fp)!=NULL){
printf("%s",ss);
}
puts("");

fclose(fp);

return 0;
}
-----------------------------------------

初心者な内容の質問ですいません。
以上のプログラムでまず、「gets(filename);」により、「filename[80]」の配列に「aaa.txt」という文字列を格納し、そのファイルをfopenで読もう込もうとしています。
そこで、

if((fp=fopen(filename,"r"))==NULL)

の部分に疑問があるのですが、「filename」という配列名だけで中身の「aaa.txt」と何故認識できるのでしょうか?
配列名ということで、先頭アドレスのみの情報しかないと思いました。
教えていただければ嬉しいです。

投稿日時 - 2009-03-17 04:39:15

QNo.4803386

困ってます

質問者が選んだベストアンサー

> 「filename」という配列名だけで中身の「aaa.txt」と何故認識できるのでしょうか?
> 配列名ということで、先頭アドレスのみの情報しかないと思いました。

先頭のアドレスだけが分かっていれば、
それを元に配列をたどっていって文字列全体を把握できますよね?
文字列の終わりには\0(値0)が格納されるので、
それを元に文字列の終わりを検出することができます。
なので
「filename[i]に格納された値が\0になるまで、filename[i]の値を取り出していく」
ということをすれば、文字列全体を取り出すことができます。

例えばgets(filename)で「aaa.txt」という文字列を格納しようとすると、
配列filenameには次のように数値が格納されます。

filename[0] … 97 (ASCIIコードにおいて、値97はaに対応)
filename[1] … 97
filename[2] … 97
filename[3] … 46 (ASCIIコードにおいて、値46は.に対応)
filename[4] … 116 (ASCIIコードにおいて、値116はtに対応)
filename[5] … 120 (ASCIIコードにおいて、値120はxに対応)
filename[6] … 116
filename[7] … 0 (文字列の終わりには値0が格納されます)
filename[8] … 適当な値(filename[9]以降も以下同様)

検証に使ったプログラムを載せておきます。

/***********************************************/
#include <stdio.h>

int main(void){
charfilename[32];
inti;

gets(filename);

for(i = 0; i < 32; i++){
printf("filename[%d] = %d\n", i, filename[i]);
}
printf("\n");

puts(filename);

return(0);
}
/***********************************************/

投稿日時 - 2009-03-17 06:08:24

お礼

ご回答ありがとうございます。

>先頭のアドレスだけが分かっていれば、それを元に配列をたどっていって文
>字列全体を把握できますよね?
>文字列の終わりには\0(値0)が格納されるので、それを元に文字列の終わり
>を検出することができます。

上記の内容理解できました!
配列に格納された要素を、10進数で表すプログラム分かりやすかったです。

投稿日時 - 2009-03-17 13:26:11

ANo.2

このQ&Aは役に立ちましたか?

2人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.3

zwi

確かいくつか前の回答に文字列定数"aaa.txt"も文字列のポインタだと説明した気がするんですが、つまりchar *ですね。
なので、
char filename[80];
と定義されたfilenameも文字列のポインタであるchar *です。
今までの質問への回答の理解がもう一歩かと思います。今一度、今までの質問を見直して理解できたと思われる質問はちゃんと閉じておいてください。理解できていなかったら再質問を。

今回は文字列版のダンプを作ってみました。
#include <stdio.h>
#include <string.h>

char filename[80] = "aaa.txt";

void strdump(char *pchar);//プロトタイプ宣言

int main(void)
{
strdump( filename );
strdump( "bbb.txt" );

return 0;
}

//簡易文字列版ダンプ。
void strdump(char *pchar)
{
int i;

printf( "%s\n", pchar );
for( i=0 ;; i++ ) {
printf( "%02X", pchar[i] );
//文字列の終端で終了
if( pchar[i]==0x00 ) break;
}
printf( "\n" );
}

投稿日時 - 2009-03-17 11:03:35

お礼

ご回答ありがとうございます。

>char filename[80];
>と定義されたfilenameも文字列のポインタであるchar *です。

上記の内容忘れぬようしっかり頭に入れておきます!
配列に格納した文字列「aaa.txt」、「bbb.txt」を16進数で表すプログラムとても分かりやすかったです。

投稿日時 - 2009-03-17 13:33:00

ANo.1

プログラムの良し悪しは別として、

fopenの第一引数が char *
だからです。

投稿日時 - 2009-03-17 05:51:42

お礼

ご回答ありがとうございます。

参考書のライブラリ関数一覧表に書いてある「FILE *fopen(const char *filename,const char *openmode);」等の記述の意味がが他の回答者様のご回答を含めて少し理解できました。

投稿日時 - 2009-03-17 13:21:47

あなたにオススメの質問