• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • fscanf()

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

    从文件中格式化输入

    说明

    fscanf(resource $handle,string $format[,mixed&$...]): mixed

    fscanf()函数和sscanf()相似,但是它从与$handle关联的文件中接受输入并根据指定的$format(定义于sprintf()的文档中)来解释输入。

    格式字符串中的任何空白会与输入流中的任何空白匹配。这意味着甚至格式字符串中的制表符t也会与输入流中的一个空格字符匹配。

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

    参数

    $handle

    文件系统指针,是典型地由fopen()创建的resource(资源)。

    $format

    参数格式是sprintf()文档中所描述的格式。

    ...

    The optional assigned values.

    返回值

    如果只给此函数传递了两个参数,解析后的值会被作为数组返回。否则,如果提供了可选参数,此函数将返回被赋值的数目。可选参数必须用引用传递。

    更新日志

    版本说明
    4.3.0在 PHP 4.3.0 之前,从文件中读入的最大字符数是 512(或者第一个n,看先碰到哪种情况)。从 PHP 4.3.0 起可以读取任意长的行。

    范例

    Example #1fscanf()例子

    <?php
    $handle = fopen("users.txt", "r");
    while ($userinfo = fscanf($handle, "%s\t%s\t%s\n")) {
        list ($name, $profession, $countrycode) = $userinfo;
        //... do something with the values
    }
    fclose($handle);
    ?>
    

    users.txt 的内容

    javier  argonaut        pe
    hiroshi sculptor        jp
    robert  slacker us
    luigi   florist it

    参见

    • fread() 读取文件(可安全用于二进制文件)
    • fgets() 从文件指针中读取一行
    • fgetss() 从文件指针中读取一行并过滤掉 HTML 标记
    • sscanf() 根据指定格式解析输入的字符
    • printf() 输出格式化字符串
    • sprintf()Return a formatted string
    For C/C++ programmers.
    fscanf() does not work like C/C++, because PHP's fscanf() move file pointer the next line implicitly.
    It would be great to precise in the fscanf documentation
    that one call to the function, reads a complete line.
    and not just the number of values defined in the format.
    If a text file contains 2 lines each containing 4 integer values,
    reading the file with 8 fscanf($fd,"%d",$v) doesnt run !
    You have to make 2 
    fscanf($fd,"%d %d %d %d",$v1,$v2,$v3,$v4);
    Then 1 fscanf per line.
    If you want to read text files in csv format or the like(no matter what character the fields are separated with), you should use fgetcsv() instead. When a text for a field is blank, fscanf() may skip it and fill it with the next text, whereas fgetcsv() correctly regards it as a blank field.
    If you want to parse a cron file, you may use this pattern:
    <?php
    while ($cron = fscanf($fp, "%s %s %s %s %s %[^\n]s"))
    {
    }
    ?>
    
    Yet another function to read a file and return a record/string by a delimiter. It is very much like fgets() with the delimiter being an additional parameter. Works great across multiple lines.
    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;
    }
    actually, instead of trying to think of every character that might be in your file, excluding the delimiter would be much easier.
    for example, if your delimiter was a comma use:
    %[^,]
    instead of:
    %[a-zA-Z0-9.| ... ]
    Just make sure to use %[^,\n] on your last entry so you don't include the newline.
    to include all type of visible chars you should try:
    <?php fscanf($file_handler,"%[ -~]"); ?>
    
    fscanf works a little retardedly I've found. Instead of using just a plain %s you probably will need to use sets instead. Because it works so screwy compared to C/C++, fscanf does not have the ability to scan ahead in a string and pattern match correctly, so a seemingly perfect function call like:
    fscanf($fh, "%s::%s");
    With a file like:
    user::password
    Will not work. When fscanf looks for a string, it will look and stop at nothing except for a whitespace so :: and everything except whitespace is considered part of that string, however you can make it a little smarter by:
    fscanf($fh, "%[a-zA-Z0-9,. ]::%[a-zA-Z0-9,. ]" $var1, $var2);
    Which tells it that it can only accept a through z A through Z 0 through 9 a comma a period and a whitespace as input to the string, everything else cause it to stop taking in as input and continue parsing the line. This is very useful if you want to get a sentence into the string and you're not sure of exactly how many words to add, etc.
    If you want fscanf()to scan one variable in a large number of lines, e.g an Ipadress in a line with more variables, then use fscanf with explode()
    <?
    $filename = "somefile.txt";
    $fp = fopen($filename, "r") or die ("Error opening file! \n");
    $u = explode(" ",$line); // $u is the variable eg. an IPadress
    while ($line = fscanf($fp,"%s",$u)) {
    if(preg_match("/^$u/",$_SERVER['REMOTE_ADDR'])) {$badipadresss++;} // do something and continue scan
    }
    ?>
    Besides, fscanf()is much faster than fgets()
    The use of PHP code in the ACM submission
    Here is a sample solution for problem 1001 using PHP:
    <?php
    while (fscanf(STDIN, "%d%d", $a, $b) == 2) {
      print ($a + $b) . "\n";
    }

    上篇:fread()

    下篇:fseek()