C

プログラムから別のコマンドを実行する

C K&R

K&R本 7.8.4system関数を使えば、別のコマンドを実行できる。ためしに自分自身を呼び出すプログラムを書いてみる #include <stdio.h> #include <stdlib.h> int main (int argc,char *argv[]) { int i = 0; char command[100]; if ( argc < 2 ) exit(0); i = atoi(*++argv); if (</stdlib.h></stdio.h>…

入力ストリームへ一文字だけもどせるungetc関数

C K&R

K&R本 7.8.3ungetcを使うとgetchar等で取得した文字を一つだけ戻すことができます。ためしに二つ進んで一つ戻す処理を書いてみます。 #include <stdio.h> int main (void) { int c; int i = 0; while( (c = getchar()) != EOF ) { printf("%c",c); if ( (i = (i+1) % </stdio.h>…

文字列をコピーしてポインタを返す_strdup関数

C

値を単なるポインタで渡すと元の値を変更したときに、書き換わってしまうのでデータを保存しておくためには新しく割り当てたポインタを保持する必要がある。それをやってくれるのが_strdup関数 #include <stdio.h> #include <string.h> int main (void) { char *p; char str[] =</string.h></stdio.h>…

ファイルを比べて違ってる最初の行を表示

C K&R

K&R本 演習7-6 二つのファイルを比べて、違っている最初の行を印字するプログラムを書け。 #include <stdio.h> #include <string.h> #include <stdlib.h> char *getline (FILE *fp) { char str[100]; char *p = NULL; size_t len = 0; size_t lentotal = 0; while ( fgets(str,sizeof(str)</stdlib.h></string.h></stdio.h>…

fopenとfopen_s

C

VC2008の警告レベル最大だとfopenは警告が出る。fopen_sの方を使えと。ということでそれぞれの書き方を以下に示す。fopenの場合 FILE *fp; if ( (fp = fopen("foo.txt","r")) == NULL ) { // エラー処理 } fopen_sの場合 FILE *fp; errno_t error; if ( (err…

共用体に先頭要素が共通している構造体が含まれている場合

C K&R

K&R本 付録A8.3 共用体の利用を簡単にするのには、一つ特別な方法が用意されている。ある共用体に、先頭のメンバー並びが共通しているいくつかの構造体が含まれていて、しかも共用体がいまそれらの構造体の一つを保持しているときには、含まれている任意の構…

Cソースファイルからコメント行だけを削除する

C

難しそうですがとりあえずまずは仕様を満たすように我武者羅に実装してみます。 #include <stdio.h> /* コメントの除去プログラム // */ // /* int main (void) { int c; // 読み込む文字を格納 int linebegin = 0; // 始めの/フラグ用 int linecomment = 0; // 一行</stdio.h>…

単語数算出二分木の再帰版

C K&R

K&R本 6.5前回の記事で単語算出の処理を書きました。ですがK&Rのサンプルを見ていると二分木にデータを追加する処理に再帰を使っていました。ということで僕が作ったプログラムも再帰版に書き換えてみようかと思います。 #include <stdio.h> #include <string.h> #include <stdlib.h> #inc</stdlib.h></string.h></stdio.h>…

呼ばれたコマンド名によって処理分けする

C K&R

K&R本 演習7-1 argv[0]にあるどんな名前で呼ばれたかにより、大文字を小文字に、あるいは小文字を大文字に変換するプログラムを書け。 なんだか凄いトリッキーな処理ですね。実行したときの名前によって処理分けするなんて本来ならやっちゃいけなさそうな感…

ハッシュの実装(演習版)

C K&R

K&R本 演習6-5ハッシュの実装は一度やっていますが、K&R本に載っていたハッシュ実装(チェイン法)がなかなか良さそうだったので参考にしながら自分で再実装してみます。また、演習もやってみます。 lookupとinstallによって保守されるテーブルから、名前と定…

単語をグループごとにソート表示

C K&R

K&R本 演習6-2 Cのプログラムを読み込んで、最初の6文字が同じで、その後のどこかが異なっている変数名の各グループを、アルファベット順に印字するプログラムを書け。文字列やコメントの中の単語は数えるな。6はコマンドラインからセットできるパラメータに…

オプション付きソートプログラム

C K&R

K&R本 演習5-14、演習5-15 sortを変更して分類を逆方向にすることを指示する-rというフラグを取り扱えるようにせよ。-rは-nと同時に使えなければならない 分類において、大文字と小文字の区別をなくしてしまうためのオプション-fを加えよ。これによって、大…

整数定数とポインタへのキャストの挙動の意味

C

ようやくわかったかもしれない。 int main (void) { int *a = (int *)100; printf("%d \n",a); return 0; } $ main 100これが100と表示される意味。整数定数がどうとか考えるからややこしかったのかも。まず実体のある変数のポインタを表示させてみる。 int …

総称ポインタを使ったswap関数

C K&R

K&R本 5-11今までswap関数として以下のものを使っていました void swap (int *a, int *b) { int work = *a; *a = *b; *b = work; } しかし、これだと別の型の場合に同じような別の関数を作らなくてはいけないので面倒でした。これに対するK&R本に一つの解が…

ファイルの内容を行毎に配列して取得する

C

ファイルの内容を行毎に全部取得して二次元配列にするプログラムです。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define LINEMAX 100 #define LINESMAX 5000 int readlines (FILE *fh,char **lines,int size) { int linenum = 0; size_t len; size_t linelen = 0; ch</string.h></stdlib.h></stdio.h>…

単語数算出を二分木でやる

C K&R

K&R本 6.5単語数の算出処理に二分木の話が出てきたので復習がてら実装してみる。 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #define WORDMAX 100 struct NODE { char *word; int count; struct NODE *left; struct NODE *right; }; typedef struct NODE NODE</ctype.h></stdlib.h></string.h></stdio.h>…

int (*p[])()ってなんだ?

C K&R

K&R本 5.12複雑な宣言で出てきたこれ int (*p[])(); 所見なんだこりゃってなったけど少し考えてわかった。これはつまり関数ポインタの配列ってことね。関数プロトタイプを宣言してないので一瞬なんだろうと迷ってしまった。これは多分正しく書くなら int (*p…

クイックソート

http://www.geocities.jp/ky_webid/algorithm/020.htmlクイックソートの話です。もの凄いアルゴリズムですね。コレ。これを考え付いた人凄いです。普通こんなの思いつかないって。分割したデータは、中央に向かって探索、交換していき、再帰でそれを最後の要…

シーザ暗号

http://www.geocities.jp/ky_webid/algorithm/019.html凄く単調な暗号化ですね。文字をずらしたり置き換えたりするだけです。さっそく作ってみましょう。 #include <stdio.h> #include <string.h> int main (void) { char enc[100]; size_t i; int key = 3; puts("値を入力して</string.h></stdio.h>…

入力の最後のn行を表示するtailの実装

C K&R

K&R本 演習5-13 入力の最後のn行を印字するプログラムtailを書け。nの省略時仮定値は10であるが、これは省略可能な引数によって変更できるようにし、 tail -nで最後のn行を印字するようにせよ。 難しそうですね。 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #</ctype.h></stdlib.h></string.h></stdio.h>…

XOR暗号

http://www.geocities.jp/ky_webid/algorithm/018.html暗号というか単にXORが同じ演算を二回行うと元の値に戻ることを利用しただけのものですね。実際にプログラムを作って試してみましょう。 #include <stdio.h> #include <string.h> int main (void) { char enc[100]; size_t </string.h></stdio.h>…

タブをスペースに変換するdetab

C K&R

K&R本 演習5-11 プログラムentabとdetabを書き直して、タブストップの並びを引数として受け取るようにせよ。引数がないときは通常のタブ設定を使用せよ。 なんか問題文がややこしいな・・・。とりあえず今回はdetabだけやります。要はタブを4スペースに変換…

正しいポインタの操作

C K&R

K&R本 5.4箇条書きでまとめてみる 同じ型のポインタの代入 ポインタと整数との加算、減算 同じ配列のメンバーに対する二つのポインタの引算と比較 ゼロの代入やゼロとの比較 (void *)の代入 これらがすなわち正しいポインタの操作方法となる。これ以外の操作…

0とNULLの関係

C K&R

K&R本 5.4 Cでは、データを正しく指すポインタは0にならないことを保証しているから、0という戻り値は、異常事態の発生を知らせるのに使うことが出来る。ポインタと整数は相互交換可能ではない。ゼロは唯一の例外である。定数ゼロはポインタへ代入してよく、…

二分探索木

C

http://www.geocities.jp/ky_webid/algorithm/017.html前回の二分木構造の続きですね。 構造は二分木と同じだが、「左の子 ≤ 親 ≤ 右の子」という制約を持つ。左の子と右の子の両方に等号をつけているが、実際にはどちらかに統一しておく必要がある。平衡(…

ポインタ変数を引数にした間接参照がエラーになるケース

C

色々と本やWebでポインタ関連の資料を読んではいるのですが、良く分からない挙動がありました。 int main (void) { int *num; num = (int *)malloc(sizeof(int)); *num = 10; printf("%d",*num); return 0; } これはポインタ変数numにmallocでメモリを割り当…

二分木構造

http://www.geocities.jp/ky_webid/algorithm/016.htmlいわゆるツリー構造と呼ばれる物です。概念としては良く分かりました。が、実際にどう実装するかのイメージがつきません。ということで今回は先に解答例をじっくり読んでどういったものかを理解した上で…

itoa関数の再帰版の再実装、負の値に対応

C

itoa関数の再帰版の実装 - (void*)Pないとこれですが、負の値のことをすっかり忘れてました。ということで再実装しました。 #include <stdio.h> void myitoa (int n,char *s) { if(n){ int i = 0; int l = n; while(l/=10){ i++; } myitoa(n/10,s); if(n<0){ n *= -1;</stdio.h>…

オープンアドレス法によるハッシュ探索

http://www.geocities.jp/ky_webid/algorithm/015.html前回に引き続き、ハッシュ探索のお話です。今回はオープンアドレス法という処理方法になります。チェイン法と違って、同じ格納位置が生成されたときに元のハッシュテーブルを拡張し、データの重複を防ぎ…

参照渡しで値が全部同じになるミスをした

C

やってしまいました。単純化したコードですが、下記のようなことをしてしまいました。 int main (void) { int *num[10]; int i; for(i=0;i<10;++i){ int data = i; num[i] = &data; } for(i=0;i<10;++i){ printf("%d ",*num[i]); } return 0; } $ main 9 9 9…