Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【PHP8.x】fscanf()関数の使い方

fscanf関数の使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

fscanf関数は、ファイルポインタから書式指定文字列に従ってデータを読み込む関数です。この関数は、指定されたファイルリソースから、特定のパターンに合致するテキストデータを抽出し、それを変数に格納する際に非常に役立ちます。例えば、ログファイルや設定ファイル、あるいはCSV形式のような構造化されたテキストファイルから、日付、数値、文字列といった特定の情報を効率的に読み取りたい場合に利用されます。

第一引数にはfopen関数などで開いたファイルポインタを、第二引数には読み込むデータの形式を指定する書式指定文字列(例:文字列は%s、整数は%dなど)を渡します。さらに、オプションとして、読み込んだ値を格納するための変数を参照渡しで追加の引数として指定することができます。これらの引数にデータが正常に割り当てられた場合、fscanf関数は割り当てられた変数の数を返します。もし、参照渡しで変数を指定しなかった場合は、パースされた値が配列として返されます。

ファイルポインタが不正であったり、読み込み中にエラーが発生したり、ファイルの終端に達してデータが読み込めなかった場合は、falseが返されます。この関数を使用することで、複雑なデータを持つテキストファイルから必要な情報を簡単に抽出・加工できるようになり、データ処理の柔軟性が高まります。

構文(syntax)

1<?php
2$handle = fopen("example.txt", "r");
3if ($handle) {
4    // example.txt から文字列、文字列、整数を読み込み、$data に配列として格納する
5    // "%s" は文字列、"%d" は整数を表すフォーマット指定子
6    $data = fscanf($handle, "%s %s %d");
7    fclose($handle);
8}
9?>

引数(parameters)

$stream, string $format, mixed ...$vars

  • resource|object $stream: 読み込み対象のストリームリソース(ファイルハンドルなど)
  • string $format: 読み込むデータのフォーマットを指定する文字列
  • mixed ...$vars: 読み込んだデータを格納するための変数を可変長引数として指定

戻り値(return)

array|int|false|null

fscanf関数は、指定されたファイルポインタからフォーマット文字列に従ってデータを読み込み、その結果を配列、または読み込んだフィールド数を整数で返します。読み込みに失敗した場合はfalseを返します。

サンプルコード

fscanf function: ファイルからCSV形式データを読み込む

1<?php
2
3/**
4 * ファイルからユーザーデータを読み込み、表示するサンプル関数。
5 * fscanf関数を使用して、指定されたフォーマットでファイルからデータを解析します。
6 * この例では、一時的なメモリファイルにサンプルデータを書き込み、そこから読み込みます。
7 */
8function readUserDataFromFile(): void
9{
10    // 一時的なメモリファイルを作成します。これにより、実際のファイルシステムに影響を与えずにテストできます。
11    // 'r+' モードは読み書きを可能にし、ファイルが存在しない場合は作成を試みます。
12    $tempFile = fopen('php://memory', 'r+');
13    if (!$tempFile) {
14        echo "エラー: 一時ファイルの作成に失敗しました。\n";
15        return;
16    }
17
18    // サンプルデータを一時ファイルに書き込みます。
19    // 各行は「名前,年齢,身長」のCSV形式です。
20    fwrite($tempFile, "Alice,30,165.5\n");
21    fwrite($tempFile, "Bob,25,178.0\n");
22    fwrite($tempFile, "Charlie,35,170.2\n");
23    fwrite($tempFile, "David,40,180.0\n");
24
25    // ファイルポインタをファイルの先頭に戻します。
26    // これにより、書き込んだデータがfscanfで読み込み可能になります。
27    fseek($tempFile, 0);
28
29    echo "ファイルからユーザーデータを読み込み、解析します。\n";
30    echo "---------------------------------------------------\n";
31
32    // fscanf用のフォーマット文字列を定義します。
33    // %[^,] : カンマ以外の文字を読み込みます (名前)
34    // %d    : 整数を読み込みます (年齢)
35    // %f    : 浮動小数点数を読み込みます (身長)
36    $format = "%[^,],%d,%f";
37
38    // ファイルの終わり(EOF)に達するか、fscanfがfalse(エラー)またはnull(EOF)を返すまでループします。
39    while (($userData = fscanf($tempFile, $format)) !== false && $userData !== null) {
40        // fscanfが成功した場合、読み込んだデータは配列として返されます。
41        // 配列の要素数が期待通りか確認します。
42        if (is_array($userData) && count($userData) === 3) {
43            echo "名前: " . $userData[0] . ", ";
44            echo "年齢: " . $userData[1] . ", ";
45            echo "身長: " . $userData[2] . "\n";
46        } else {
47            // フォーマットに一致しない行があった場合の処理
48            echo "警告: フォーマットに一致しないデータが見つかりました。\n";
49        }
50    }
51
52    // 開いたファイルを閉じます。
53    fclose($tempFile);
54
55    echo "---------------------------------------------------\n";
56    echo "データの読み込みが完了しました。\n";
57}
58
59// 関数を実行します。
60readUserDataFromFile();
61
62?>

PHPのfscanf関数は、ファイルから指定した書式(フォーマット)に従ってデータを読み込むための関数です。このサンプルコードでは、メモリ上に作成した一時ファイルから、CSV形式のユーザーデータを1行ずつ解析しています。

第1引数にはfopen関数などで開いたファイルポインタを渡し、どのファイルからデータを読み込むかを指定します。第2引数には、データの書式を定義する文字列を指定します。この例の"%[^,],%d,%f"という書式は、「カンマ以外の文字列」「整数」「浮動小数点数」がこの順でカンマ区切りになっているデータ行を読み込むことを意味します。

PHP 8.0以降、fscanf関数は読み込みに成功すると、取得した値を格納した配列を返します。サンプルでは、この配列を受け取って各データを表示しています。ファイルの終端に達するとnullを、エラーの場合はfalseを返すため、whileループと組み合わせることでファイルの最後まで安全にデータを読み進めることができます。このように、fscanf関数は特定の構造を持つテキストファイルからデータを効率的に抽出する際に役立ちます。

fscanf関数は、第二引数で指定するフォーマット文字列が非常に重要です。特に%[^,]は「カンマ以外の文字」を読み込む特殊な指定で、データの形式と完全に一致していないと正しく解析できません。関数の戻り値は、成功時に配列、入力が尽きた場合にnull、エラー時にfalseを返します。そのため、ループを安全に実行するには、サンプルコードのようにnullfalseの両方を厳密にチェックする必要があります。また、ファイルに書き込み後、読み込みを開始する前にはfseekでファイルポインタを先頭に戻す操作が不可欠です。最後に、fopenで開いたリソースは、処理完了後に必ずfcloseで閉じてください。

PHP fscanfでファイルからフォーマットデータ読み込み

1<?php
2
3/**
4 * PHPのfscanf関数を使用して、ファイルからフォーマットされたデータを読み込むサンプルです。
5 * システムエンジニアを目指す初心者向けに、基本的なファイル入出力のプロセスを示します。
6 */
7
8// 1. サンプルデータファイルを作成します。
9// このファイルは、fscanf関数が読み込むデータ源となります。
10$filename = 'data.txt';
11$fileContent = "Alice 30\nBob 25\nCharlie 35\n"; // 名前と年齢の形式
12file_put_contents($filename, $fileContent);
13
14echo "--- ファイル '{$filename}' からデータを読み込みます ---\n";
15
16// 2. 作成したファイルを読み込みモード ('r') で開きます。
17// fopen関数は、成功するとファイルリソース(ハンドル)を、失敗すると false を返します。
18$fileHandle = fopen($filename, 'r');
19
20// 3. ファイルが正常に開かれたかを確認します。
21if ($fileHandle === false) {
22    echo "エラー: ファイル '{$filename}' を開けませんでした。\n";
23    exit(1); // スクリプトを終了します。
24}
25
26// 4. ファイルの終端までループし、fscanf関数でデータを読み込みます。
27// fscanf(ストリーム, フォーマット文字列, ...変数)
28// - $fileHandle: 開かれたファイルのリソース。
29// - "%s %d": フォーマット文字列。
30//   - %s: 文字列を読み込みます (名前)。
31//   - %d: 10進数整数を読み込みます (年齢)。
32// fscanfは、指定されたフォーマットでデータを読み込み、成功すると配列を返します。
33// 読み込むデータがもうない場合やエラーの場合は、false または null を返します (PHP 8以降)。
34while (true) {
35    $data = fscanf($fileHandle, "%s %d");
36
37    // 読み込むデータがなくなったか、エラーが発生した場合
38    if ($data === false || $data === null) {
39        break; // ループを終了します。
40    }
41
42    // 読み込んだデータは配列として取得されます。
43    // 配列の0番目に名前、1番目に年齢が格納されます。
44    $name = $data[0] ?? 'N/A'; // 名前が取得できなかった場合のデフォルト値
45    $age = $data[1] ?? 'N/A';  // 年齢が取得できなかった場合のデフォルト値
46
47    echo "名前: {$name}, 年齢: {$age}\n";
48}
49
50// 5. ファイル操作が完了したら、ファイルを閉じます。
51// fclose関数は、開いたファイルリソースを解放します。
52fclose($fileHandle);
53
54echo "--- データの読み込みが完了しました ---\n";
55
56// 6. サンプルとして作成した一時ファイルを削除します。
57// unlink関数はファイルを削除します。
58unlink($filename);
59
60?>

PHPのfscanf関数は、ファイルから特定のフォーマットに従ってデータを読み込む際に使用されます。このサンプルコードでは、まず一時的なデータファイルを作成し、そのファイルから名前(文字列)と年齢(整数)の形式でデータを読み込む一連の流れを示しています。

fscanf関数は、fopen関数で開かれたファイルリソース($stream)と、読み込むデータの形式を定義するフォーマット文字列(string $format)を必須の引数として受け取ります。例えば、"%s %d"というフォーマットは、「文字列の後にスペース、そして整数」という形式のデータを読み込むことを意味します。ここで%sは文字列を、%dは10進数整数を読み込む指示です。

関数が成功すると、読み込んだデータが格納された配列が戻り値として返されます。この配列の要素は、フォーマット文字列で指定した順序でデータを含みます。ファイル終端に到達した場合や読み込みエラーが発生した場合は、falseまたはnullが返されるため、これを利用してデータ読み込みの終了を判断します。

本サンプルでは、ファイルを開き、whileループ内でfscanfを繰り返し呼び出して各行のデータを構造的に読み込み、処理後にファイルを閉じ、作成した一時ファイルを削除するまでの一連のファイル入出力処理を学ぶことができます。

PHPのfscanf関数を利用する際は、まずfopenでファイルを開く際にエラーがないか(falseが返されていないか)を必ず確認し、処理後はfcloseでファイルを閉じ、リソースを解放してください。ファイル操作の基本であり、エラー時のスクリプト異常終了やリソースリークを防ぐ重要な手順です。fscanfの第2引数であるフォーマット文字列は、読み込むデータ形式(%sは文字列、%dは整数など)と正確に一致させる必要があります。関数は読み込み成功で配列を返しますが、ファイルの終端やエラー時にはfalsenullを返すため、これらの戻り値を適切にチェックし、ループ終了やエラー処理を行うことが重要です。実運用では、ファイルオープン失敗時などに備え、適切なエラーハンドリングと、一時ファイルの確実な削除によるリソース管理を徹底してください。

PHP fscanfで標準入力を読み取る

1<?php
2
3declare(strict_types=1);
4
5/**
6 * 標準入力(STDIN)から fscanf を使用してデータを読み取るサンプルです。
7 *
8 * このスクリプトをコマンドラインで実行し、
9 * 名前と年齢をスペースで区切って入力してからEnterキーを押してください。
10 * (例: Taro 25)
11 */
12function readFormattedInputFromStdin(): void
13{
14    // ユーザーに入力を促すメッセージを表示します。
15    echo "名前と年齢をスペース区切りで入力してください (例: Taro 25): ";
16
17    // 変数を初期化します。
18    $name = null;
19    $age = null;
20
21    // 標準入力ストリーム(STDIN)からフォーマット指定でデータを読み取ります。
22    // "%s %d" は「文字列、スペース、整数」という形式を示します。
23    // 読み取られた値は、第3引数以降で渡した変数に格納されます。
24    $assignedCount = fscanf(STDIN, "%s %d", $name, $age);
25
26    // fscanfは正常に読み込み、変数に代入できた項目の数を返します。
27    // 今回は名前と年齢の2項目が読み込めることを期待しています。
28    if ($assignedCount === 2) {
29        // 読み取ったデータを使用してメッセージを出力します。
30        printf("こんにちは、%sさん! あなたは%d歳ですね。\n", $name, $age);
31    } else {
32        // 入力が期待したフォーマットと異なっていた場合のエラーメッセージです。
33        fwrite(STDERR, "エラー: 入力形式が正しくありません。\n");
34    }
35}
36
37// 関数を実行します。
38readFormattedInputFromStdin();

fscanf関数は、ファイルポインタや標準入力などのストリームから、指定した書式(フォーマット)に従ってデータを読み取るための関数です。このサンプルコードは、コマンドラインでユーザーがキーボードから入力した名前と年齢をfscanf関数を使って受け取る処理を示しています。

fscanf関数の第1引数には、データの読み取り元となるストリームを指定します。ここではSTDINが指定されており、これは「標準入力」、つまりキーボードからの入力を意味します。

第2引数の"%s %d"は、入力データの書式を指定する文字列です。%sは任意の文字列、%dは10進数の整数を表しており、「文字列、スペース、整数」という形式のデータを期待していることを示します。

第3引数以降には、読み取ったデータを格納するための変数を指定します。サンプルでは、書式%sで読み取った文字列が変数$nameに、%dで読み取った整数が変数$ageにそれぞれ代入されます。

この関数の戻り値は、書式に従って正常に読み込み、変数に代入できた項目の数です。サンプルでは、名前と年齢の2項目が正しく代入されることを期待しているため、戻り値が2であるかどうかを確認し、入力が正しい形式であったかを判断しています。もし入力が期待した形式でなかった場合、戻り値は2未満となり、エラーメッセージが表示されます。

fscanf関数を使う際の注意点を説明します。この関数は第3引数以降に渡した変数へ直接値を代入するため、事前に変数を定義しておく必要があります。ユーザーの入力は常に正しいとは限らないため、関数の戻り値を確認することが非常に重要です。戻り値は正常に代入できた項目の数なので、この値が期待通りかチェックすることで、不正な形式の入力によるエラーを防げます。また、フォーマット指定子"%s"は空白文字までの文字列しか読み込みません。そのため、名前にスペースが含まれる場合(例: "Taro Yamada")は期待通りに動作しない点にも注意してください。このような場合は一行ずつ読み込むfgetsなどの利用を検討すると良いでしょう。

関連コンテンツ

関連プログラミング言語