新規ドキュメント


忘れていく脳のための備忘録
by w_l_s
プロフィールを見る
画像一覧

fgetsでgetsを再現する

gets。
バッファ・オーバーフローが起きるから使うなと言われる。
代わりにfgetsを使えと。
取得するサイズを決められるから、バッファ・オーバーフローが起きにくい。

でも動作がちょっと違う。
改行を含むのがfgets、含まないのがgets。
取得し切れなかった文字列がストリームに残るのがfgets、残らないのがgets。

株式会社きじねこさんのページを見て、簡単に置き換えられるものじゃないことを知った。
改行云々については前に悩まされたことがあったけど、ストリームに残ることについては
気にしたことなかったな。

きじねこさんのページには、getsをfgetsで再現するコードが載っている。
関数にすれば便利かも知れないので、まとめてみることにした。
初心者にはちょうどいい練習になりました。

/**********************************************************************/
/*
_getsヘッダ
*/

#ifndef _GETS
#define _GETS

#include <stdio.h>
#include <string.h>

extern char *_gets(char *s, size_t bytes);

#endif

/*
_getsソースコード
*/

#include "_gets.h"

#define ERROR 1
#define CORRECT 0

static int clear_buffer(void);

// getsをfgetsで再現
char *_gets(char *s, size_t bytes)
{
size_t length = 0;

fgets(s, bytes, stdin);
length = strlen(s);

if(s[length - 1] == '\n') {
s[length - 1] = '\0';
} else {
clear_buffer();
}
return s;
}

// バッファに残った文字列を消す
static int clear_buffer()
{
int letter;
int state = ERROR;

do {
letter = getchar();
if(letter == EOF) {
if(feof(stdin)) {
state = CORRECT;
break;
} else {
/*エラー処理を入れる*/
break;
}
}
} while(letter != '\n');

return state;
}

/**********************************************************************/

clear_buffer()のエラー処理は、単純にエラーコードを返すだけにした。
バッファに入りきらずにストリームに残った入力はすべて捨てている。
feof()なんて使ったことないな…。本によっては、この関数も絶対使うなと書いてあるけど、今回の例ではどうなんだろうか。
[PR]
by w_l_s | 2009-01-12 01:37 | c言語

PythonでQueueを作ってみた

今、アルゴリズムの勉強をしている。
学生のころ、ほとんどやってこなかったせいで、今かなり苦しんでる。
やっぱり時間があるときやっとくべきだったなぁ…。

そんなわけで本を買ってきて勉強してるんだけど、中身はCで書かれている。
最近はPythonにあまり触ってこなかったし、せっかくなのでPythonでも書いてみることにした。

ちなみに本は「定本 Cプログラマのためのアルゴリズムとデータ構造」(著者: 近藤 嘉雪)です。

そのまんま書き写しただけだとつまらないので、ちょっと関数を追加してたりする。

/*************************************************************************/

# -*- coding: utf-8 -*-

class Queue:
def __init__(self, MAXQUEUESIZE = 100):
self.queue = []
self.MAXQUEUESIZE = MAXQUEUESIZE

# queueが空?
def isEmpty(self):
return (self.total() == 0)

# queueがいっぱい?
def isFull(self):
return (self.total() == self.MAXQUEUESIZE)

# 残りのqueue数
def remain(self):
return self.MAXQUEUESIZE - self.total()

# 今のqueue数
def total(self):
return len(self.queue)

# queueの初期化
def init(self, MAXQUEUESIZE = 100):
self.__init__(MAXQUEUESIZE)

# queueの中身を取得
def peekAll(self):
return self.queue[:]

# 次のpush()の値を取得
def peek(self):
stat = None
if not self.isEmpty():
stat = self.queue[0]
return stat

# queueに値を入れる
def enqueue(self, element):
state = False
if not self.isFull():
self.queue.append(element)
state = True
return state

# queueから値を取り出す
def dequeue(self):
state = None
if not self.isEmpty():
state = self.queue.pop(0)
return state


/*************************************************************************/

最初は本のとおりにリングバッファを使おうとしていた。
でも途中でpop()は削除して以降の要素を詰めることに気づく。
本のままじゃうまくいかなくなるわけだ。
Cの配列とは違うなぁ。

いまさら変数名が気に入らなくなってきた。
pointerよりcurrentIndexとかのほうがいい気がする。

2009/1/9修正
pointerなんていらなかったので消去。
peek()は今のリストのコピーを取れるように変更。
ほかいくつか関数を追加

2009/1/11修正
enqueue, dequeueだよね
[PR]
by w_l_s | 2009-01-09 01:52 | Python

カテゴリ

全体
erlang
Python
c言語
作って遊ぼう
シェルスクリプト
OS
javascript
jQuery
反省
vim
未分類

フォロー中のブログ

メモ帳

最新のトラックバック

ライフログ

検索

タグ

ファン

ブログジャンル

画像一覧