fgets関数に関して
fgets関数に関して
はじめましてskyです。fgets関数を用いてpgmファイルの始めの2行(添付ファイルの場合, P2, 304,322)をそれぞれ、変数header, width, heightに格納するプログラムを考えているのですがfgets関数は一行ずつ読み込む関数ですよね?304,322は同じ行にあるのにこれを別々の変数に格納する方法がよくわかりません。
サイトや参考書を見て以下までできました。これからどうしたら良いか行き詰ってます。
OS:UNIX,コンパイル:gcc
#include<stdio.h>
#define BUFFER_SIZE 200
void main(){
char buffer[BUFFER_SIZE];
FILE *fp;
fp = fopen("test_barbarar.pgm", "r");
// ファイルオープン失敗か?
if ( !fp ){
printf("ファイルオープンエラー\n");
return;
}
// 1行ずつ読み込んで表示する
while( fgets(buffer, BUFFER_SIZE, fp) ){
printf("%s", buffer);
}
// ファイルクローズ
fclose(fp);
}
添付ファイルtest_barbarar.のサイズが大きくて貼れなかったので、初めの4行は以下のようになってます。
P2
304 322
255
161 162 162 161 161 162 160 160 157 158 165 163 161 164 163 165 164 162
長々と失礼しました。どうかよろしくお願いします。
サイトや参考書を見て以下までできました。これからどうしたら良いか行き詰ってます。
OS:UNIX,コンパイル:gcc
#include<stdio.h>
#define BUFFER_SIZE 200
void main(){
char buffer[BUFFER_SIZE];
FILE *fp;
fp = fopen("test_barbarar.pgm", "r");
// ファイルオープン失敗か?
if ( !fp ){
printf("ファイルオープンエラー\n");
return;
}
// 1行ずつ読み込んで表示する
while( fgets(buffer, BUFFER_SIZE, fp) ){
printf("%s", buffer);
}
// ファイルクローズ
fclose(fp);
}
添付ファイルtest_barbarar.のサイズが大きくて貼れなかったので、初めの4行は以下のようになってます。
P2
304 322
255
161 162 162 161 161 162 160 160 157 158 165 163 161 164 163 165 164 162
長々と失礼しました。どうかよろしくお願いします。
Re:fgets関数に関して
#include<stdio.h> #define BUFFER_SIZE 200 #define HEADER_SIZE 8 int main(void) { char buffer[BUFFER_SIZE] = {0, }; char header[HEADER_SIZE] = {0, }; int width = 0, height = 0; FILE *fp; // ファイルオープン fp = fopen("test_barbarar.pgm", "r"); // ファイルオープン失敗か? if (fp == NULL) { printf("ファイルオープンエラー\n"); return; } // header, width, heightを読み込む fscanf(fp, "%s", header); fscanf(fp, "%d%d", &width, &height); // header, width, heightを表示する printf("header = %s\n", header); printf("width = %d\n", width); printf("height = %d\n", height); // ファイルクローズ fclose(fp); return 0; }
Re:fgets関数に関して
おっと、ファイルオープンに失敗した際の戻り値を設定するのを忘れておりましたm(__)m
#include<stdio.h> #define BUFFER_SIZE 200 #define HEADER_SIZE 8 int main(void) { char buffer[BUFFER_SIZE] = {0, }; char header[HEADER_SIZE] = {0, }; int width = 0, height = 0; FILE *fp; // ファイルオープン fp = fopen("test_barbarar.pgm", "r"); // ファイルオープン失敗か? if (fp == NULL) { printf("ファイルオープンエラー\n"); return -1; } // header, width, heightを読み込む fscanf(fp, "%s", header); fscanf(fp, "%d%d", &width, &height); // header, width, heightを表示する printf("header = %s\n", header); printf("width = %d\n", width); printf("height = %d\n", height); // ファイルクローズ fclose(fp); return 0; }
Re:fgets関数に関して
バグさん、丁寧にご回答まことにありがとうございます。
一応課題でfgetsを使うことを指定されています。fgetsは一行ずつファイルから読み込む関数と解釈しているのですが添付ファイルの2行目が304 322となってるので これをそれぞれ違う変数に格納するやり方を教えて頂ければ幸いです。私の記述の仕方が悪かったです。本当にすみません。
一応課題でfgetsを使うことを指定されています。fgetsは一行ずつファイルから読み込む関数と解釈しているのですが添付ファイルの2行目が304 322となってるので これをそれぞれ違う変数に格納するやり方を教えて頂ければ幸いです。私の記述の仕方が悪かったです。本当にすみません。
Re:fgets関数に関して
ちがう変数とのことですが、どんな変数でしょうか?
例えば、文字列として扱えばよいのであれば、sscanfよりstrtokの方がむしろ楽です。
整数値として扱うのであれば、strtolやstrtoulを使うべきです(もちろん、strtollやstrtoimaxが使えるなら、それでもOK)。
例えば、文字列として扱えばよいのであれば、sscanfよりstrtokの方がむしろ楽です。
整数値として扱うのであれば、strtolやstrtoulを使うべきです(もちろん、strtollやstrtoimaxが使えるなら、それでもOK)。
Re:fgets関数に関して
nonさん>>
ありがとうございます。fgets関数で2行分だけ読み込みsscanfを用いるということでしょうか。
2行分だけ読み込むことは可能なんですかね?
たかぎさん>>
お手数おかけします。返答ありがとうございます。
304と322という整数をそれぞれ widthとheightに格納するということです。
問題がfgets関数を用いてpgmファイルの始めの2行(添付ファイルの場合, P2, 304,322)をそれぞれ、変数header, width, heightに格納するプログラムを作成せよ。
ってなっててstrtolやstrtoulはまだ習ってないです。ホントにすみません。
ありがとうございます。fgets関数で2行分だけ読み込みsscanfを用いるということでしょうか。
2行分だけ読み込むことは可能なんですかね?
たかぎさん>>
お手数おかけします。返答ありがとうございます。
304と322という整数をそれぞれ widthとheightに格納するということです。
問題がfgets関数を用いてpgmファイルの始めの2行(添付ファイルの場合, P2, 304,322)をそれぞれ、変数header, width, heightに格納するプログラムを作成せよ。
ってなっててstrtolやstrtoulはまだ習ってないです。ホントにすみません。

Re:fgets関数に関して
それならば、nonさんの言われるように、fgets関数でいったん文字列としてファイルの内容を取得しておいて、sscanf関数を使用して、文字列→数値へ変換してやればいいと思いますよ。
これらの手間を一度に行えるのがfscanf関数なので、結局同じことではあるのですが…(^_^;)
sscanf関数の使い方が分からなければ、下記URLを参照ください。
http://www.bohyoh.com/CandCPP/C/Library/sscanf.html
これらの手間を一度に行えるのがfscanf関数なので、結局同じことではあるのですが…(^_^;)
sscanf関数の使い方が分からなければ、下記URLを参照ください。
http://www.bohyoh.com/CandCPP/C/Library/sscanf.html
Re:fgets関数に関して
バグさん本当にありがとございます。
プログラム苦手なので考えるのに時間がかかりますけどやってみます。
また分からないことがあればよろしくお願いします。
プログラム苦手なので考えるのに時間がかかりますけどやってみます。
また分からないことがあればよろしくお願いします。
Re:fgets関数に関して
トークン分割用:strtok 数値変換用:strtolやatoi(はあまりよろしくないけど) はつかってもよい? そもそも >304と322という整数をそれぞれ widthとheightに格納するということです。 widthとheightは何型? char型の配列であれば、strtolとかは不要。

Re:fgets関数に関して
>widthとheightは何型か特に指定されていない
のであれば、char型配列にしてしまえばw
2行目は先頭から空白の手前までをwidthに、空白の後ろから改行もしくは終端までをheightに
入れるような処理を書けばよいですね。
未検証だけどこんな感じ?

のであれば、char型配列にしてしまえばw
2行目は先頭から空白の手前までをwidthに、空白の後ろから改行もしくは終端までをheightに
入れるような処理を書けばよいですね。
未検証だけどこんな感じ?
char width[8] = ""; // サイズは適当 char height[8] = ""; char* p; // 検索用 int i; // 格納用 i = 0; for (p = buffer; *p != ' ' && *p != '\0'; ++p, ++i) { width = *p; } width = '\0'; if (*p != '\0') { ++p; i = 0; for (; *p != '\0' && *p != '\n'; ++p, ++i) { height = *p; } height = '\0'; }

Re:fgets関数に関して
Blueさん>>
ありがとうございます。すこしお尋ねしたいのですが…
width = *p;
}
width = '\0';←これはどういう意味ですかね?
ありがとうございます。すこしお尋ねしたいのですが…
width = *p;
}
width = '\0';←これはどういう意味ですかね?
Re:fgets関数に関して
Blueさん>>
参考にさせてもらいました。以下のようにしたのですが…
#include <stdio.h>
#define BUFFER_SIZE 200
void main(){
char buffer[BUFFER_SIZE];
char header[10];
char width[10]="",height[10]="",space[10];//格納
char *p;
int i;
FILE *fp ;
FILE *new;
fp = fopen("test_barbarar.pgm", "r");
// ファイルオープン失敗か?
if ( !fp ){
printf("ファイルオープンエラー\n");
return;
}
fgets(header, BUFFER_SIZE, fp);
printf("header=%s", header);
fgets(buffer, BUFFER_SIZE, fp);
i = 0;
for (p = buffer; *p != ' ' && *p != '\0'; ++p, ++i) {
width = *p;
}
width = '\0';
if (*p != '\0')
{
++p;
i = 0;
for (; *p != '\0' && *p != '\n'; ++p, ++i) {
height = *p;
}
height = '\0';
}
printf("width=%s", width);
printf("height=%s", header);
// ファイルクローズ
fclose(fp);
}
実行結果
header=p2
width=(null)header=(null)
となってしまいます。何がいけなかったのでしょうか?何度もすみません。
参考にさせてもらいました。以下のようにしたのですが…
#include <stdio.h>
#define BUFFER_SIZE 200
void main(){
char buffer[BUFFER_SIZE];
char header[10];
char width[10]="",height[10]="",space[10];//格納
char *p;
int i;
FILE *fp ;
FILE *new;
fp = fopen("test_barbarar.pgm", "r");
// ファイルオープン失敗か?
if ( !fp ){
printf("ファイルオープンエラー\n");
return;
}
fgets(header, BUFFER_SIZE, fp);
printf("header=%s", header);
fgets(buffer, BUFFER_SIZE, fp);
i = 0;
for (p = buffer; *p != ' ' && *p != '\0'; ++p, ++i) {
width = *p;
}
width = '\0';
if (*p != '\0')
{
++p;
i = 0;
for (; *p != '\0' && *p != '\n'; ++p, ++i) {
height = *p;
}
height = '\0';
}
printf("width=%s", width);
printf("height=%s", header);
// ファイルクローズ
fclose(fp);
}
実行結果
header=p2
width=(null)header=(null)
となってしまいます。何がいけなかったのでしょうか?何度もすみません。
Re:fgets関数に関して
>fgets(header, BUFFER_SIZE, fp);
header[/url]のサイズは10なのに、関係のないBUFFER_SIZEを渡すのはどうかと。
10 または、sizeof(header) / sizeof(header[0]) にするほうが良いと思います。
>printf("width=%s", width);
>printf("height=%s", header);
printf 関数に渡すべきは文字列の先頭アドレスなのに、文字を渡しています。
また、このときのiは何を意図しているのでしょう?
header[/url]のサイズは10なのに、関係のないBUFFER_SIZEを渡すのはどうかと。
10 または、sizeof(header) / sizeof(header[0]) にするほうが良いと思います。
>printf("width=%s", width);
>printf("height=%s", header);
printf 関数に渡すべきは文字列の先頭アドレスなのに、文字を渡しています。
また、このときのiは何を意図しているのでしょう?