topic: file-io (read / write / CSV / paths / upload概念) / ch02 — ファイルを読む / 演習 02

📝 ドリル 02 — 1 行ずつ読んで行番号を付ける

問題

__DIR__ . '/tests/data/poem.txt'1 行ずつ 読み、各行の先頭に "N: " (N は 1 始まりの行番号) を付けて出力する PHP を書いてください。

データファイル (tests/data/poem.txt):

春はあけぼの
やうやう白くなりゆく山ぎは
すこしあかりて
紫だちたる雲のほそくたなびきたる

期待される出力:

1: 春はあけぼの
2: やうやう白くなりゆく山ぎは
3: すこしあかりて
4: 紫だちたる雲のほそくたなびきたる

採点

php scripts/grade.php topics/14-file-io/ch02-read-file/drill/02-read-line-by-line/

ヒント

$fp = fopen(__DIR__ . '/tests/data/poem.txt', 'r');
$n = 1;
while (($line = fgets($fp)) !== false) {
    echo $n . ': ' . rtrim($line, "\r\n") . "\n";
    $n++;
}
fclose($fp);
▶ 3v4l で実行
  • fopen($path, 'r')読み込みモード で開く
  • fgets($fp)1 行返す (EOF で false)
  • fgets の戻り値には 末尾改行 が含まれるので rtrim($line, "\r\n") で剥がし、自分で "\n" を付け直す
  • 開いたら必ず fclose

つまづいたら

  • 最後に空行が 1 つ余分に出る → fgets の戻り値末尾の改行を剥がさず、さらに "\n" を付け足している
  • 1 行ズレる / 行が 1 個多い → while (!feof($fp)) で書くと末尾で 1 回余分に回ることがある。while (($line = fgets($fp)) !== false) の形で書く

テストケース

期待される出力

1: 春はあけぼの
2: やうやう白くなりゆく山ぎは
3: すこしあかりて
4: 紫だちたる雲のほそくたなびきたる

📄 starter.php(雛形)

このコードから書き始めてください。

<?php

// TODO: tests/data/poem.txt のパスを __DIR__ ベースで組み立てる
// $path = __DIR__ . '/...';

// TODO: fopen でファイルを 'r' (読み込み) モードで開く

// TODO: while (($line = fgets($fp)) !== false) で 1 行ずつ読み、
//       "N: 本文" の形式で出力する (N は 1 始まりの行番号)
//       fgets は末尾改行を含むので rtrim($line, "\r\n") で剥がす

// TODO: 最後に fclose で閉じる
✅ 解答例を見る(自分で解いてから)
<?php

// 1 行ずつ読んで "N: 本文" の形で出力する
$path = __DIR__ . '/tests/data/poem.txt';
$fp = fopen($path, 'r');
if ($fp === false) {
    fwrite(STDERR, "open failed: $path\n");
    exit(1);
}

$lineNo = 1;
while (($line = fgets($fp)) !== false) {
    // fgets は末尾改行を含むので rtrim で剥がす
    echo $lineNo . ': ' . rtrim($line, "\r\n") . "\n";
    $lineNo++;
}

fclose($fp);