fscanf

(PHP 4 >= 4.0.1, PHP 5, PHP 7, PHP 8)

fscanf根据格式解析文件中的输入

描述

fscanf(资源 $stream, 字符串 $format, 混合 &...$vars): 数组|整数|false|null

函数 fscanf() 类似于 sscanf(),但它从与 stream 关联的文件中获取输入,并根据指定的 format 解释输入。

格式字符串中的任何空格都与输入流中的任何空格匹配。这意味着,即使格式字符串中的制表符 (\t) 也可以与输入流中的单个空格字符匹配。

每次调用 fscanf() 都从文件中读取一行。

参数

stream

文件系统指针 资源,通常使用 fopen() 创建。

format

string 的解释格式,在 sprintf() 文档中进行了描述,但存在以下区别

  • 函数不感知区域设置。
  • FgGb 不受支持。
  • D 代表十进制数。
  • i 代表带有基数检测的整数。
  • n 代表到目前为止处理的字符数。
  • s 在遇到任何空格字符时停止读取。
  • * 代替 argnum$ 会抑制对该转换说明的赋值。

vars

可选的赋值。

返回值

如果此函数只传递了两个参数,则解析的值将作为数组返回。否则,如果传递了可选参数,则函数将返回分配的值数量。可选参数必须通过引用传递。

如果 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

参见

  • fread() - 安全的二进制文件读取
  • fgets() - 从文件指针中获取行
  • fgetss() - 从文件指针中获取行并去除 HTML 标签
  • sscanf() - 根据格式解析字符串中的输入
  • printf() - 输出格式化字符串
  • sprintf() - 返回格式化字符串

添加备注

用户贡献的备注 10 个备注

yasuo_ohgaki at hotmail dot com
23 年前
对于 C/C++ 程序员。

fscanf() 的工作原理与 C/C++ 不同,因为 PHP 的 fscanf() 会隐式地将文件指针移动到下一行。
Bertrand dot Lecun at prism dot uvsq dot Fr
17 年前
最好在 fscanf 文档中说明
一次调用该函数,会读取完整的一行。
而不是仅仅读取格式中定义的值数量。

如果一个文本文件包含 2 行,每行包含 4 个整数值,
使用 8 个 fscanf($fd,"%d",$v) 读取文件,不会运行!
您必须执行 2 次
fscanf($fd,"%d %d %d %d",$v1,$v2,$v3,$v4);

然后每行 1 个 fscanf。
eugene at pro-access dot com
22 年前
如果您想读取 csv 格式的文本文件或类似文件(无论字段使用什么字符分隔),您应该使用 fgetcsv()。当字段的文本为空时,fscanf() 可能会跳过它并用下一个文本填充它,而 fgetcsv() 会正确地将其视为一个空字段。
worldwideroach at hotmail dot com
19 年前
另一个用于读取文件并通过分隔符返回记录/字符串的函数。它与 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;
}
nico at nicoswd dot com
10 年前
如果您想解析 cron 文件,可以使用此模式

<?php

while ($cron = fscanf($fp, "%s %s %s %s %s %[^\n]s"))
{

}

?>
loco.xxx at gmail dot com
18 年前
要包含所有类型的可见字符,您应该尝试

<?php fscanf($file_handler,"%[ -~]"); ?>
robert at NOSPAM dot NOSPAM
21 年前
实际上,与其尝试考虑文件中可能存在的每个字符,不如排除分隔符更轻松。

例如,如果您的分隔符是逗号,请使用

%[^,]

而不是

%[a-zA-Z0-9.| ... ]

只需确保在最后一个条目中使用 %[^,\n],这样您就不会包含换行符。
arentzen at religion dot dk
16 年前
如果您希望 fscanf() 在大量行中扫描一个变量,例如一行中包含多个变量的 IP 地址,则可以使用 fscanf 与 explode()
<?
$filename = "somefile.txt";
$fp = fopen($filename, "r") or die ("Error opening file! \n");
$u = explode(" ",$line); // $u 是变量,例如 IP 地址
while ($line = fscanf($fp,"%s",$u)) {
if(preg_match("/^$u/",$_SERVER['REMOTE_ADDR'])) {$badipadresss++;} // 执行某些操作并继续扫描
}
?>
此外,fscanf() 比 fgets() 快得多
james at zephyr-works dot com
23 年前
我发现 fscanf 的工作方式有点奇怪。 你可能需要使用集合而不是简单的 %s。 因为 fscanf 的工作方式与 C/C++ 大相径庭,所以它没有能力在字符串中提前扫描并正确匹配模式,因此看似完美的函数调用,例如:

fscanf($fh, "%s::%s");

对于类似这样的文件:

user::password

将不起作用。 当 fscanf 寻找字符串时,它只会查找并停止在空格处,因此 :: 以及除空格之外的所有内容都将被视为该字符串的一部分。 但是,你可以通过以下方式使它更聪明一些:

fscanf($fh, "%[a-zA-Z0-9,. ]::%[a-zA-Z0-9,. ]" $var1, $var2);

这告诉它,它只能接受 a 到 z、A 到 Z、0 到 9、逗号、句号和空格作为字符串的输入。 其他任何字符都将导致它停止接收输入并继续解析该行。 如果您希望将一个句子放入字符串中,并且不确定要添加多少个单词,等等,这将非常有用。
hdh265 at 163 dot com
9 年前
在 ACM 提交中使用 PHP 代码
这是一个使用 PHP 解决问题 1001 的示例解决方案
<?php
while (fscanf(STDIN, "%d%d", $a, $b) == 2) {
print (
$a + $b) . "\n";
}
To Top