給 C/C++ 程式設計師的說明:
fscanf() 的運作方式與 C/C++ 不同,因為 PHP 的 fscanf() 會隱式地將檔案指標移至下一行。
(PHP 4 >= 4.0.1, PHP 5, PHP 7, PHP 8)
fscanf — 根據格式從檔案解析輸入
函式 fscanf() 類似於 sscanf(),但它會從與 stream
關聯的檔案取得輸入,並根據指定的 format
來解讀輸入。
格式字串中的任何空白字元會比對輸入資料流中的任何空白字元。這表示即使格式字串中的定位字元 (\t
) 也能比對輸入資料流中的單個空格字元。
每次呼叫 fscanf() 會從檔案中讀取一行。
如果只傳遞兩個參數給此函式,則剖析的值將以陣列形式返回。否則,如果傳遞了選擇性參數,則函式將返回賦值的數量。選擇性參數必須以傳址方式傳遞。
如果在 format
中預期的子字串數量多於 string
中可用的子字串數量,則會返回 null
。其他錯誤情況下,將返回 false
。
範例 #1 fscanf() 範例
<?php
$handle = fopen("users.txt", "r");
while ($userinfo = fscanf($handle, "%s\t%s\t%s\n")) {
list ($name, $profession, $countrycode) = $userinfo;
//... 處理這些值
}
fclose($handle);
?>
範例 #2 users.txt 的內容
javier argonaut pe hiroshi sculptor jp robert slacker us luigi florist it
給 C/C++ 程式設計師的說明:
fscanf() 的運作方式與 C/C++ 不同,因為 PHP 的 fscanf() 會隱式地將檔案指標移至下一行。
在 fscanf 文件中明確說明以下內容會很有幫助:
呼叫一次此函式會讀取完整的一行,
而不僅僅是格式中定義的值的數量。
如果一個文字檔包含 2 行,每行包含 4 個整數值,
使用 8 次 fscanf($fd,"%d",$v) 讀取檔案將無法正常運作!
您必須執行 2 次
fscanf($fd,"%d %d %d %d",$v1,$v2,$v3,$v4);
也就是每行呼叫 1 次 fscanf。
如果您想讀取 csv 格式或類似格式的文字檔(無論欄位以何種字元分隔),您應該使用 fgetcsv() 函式。當某個欄位的文字為空白時,fscanf() 可能會跳過它並以下一個文字填入,而 fgetcsv() 則會正確地將其視為空白欄位。
另一個用於讀取檔案並根據分隔符號返回記錄/字串的函式。它與 fgets() 非常相似,只是分隔符號是一個額外的參數。可以跨多行運作。
function fgetd(&$rFile, $sDelim, $iBuffer=1024) {
$sRecord = '';
while(!feof($rFile)) {
$iPos = strpos($sRecord, $sDelim);
if ($iPos === false) {
$sRecord .= fread($rFile, $iBuffer);
} else {
fseek($rFile, 0-strlen($sRecord)+$iPos+strlen($sDelim), SEEK_CUR);
return substr($sRecord, 0, $iPos);
}
}
return false;
}
如果您想解析 cron 檔案,可以使用以下模式
<?php
while ($cron = fscanf($fp, "%s %s %s %s %s %[^\n]s"))
{
}
?>
實際上,比起試圖考慮檔案中可能出現的每個字元(不包括分隔符號),排除分隔符號會更容易。
例如,如果您的分隔符號是逗號,請使用
%[^,]
而不是
%[a-zA-Z0-9.| ... ]
只需確保在最後一個項目上使用 %[^,\n],這樣就不會包含換行符號。