printf(char*)と printf("%s", char*)の違い
2005-05-28-1 / カテゴリ: [c][perl][programming] / [permlink]

(いや、チョー基本的なことなんだろうケド)
char* の中身に % が含まれていたときに意図した動きをしない。

…あ、Perl もだ。printf なんてほとんど使わないから気づかんかった。

source のインストール
2005-05-27-3 / カテゴリ: [win][c][programming][cygwin] / [permlink]

インストーラのパッケージ選択画面で、Source を選択すると、/usr/src/package-version 以下にダウンロードされる。

お勉強用に、more(1) のソースを眺める。割と面白い。more.c しかないのが敷居が低くて良いかも。

Code Reading オープンソースから学ぶソフトウェア開発技法購入
2005-05-27-1 / カテゴリ: [programming][diary][] / [permlink]

昨日amazonで「プログラミング+設計」で検索してたときに偶然見付けた書籍。レビューを見る限り面白そうだったので買ってしまいました。

http://www.amazon.co.jp/exec/obidos/ASIN/4839912653/qid=1117 ...

他人のソースを読んで勉強…。言われてみれば当然なはずなのに、仕事で触れる(私の入社前に外注が書いた)ソースコード(Perl)があまりにも腐ってる(現在形)ので、今までそんな風に考えることができなかった…。
(上司が新人にそのコードのチェックをさせようとした時に「教育上よくない」と止めた程)
4ページ目より引用
低品質のコードは、次の点に着目すればすぐ見分けることができます。
  • コーディングスタイルに一貫性がない
  • 意味もなく複雑な構造や理解不能な構造が使われている
  • 明らかな論理ミスや手抜きがある
  • 移植性のない構造が多用されている
  • 保守されていない
おぉ……、全部当てはまってる…。
低品質なコードを見分けるスキルは見に付いてるってことか??

rewind と fseek(先頭)の違い
2005-05-26-2 / カテゴリ: [programming][c] / [permlink]

rewind では、FILEオブジェクトが保持している、ファイルopen後のエラーの状態(ferrorで取得できる状態->ファイルエラー指示子)をクリアした上で、先頭へ移動する。
先頭への移動そのものは、fseek(FILE*, 0L, SEEK_SET)と同じ。

独習C 読破
2005-05-26-1 / カテゴリ: [programming][c][diary][] / [permlink]

買って5日なのに…速いって。もったいない…。
ここ最近、通勤電車中でプログラミングの本ばっか読んでるなぁ。ポインタが理解できない理由も読破したのは電車の中だったし。
けど、「本を読む」量は多いけど、「コードを書く」量が少ないのは問題…。電車の中でコードを書くのは…できなくもないけど。座ってるから。どうしよっかな。

はやくハリーポッター文庫版の続き、出ないかなぁ

ファイルIOで1行ずつの処理は
2005-05-25-1 / カテゴリ: [programming][c] / [permlink]

fgets を使って、\nまで読んだのか、\0まで読んだのか、そうでないのかをチェック
  input_buf = (char *)malloc(sizeof(char) * cur_mem_size);
  if (input_buf == NULL) {
    perror("memory alocate error(input_buf)\n");
    exit(1);
  }

  // EOF まで読み込み
  while (!feof(fp)) {
    if (fgets(read_buf, INPUT_BUFFER, fp)) {
      strcat(input_buf, read_buf);

      if (!feof(fp) && input_buf[strlen(input_buf) - 1] != '\n') {
        // EOFでなく かつ 行の途中までしか読めなかった
        cur_mem_size += INPUT_BUFFER;
        printf("%d\n", cur_mem_size);
        input_buf = (char *)realloc(input_buf, sizeof(char) * cur_mem_size);
        if (input_buf == NULL) {
          perror("realloc error\n");
          exit(1);
        }
      }
      else {
        // EOFまたは行末まで読んだ
        printf("[%s]", input_buf);  // 行に対する処理
        input_buf[0] = '\0';
      }
    }
  }
cur_mem_size ずつファイルを読み込み、行末までよんでなかったら、バッファを realloc して更に読む、というやり方。こんなんで良いのだろうか。

独習C
2005-05-22-1 / カテゴリ: [c][programming][diary][] / [permlink]

日曜日だとゆーのに、深夜の電話番。電話がならなければただの夜更し(ぉぃ)。ぃゃ、別に起きてなくても良いんだけど、睡眠中に鳴るケータイに反応できる程、敏感ではないので、徹夜せざるを得ない身体がうらめしい。

ただ起きててもアホらしいので、独習CでC言語のお勉強。一気に200ページ程読んでしまった。
2年生子ちゃんが(押えるべきポイントを)見て分かりやすいように、(自分は理解できてる範囲も含めて)テストに出そうな項目(笑)にマーカーをどんどん引いて行く。

switch-case って、Perl 使いだったせいか、イマイチ使いどころがわからん。

独習C 購入
2005-05-21-1 / カテゴリ: [c][programming][] / [permlink]

1年前位に買った「猫でも分かるCプログラミング」だと、ちょっと情報が足りなくなってきたので、初・中級用のつもりで購入。割と読みやすい。
「C言語 ポインタが理解できない理由」を一通り読んでたおかげかな?

2年生の子にはちょっと敷居が高いかもしんないけど、猫わかに載ってない範囲で勉強するには良いかな?

ちょうど、すぐわかるPerl + 独習Perl と同じ体制になったな(笑

うるう年の判定
2005-05-20-2 / カテゴリ: [programming] / [permlink]

yが4の倍数なら「とりあえず」うるう年.
yが100の倍数なら4の倍数ではあるが平年.
yが400の倍数なら100の倍数ではあるがうるう年.
なんで
if ((y % 400 == 0) || ((y % 100 != 0) && (y % 4 == 0))) {
  うるう年
}
else {
  うるう年ではない
}
何を今更…

Zeller(ツェラー)の公式で曜日の判定
2005-05-20-1 / カテゴリ: [programming] / [permlink]

年 + 年/4 - 年/100 + 年/400 + (13*月+8)/5 + 日 を7で割ったときの
あまりが、0ならば日曜、1ならば月曜・・・6ならば土曜になります。
perl:localtime の第6引数を使う方法しかしらねー…

C言語課題
2005-05-19-1 / カテゴリ: [programming][diary] / [permlink]

一緒に仕事している、2年生のかけだしCプログラマ(♀)のための、プログラミング課題を考える。…なにも思いつかない。
Perlだとフィルタとか文字列処理用途で使用頻度も高くて、実用的な練習課題は作りやすい(というか、いくらでも作れる)けど、Cってどんな問題が適してるんだ?? それ以前に、Cの実績がゼロに近くて、問題作れないんですが ^-^;;;
結局、大学のときの演習課題(のtar.gz)を紐解いて、なんか良いのがないのか探してみる。なんか、.p なファイル(pascal)なんかあってなつかしい。というか、「なんの課題か」のコメントがない…。ちゃんと書け>x年前の自分

最低でも、「それが何のプログラムか」のコメントは必要だな>今の自分。
Referrer (Inside): [2005-11-24-1]

条件コンパイルを行う
2005-04-26-1 / カテゴリ: [programming][c] / [permlink]

予めデバッグフラグを #define で定義し、#ifdef 〜 #endif でブロック(?)を囲む
#define DEBUG 1
:
:
#ifdef DEBUG
 // ここにコード
 // DEBUGが定義されていればコンパイルされる。
#endif
:
:

malloc, realloc 基本
2005-04-23-1 / カテゴリ: [c][programming] / [permlink]

メモリを確保する
malloc
「プログラムが」使用出来るメモリ領域を確保する。
#include <stdio.h>
#include <stdlib.h>

int main() {
  char *str;
  char *str2 = "hogefoobar";

  str = (char *)malloc(strlen(str2) + 1);  /* str2の文字列長+1('\0'用)を確保し
                                              str にそのアドレスを保持 */
  if (str == NULL) {                       /* malloc の例外処理 */
    perror("cannot malloc\n");
    return -1;
  }

  strcpy(str, str2);                       /* 文字列のコピー */
  printf("str: [%s] %p\n", str, str);
  printf("str2: [%s] %p\n", str2, str2);

  free(str);                               /* メモリの開放 */

  return 0;
}
malloc 前にどこかのアドレスをさしていた場合は、その内容はなくなる…のかな

realloc
プログラムが使用出来る既存のメモリ領域を拡大する。既存のメモリ領域から連続した領域が空いていればそこが、空いていなければ、別の位置に領域確保&既存の位置のデータのコピーが行われる。多分
#include <stdio.h>
#include <stdlib.h>

int main() {
  char *str;
  char *str2 = "foobar";

  str = (char *)malloc(strlen(str2) + 1);  /* まずは str に領域確保 */
  if (str == NULL) {
    perror("cannot malloc\n");
    return -1;
  }
  strcpy(str, str2);
  printf("str: [%s] %p (size: %d)\n", str, str, strlen(str));

  str = (char *)realloc(str, strlen(str) + strlen(str2) + 1);
                                           /* str に更に str2 分を追加 */
  if (str == NULL) {
    perror("cannot realloc\n");
    return -1;
  }

  strcat(str, str2);                       /* str = str + str2 */
  printf("str: [%s] %p (size: %d)\n", str, str, strlen(str));

  free(str);

  return 0;
}
↑ realloc しないとコアダンプした(cygwin/gcc)

文字列を指定文字(デリミタ)で区切って、部分文字列のアドレスを得る
2005-04-22-1 / カテゴリ: [programming][c] / [permlink]

strtok(string, charset)
#include <string.h>

char string[] = "name, title, date, value\n";
char delim[] = ", \r\n";
char *token;

printf("[%s] (%p)\n", string, string);
printf("----\n");
token = strtok(string, delim);
while (token != NULL) {
  printf("[%s] (%p)\n", token, token);
  token = strtok(NULL, delim);
}
出力は
[name, title, date, value
] (0x22efa0)
----
[name] (0x22efa0)
[title] (0x22efa6)
[date] (0x22efad)
[value] (0x22efb3)
コールするたびに、デリミタで指定した文字セット以外が連続する文字列の末尾に '\0' をいれ、先頭のポインタを返す。(よって string は壊れる)
コール時に前回のポインタを記憶しているので、NULL になるまで複数回実行すれば、対象文字列をバラせる。

便利だけど、そろそろ Perl でやりたくなってきた。

標準ライブラリのヘッダファイルはどこに?
2005-04-21-5 / カテゴリ: [programming][c] / [permlink]

/usr/include
です。

文字列中から文字を探し、長さを得る
2005-04-21-4 / カテゴリ: [programming][c] / [permlink]

strspn(string, charset) / strcspn(string, charset) で
#include <string.h>

char string[] = "abcdefg";
char target[] = "def";
size_t len1, len2;

len1 = strspn(string, target);
len2 = strcspn(string, target);
strspn は、string の先頭から target の文字のみの部分文字列の長さ。
strcspn は、string の先頭から target 以外の文字のみの部分文字列の長さ。

Perl だと
my $string = "abcdefg";
my $target = "def";
my ($len1, $len2);

$len1 = length join "", ($string =~ /^([$target]*)/);
$len2 = length join "", ($string =~ /^([^$target]*)/);
ってコトかな? (うそっぽい)

文字列中から文字を探し、アドレスを得る
2005-04-21-3 / カテゴリ: [programming][c] / [permlink]

1文字探す場合は strchr(string, char), strrchr(string, char) で
#include <string.h>

char string[] = "abcdefg";
char target = 'c';
char *p;

p = strchr(string, target);
p には、string 中の最初の c の位置のアドレスが入る
strrchr は、最後のアドレスが入る(末尾から探す)
文字が見つからなかった場合は null になる。

複数文字のうちの1文字を探す(targetに複数文字を指定)場合は
char *strpbrk(string, charset)
char string[] = "sample string";
char target[] = "aiueo";
char *p;

p = strpbrk(string, target);
p には "sample string" の先頭から、"aiueo" の中のどれか1文字が最初に見つかる、2文字目の "a" の位置のアドレスが入る。
見つからなければ null

文字列長の取得
2005-04-21-2 / カテゴリ: [programming][c] / [permlink]

strlen(string) を使う
#include <stdio.h>
size_t strlen(const char *str);
文字列を指すポインタを渡すと、文字数(size_t型)を返す

const で定数宣言
2005-04-21-1 / カテゴリ: [programming][c] / [permlink]

変数を const で修飾すると、read-only な変数になる。
const int i = 123;
i = 456;
コンパイルすると
strlen.c: In function `main':
strlen.c:10: error: assignment of read-only variable `i'

Perl なら
use constant VALUE => 123;
だ。

厳密には「定数」というわけでなく、「読み出し専用」にするってこと。

文字列をフォーマット通りに分割する
2005-04-20-1 / カテゴリ: [programming][c] / [permlink]

sscanf(string, format, ...) を使う
#include <stdio.h>
int sscanf(const char *s, const char *format, ...);
           入力文字列     入力書式文字列      格納可変個引数
コード
char buf[] = "5/4/20";
int yy, mm, dd;

sscanf(buf, "%2d/%2d/%2d", &yy, &mm, &dd);
で、yy に 5, mm に 4, dd に 20 が入る
Referrer (Inside): [2006-03-13-3]
カテゴリ: programming / 前ページ 1 2 3 4 5 6 7 次ページ

最終更新時間: 2013-05-02 16:12