質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

1回答

2599閲覧

バッファリングする fgetc () を作成する問題

nazonoP

総合スコア7

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2016/11/03 08:36

###前提・実現したいこと

C言語で open(2), close(2), read(2) 等を用いて(標準入出力ライブラリ関数を使わず)ファイルから1文字ずつ読み出すプログラムを作ろうとしています。

###発生している問題・エラーメッセージ

abcという中身のファイルを読み出すと65、66、67、aと出てしまいます。 myfgetcかmyfopenが怪しいと思うのですが、どこをどう直して良いかわかりません。

###該当のソースコード

C言語

1#include <stdio.h> 2#include <unistd.h> 3#include <fcntl.h> 4 5// バッファーサイズ 6// 動作確認しやすくするため小さめの値とする 7enum { 8 BUFFERSIZE = 5 9}; 10 11typedef struct myfile { 12 int fd; 13 int count; 14 int pointer; 15 unsigned char buffer[BUFFERSIZE]; 16} MYFILE; 17 18// 簡単化のため同時にオープンできるファイルは1個だけ 19static MYFILE myfile; 20 21void print_myfile (MYFILE *fp) { 22 int i; 23 if (fp) { 24 fprintf (stderr, "[MYFILE] fd:%d c:%d p:%d ", 25 fp->fd, fp->count, fp->pointer); 26 for (i = 0; i < BUFFERSIZE; i ++) { 27 fprintf (stderr, " %02x", fp->buffer[i]); 28 } 29 fputc ('\n', stderr); 30 } 31} 32 33MYFILE *myfopen (char *filename) { 34 // 35 // この部分を作成する 36 // 37 // 与えられたファイル名のファイルを開く 38 int fp = open(filename, O_RDWR); 39 myfile.fd = fp; 40 myfile.count = 0; 41 myfile.pointer = fp; 42 // http://www5c.biglobe.ne.jp/~ecb/c/13_09.html 43 // fdopen(fp, r+) 44 return &myfile; 45} 46 47int myfclose (MYFILE *fp) { 48 // 49 // この部分を作成する 50 // 51 close (fp->fd); 52 return 0; 53} 54 55int myfgetc (MYFILE *fp) { 56 // 57 // この部分を作成する 58 // 1文字読み込み、その文字を返します 59 60 int readCount = fp->count; 61 fp->count += 1; 62 if (fp->count < BUFFERSIZE) { 63 read(fp->fd, fp->buffer, 1); 64 return (int)*(fp->buffer + readCount); 65 } else { 66 return EOF; 67 } 68} 69 70int main (int argc, char *argv[]) { 71 char *filename = "abc.txt"; 72 MYFILE *fp; 73 int c; 74 if (argc == 2) filename = argv[1]; 75 fp = myfopen (filename); 76 if (fp) { 77 print_myfile (fp); 78 while ((c = myfgetc (fp)) != EOF) { 79 printf ("#[%02x]%c#\n", c, c); 80 print_myfile (fp); 81 } 82 print_myfile (fp); 83 myfclose (fp); 84 return 0; 85 } else { 86 return 1; 87 } 88} 89

###試したこと
課題に対してアプローチしたことを記載してください
// この部分を作成する、と書かれた関数は自作して何とか動作までは漕ぎ着けました。
ただ、openやread、バッファリングなどの仕組みについて理解が足りないようで、正常に開けていない或いは正常に読み込めていません。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

abc.txtというファイルを作って中身にabcと入力、
質問分に記載されているソースをそのままコピペしてmacのgccでコンパイル&実行

結果

[MYFILE] fd:3 c:0 p:3 00 00 00 00 00 #[61]a# [MYFILE] fd:3 c:1 p:3 61 00 00 00 00 #[00]# [MYFILE] fd:3 c:2 p:3 62 00 00 00 00 #[00]# [MYFILE] fd:3 c:3 p:3 63 00 00 00 00 #[00]# [MYFILE] fd:3 c:4 p:3 0a 00 00 00 00 [MYFILE] fd:3 c:5 p:3 0a 00 00 00 00

結果の右側の値をみると、61,62,63,0aとfp->buffer[0]にはabc[LF]と読み込まれているようですが?
また本来myfgetcで返すはずの文字が表記ではおかしいので
myfgetc関数のファイル読み込みのバッファの位置を少し変更

read(fp->fd, &fp->buffer[fp->count], 1);

で実行結果は

[MYFILE] fd:3 c:0 p:3 00 00 00 00 00 #[00]# [MYFILE] fd:3 c:1 p:3 00 61 00 00 00 #[61]a# [MYFILE] fd:3 c:2 p:3 00 61 62 00 00 #[62]b# [MYFILE] fd:3 c:3 p:3 00 61 62 63 00 #[63]c# [MYFILE] fd:3 c:4 p:3 00 61 62 63 0a [MYFILE] fd:3 c:5 p:3 00 61 62 63 0a

なりました。
質問分の65、66、67は再現しないのですが。。。

投稿2016/11/03 09:06

hiim

総合スコア1689

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nazonoP

2016/11/03 09:14

すみません、値が間違っていたようです これで合っていると思います
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問