For C/C++ programmers.
fscanf() does not work like C/C++, because PHP's fscanf() move file pointer the next line implicitly.
(PHP 4 >= 4.0.1, PHP 5, PHP 7)
fscanf — Parses input from a file according to a format
The function fscanf() is similar to
sscanf(), but it takes its input from a file
associated with stream
and interprets the
input according to the specified format
, which is
described in the documentation for sprintf().
Any whitespace in the format string matches any whitespace in the input
stream. This means that even a tab \t
in the format
string can match a single space character in the input stream.
Each call to fscanf() reads one line from the file.
stream
O resursă de tip indicator în sistemul de fișiere care este în mod tipic creată utilizând fopen().
format
Șirul de formatare este compus din zero sau mai multe directive: caractere
obișnuite (în afară de %
), care sunt copiate direct
în rezultat și specificatori de conversie, fiecare
având parametrul său.
Un specificator de conversie e compus după următorul prototip:
%[argnum$][flags][width][.precision]specifier
.
Un întreg urmat de senmul dolar $
,
pentru a specifica ce argument de număr trebuie tratat în conversie.
Flag | Descriere |
---|---|
- |
Alinierea spre stânga în limitele lungimii câmpului; Implicit se efectuează alinierea spre dreapta |
+ |
Prefixează numerele pozitive cu semnul plus
+ ; implicit doar numerele negative sunt prefixate cu
semnul minus.
|
(spațiu) |
Completează rezultatul cu spații. Acesta este comportamentul implicit. |
0 |
Completează numerele cu zerouri în stânga.
Cu specificatorii s se poate de completat cu zerouri
și în dreapta.
|
' (char) |
Completează rezultatul cu caracterul (char). |
Un număr întreg ce indică câte caractere (minimum) trebuie să aibă rezultatul conversiei.
Un punct .
, urmat de un număr întreg, însemnătatea căruia
depinde de specificator:
e
, E
,
f
și F
: acesta este numărul de cifre
ce vor fi tipărite după punctul zecimal (implicit acesta este 6).
g
și G
:
acesta este numărul maxim de cifre semnificative ce va fi tipărit.
s
: acesta funcționează ca punct
de oprire, stabilind limita maximă a numărului de caractere din șir.
Notă: Dacă punctul este specificat fără o valoare explicită pentru precizie, se presupune că aceasta este 0.
Notă: Încercarea de a folosi un specificator de poziție mai mare decât
PHP_INT_MAX
va genera avertizări.
Specifier | Descriere |
---|---|
% |
Specifică caracterul procent. Nu este necesar vre-un argument. |
b |
Argumentul este tratat ca un întreg și prezentat ca număr binar. |
c |
Argumentul este tratat ca un întreg și prezentat ca caracter cu acest cod ASCII. |
d |
Argumentul este tratat ca un întreg și prezentat ca număr zecimal (cu semn). |
e |
Argumentul este tratat ca număr în notație exponențială (de ex. 1.2e+2). Specificatorul de precizie semnifică numărul de cifre după virgulă începând cu PHP 5.2.1. În versiuni anterioare el specifica numărul de cifre semnificative (cu una mai puțin). |
E |
La fel ca și specificatorul e , dar folosește
caracterul majuscul (de ex. 1.2E+2).
|
f |
Argumentul este tratat ca număr cu virgulă și prezentat ca atare (în dependență de setările de localizare). |
F |
Argumentul este tratat ca număr cu virgulă și prezentat ca atare (fără a se ține cont de setările de localizare). Disponibil începând cu PHP 5.0.3. |
g |
Format general. Fie că P este egal cu precizia, dacă nu este zero, 6 dacă precizia este omisă, sau 1 dacă precizia este zero. Atunci dacă o conversie cu stilul E ar avea un exponent X: Dacă P > X ≥ −4, atunci conversia este de stilul f și precizia P − (X + 1). În caz contrar, conversia este de stilul e și precizia P − 1. |
G |
La fel ca și specificatorul g , dar utilizează
E și f .
|
o |
Argumentul este tratat ca întreg și prezentat ca număr octal. |
s |
Argumentul este tratat și prezentat ca șir de caractere. |
u |
Argumentul este tratat ca întreg și prezentat ca număr zecimal fără semn. |
x |
Argumentul este tratat ca întreg și prezentat ca număr hexazecimal (cu caractere minuscule). |
X |
Argumentul este tratat ca întreg și prezentat ca număr hexazecimal (cu caractere majuscule). |
Specificatorul de tip c
ignoră completarea cu spații și lungimea
Încercarea de a folosi o combinație din specificatori de șiruri de caractere și lungime cu seturi de caractere ce necesită mai mult de un octet per caracter poate da rezultate imprevizibile
Variabilele vor fi aduse la un tip potrivit pentru specificatorul:
Tipul | Specificatorii |
---|---|
string |
s |
integer |
d ,
u ,
c ,
o ,
x ,
X ,
b
|
double |
g ,
G ,
e ,
E ,
f ,
F
|
vars
The optional assigned values.
If only two parameters were passed to this function, the values parsed will be returned as an array. Otherwise, if optional parameters are passed, the function will return the number of assigned values. The optional parameters must be passed by reference.
If there are more substrings expected in the format
than there are available within string
,
null
will be returned. On other errors, false
will be returned.
Example #1 fscanf() Example
<?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);
?>
Example #2 Contents of users.txt
javier argonaut pe hiroshi sculptor jp robert slacker us luigi florist it
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.
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;
}
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"))
{
}
?>
to include all type of visible chars you should try:
<?php fscanf($file_handler,"%[ -~]"); ?>
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.
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()
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.
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";
}