php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #49988 fscanf() function doesn't work as specified
Submitted: 2009-10-25 01:41 UTC Modified: 2009-10-25 18:02 UTC
From: mwease at tx dot rr dot com Assigned:
Status: Not a bug Package: Strings related
PHP Version: 5.3.0 OS: Linux 2.0
Private report: No CVE-ID: None
 [2009-10-25 01:41 UTC] mwease at tx dot rr dot com
Description:
------------
Maybe I'm doing something wrong, but I don't think so. 

The documentation for fprintf() and fscanf() say that those functions
use the format string as defined in the documentation for sprintf().
This is not so.  fprintf() works that way, but not fscanf().  One
should actually be REQUIRED to use exactly the same format for each
if they expect what is written with fprintf() to be read by fscanf(),
but this does not work.

Reproduce code:
---------------
fprintf($entryfile,
  "%s~%s~%s~%s~%s~%s~%s~%s~%s~%s~%s~%s~%s~%s~%s~%s~%s~\n",$entrynum",
  $timestamp,$tripmiles,$loadingtype,$content,$origcity,
  $origstate,$firstdate,$lastdate,$destcity,$deststate,
  $trucktypes,$entrynotes,$thisusername,$contact,
  $_SESSION["company_name"],$phone);

output in file is:

2~200908301103~386~Drop~Unknown~Aliceville~AL~9/30/09~10/2/09~Pembroke~GA~Hopper~~JimmyB~Kyle~Ampro~800-849-6647~

$numfields = 
  fscanf($entryfile,
  "%s~%s~%s~%s~%s~%s~%s~%s~%s~%s~%s~%s~%s~%s~%s~%s~%s~",
  $fentrynum,$fdatetime,$ftripmiles,$floadingtype,$fcontent,
  $forigcity,$forigstate,$ffirstdate,$flastdate,$fdestcity,
  $fdeststate,$ftrucktypes,$fentrynotes,$fusername,$fcontact,
  $fcompany,$fphone)

Expected result:
----------------
fprintf() writes exactly the output I expect, i.e., the values of
the variables listed, all separated by the tilde (~).  some of the variables are multiple words and one of them can be 80 chars long and
at least one can be null, resulting in two tildes one after another
'~~'.  fprintf() handles it.

since i used the exact same format, minus the "\n" at the end,
fscanf() should return exactly what fprintf() wrote, assigning the
same variables to exactly what they were when written with fprintf().

Actual result:
--------------
this is what and how fscanf() reads the first line (these are results of echo statements):

numfields=1; fentrynum=2~200908301103~386~Drop~Unknown~Aliceville~AL~9/30/09~10/2/09~Pembroke~GA~Hopper~~JimmyB~Kyle~Ampro~800-849-6647~

only the first variable was assigned and to the entire line from the
file, as evidenced by both echoes.  all other variables are null.  if
i don't include the variables on the fscanf(), only the first element
of the resulting array is assigned.

apparently, the fscanf() also skipped every other line in the file.
this is the second line printed, but is actually the third line of
the file written with fprintf():

numfields=1; fentrynum=4~200908301103~642~Drop~Unknown~Birmingham~AL~9/30/09~10/1/09~Pompano

the scanning of the input line stopped at the blank in "pompano 
beach", which is the first blank in the data.  This is also wrong and not what fprintf() does with the same
format string.

i cannot place blanks to match those in my data because i have no way
of knowing where they will be and i shouldn't have to.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-10-25 11:11 UTC] jani@php.net
1. You really need to include the \n in the format string..
2. What do _you_ expect the first %s in the reading to match? Now think 
what the computer does.. :) (hint: it's all string to it..)

You need to use more precise format. Simple %s just won't work. 
http://www.php.net/manual/en/function.sprintf.php and example 6..

Basically you're writing/reading CSV format here, why not use those 
funcs instead? 

There is no bug here.

 [2009-10-25 18:02 UTC] mwease at tx dot rr dot com
in answer to your responses:

YOUR COMMENT: 1. You really need to include the \n in the format string..

----- so, you're saying that, even though the documentation specifically states that fscanf 'reads one line' per call, i must include the endline char in the format?  ridiculous AND stupid! however, i accidentally did that on the first try and i got the same results and thought that was the reason, ESPECIALLY the reading of only every other line, which you did not address.  even you have to admit that SOMETHING is wrong when i get the same results WITH or WITHOUT a '\n' character in the format!

YOUR COMMENT: 2. What do _you_ expect the first %s in the reading to match? Now think what the computer does.. :) (hint: it's all string to it..)

----- thanks for the "hint".  *I*, and anyone who thinks, would expect that first %s to take the smallest possible substring of the larger string that it is dealing with UP TO BUT NOT INCLUDING the very first occurrence of the delimiting character ('~') specified and put that substring into the first variable listed.  period.  logical.  your documentation implies it, if not explicitly stated, if only by mentioning tabs and blank space.  this is also the way it works in every language prior to C and C++.  why you think i should expect anything different is a mystery to me.  your documentation (and logic) explicitly states that tabs or whitespace can be used as delimiters.  it did NOT state that nothing ELSE could be.  if you want to ignore all this, then at least change the documentation to say that "fscanf, sscanf and all reading functions that supposedly parse input strings according to a specified format DO NOT WORK AS ANY LOGICAL PERSON WOULD IMAGINE", because THAT is the way it is.

never could i have imagined that such a format character could actually IGNORE 15 tildes and take the entire string.  i don't know what logic YOU are applying to the situation, but it makes no sense.  (see comments below about example 6).

YOUR COMMENT: You need to use more precise format. Simple %s just won't work. 
http://www.php.net/manual/en/function.sprintf.php and example 6..

---- my point exactly:  "%s just won't work"!  hence, the bug report.  yet, you reject the report and stil have the gall/ignorance to say that %s doesn't work?  you just said that %s doesn't work but it's not a bug.  you design shit like this on purpose?  apparently so.  if you don't call that a bug, then i'm certain that i can't do anything about it.  i WAS precise.  i told fscanf to look for some substring (%s), then it will find a '~', and to put the substring it found into my first variable, based on the %s being the first format character.  i didn't say "use this format character, %s, and suck up as many characters as you can and ignore all the other format characters and delimiters  i put in this format string"!!!!!!!

---- by directing me to this example, it appears that you are suggesting that i use fixed-length fields when i output so that i can overcome the deficiencies in PHP when using the xscanx functions.  well, one answer is that i have one field that in this data that can be entered by users or not, that it is a max of 80 characters, and because i am efficient.  i refuse to waste 80 characters of space for 90% of the records in my data file just because of the poor and illogical design of PHP functions and the smugness of the maintainers who can't see it.  (and, no, i'm NOT smug.  i'm right.)

YOUR COMMENT: Basically you're writing/reading CSV format here, why not use those funcs instead? 

---- i don't know what CSV is or what it stands for and why would i want to waste my time learning it when so many OTHER things in PHP don't work as expected, even though you all believe it's perfect?


PLEASE NOTE: i don't appreciate the condesending attitude.  i was a software engineer for 20 years and i was paid more as a designer than many of the next level supervisors simply because i was good.  all facts and a lot of it because i recognize bullshit when i hear/read it and i am extremely efficient when i work, how i work and in my software.

PHP is an extremely powerful language and i like a lot about it.  i've only been using it for about three months.  however, all of its power doesn't matter too much to someone who has to spend hours and days trying to figure out a simple little error such as leaving off a '$' from the front of a variable or, as C and C++ are, NOT using two equal signs instead of one in comparison.  yes, it's powerful, but it is also painful and massively time-consuming in development ONLY because your error messages SUCK.  languages back in the 1980s could tell me exactly what i did wrong, but you folks can't seem to determine when a variable lacks a $.

i opened a previous bug report about the lack or error message and was put off just as you have, jani@php.net.  when i open a bug report, i am thanked for trying to make the product better, but both times i have done so, i feel a little ridiculed and the points i made are ignored.  apparently, you believe that you all have done everything just perfectly and how it should have been done and don't give a shit about how difficult it is to use.  you are probably all C/C++ babies, but i started before such ridiculously free-wheeling languages existed.

what the C worshipers will never understand is that costs of developing software when a programmer can do just about anything with a language skyrocket because the programmers spend so much time getting the programs right exactly BECAUSE of the syntactic power.

what the C++ worshipers will never understand is that, even though PCs are something like 4000-10,000 TIMES faster than my first PC and available RAM is not 64k as it was, but virtually unlimited, OOP and fancy graphics have basically kept the response time to the end user about the same or worse.

what NEITHER C or C++ (and now PHP, i guess) worshipers have NOT realized for some unimaginable reason, is that the power of a language comes from what it DOES, NOT how one types it in or that one might have to repeat a variable's name (x = x + 1) in order to increment it by 1.  and, of course, it is intuitively obvious to every human being (and college graduate) what the outcome of THIS would be, right?: 

   if ($x++ = $y-- + $z++) $x++ .= $q[$x++];
   // gee.  does x get increased before or after it's used?

it's absolutely ridiculous.  someone once sent me a C program that looked like absolute gibberish, had not one recognizable english or C keyword in it, yet when ran, displayed all the verses to The Twelve Days of Christmas.  cool.  incredibly STUPID that a language would allow such a thing.

if i were paying someone to develop software for me, i would NEVER allow them to use C, C++ (or any OOP language) or PHP.  i couldn't possibly make a profit on it, with the possible exception that the entire industry has been taken over by such naive, but cool-and-powerful-language seekers.

i know it's free.  i assume that many people work on this without compensation.  that's a good thing.  

i just finished 3 months of the most painful computer task i have ever done.  at least 50% of that pain, probably closer to 85%, was because PHP gives the user just shy of absolutely NO help with errors, regardless of what level or error displaying is turned on.  i just thought that the maintainers might for a second take into account the usability of the product.

Michael R Wease
mwease@tx.rr.com
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Mar 28 13:01:28 2024 UTC