読者です 読者をやめる 読者になる 読者になる

やるしかなっちゃん

やるしかない!

この時代にK&Rを解く(2)

C言語 K&R

今日も解いていきます

演習1-8

空白, タブ, 改行を数える

  int c, nb = 0, nt = 0, nl = 0;
  while((c = getchar()) != EOF) {
    if (c == ' ') nb++;
    if (c == '\t') nt++;
    if (c == '\n') nl++;
  }

演習 1-9

2つ以上の空白を1つの空白に置き換える

  int c, nb = 0;
  while((c = getchar()) != EOF) {
    // 入力が空白の時は出力せずにカウント
    if (c == ' ') {
      nb++;
      continue;
    }

    // 入力が空白以外かつ前の文字に空白がない場合はそのまま出力
    if (nb == 0) {
      putchar(c);
      continue;
    }

    // 入力が空白以外かつ前の文字が1文字以上の空白場合は1つの空白に置き換えて出力
    putchar(' ');
    putchar(c);
    nb = 0;
  }

elseとifのネストが嫌いだからこう書いたけどわかりにくいかな?
普段ならネストしたifの部分を関数に切りだすけどこの段階ではまだ関数がでてきてないからこの書き方ということで

演習1-10

タブ, バックスペース, バックスラッシュをそれぞれ置き換える

  int c;
  while((c = getchar()) != EOF) {

    if (c == '\t') {
      putchar('\\');
      putchar('t');
      continue;
    }

    if (c == '\b') {
      putchar('\\');
      putchar('b');
      continue;
    }

    if (c == '\\') {
      putchar('\\');
      putchar('\\');
      continue;
    }

    putchar(c);
  }

ここも意地でもelseは使わない方向でいきましょう

ここらへんは文字定数の話っすね
'A'は内部表現のASCIIの値としては65だけど'A'と書いた方がわかりやすいという話と
’\n’は一つの文字で"\n"はたまたま一つの文字の文字列という辛みのある話が出てくる

演習1-11

単語カウントプログラムのテストの問題
まぁこれはパスで

演習1-12

入力された単語を1行ずつ出力

  int c;
  while((c = getchar()) != EOF) {

    if (c == ' ' || c == '\n' || c == '\t')
      putchar('\n');
    else
      putchar(c);

  }

演習1-13

入力された単語をヒストグラム表示する

  int c, cnt = 0;
  while((c = getchar()) != EOF) {

    if (c == ' ' || c == '\n' || c == '\t') {
      putchar(' ');
      for (int i = 0; i < cnt; i++)
        putchar('-');
      putchar('\n');
    } else {
      putchar(c);
      cnt++;
    }
  }

これでいいのか?現時点だとポインタとか出てきてないからコレで良いはずだ

演習1-14は同じ感じなのでパス
演習1-15も簡単なのでパス

演習1-16&1-17

どういうことだ? 問題の意味がよくわからない
とりあえず入力行から最長の行を出力するプログラムにエラー処理を加えろってことかな?
一旦パスで

演習1-19

文字列を逆に並べる関数の作成と入力行を逆転させる 逆に並べる関数は↓

void reverse(char s[]) {
  int len = 0;
  while(s[len] != '\0')
    len++;

  while(len >= 0)
    putchar(s[len--]);

  putchar('\n');

}

あとはgetlineはそのままにループの中で呼び出せばいいだけかな

  while ((len = gelLine(line, MAXLINE)) > 0) {
    reverse(line);
  }

演習1-18と1-20~24は本文にもあるように少し難しいのでまた後でやります
とりあえず読み進めたいので
また後でやると言ってやった試しがないけど後回しです
これで第1章は終わりなので次の記事へ続く...