bugGNU Octave - Bugs: bug #42345, manual should describe...

 
 

bug #42345: manual should describe incompatibility in fprintf on invalid %-sequence

Submitter:  Muhali <muhali>
Submitted:  Tue 13 May 2014 12:34:05 PM UTC
   
 
Category:  Documentation Severity:  2 - Minor
Priority:  5 - Normal Item Group:  Documentation
Status:  Fixed Assigned to:  None
Originator Name:  Open/Closed:  * Closed
Release:  * 3.8.1 Operating System:  * Any
Fixed Release:  None Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Tue 30 Dec 2014 05:12:34 PM UTC, comment #20: 

Using puts would be another good suggestion.

I assumed most people would be starting with code that already had printf in it and wanted to make the minimal change.  Also, puts is Octave-specific and users might want the code to run under both environments.

Rik <rik5>
Group administrator
Tue 30 Dec 2014 04:46:20 PM UTC, comment #19: 

Any reason not to recommend puts (str) instead of printf ("%s", str)?

John W. Eaton <jwe>
Group administrator
Tue 30 Dec 2014 04:33:01 PM UTC, comment #18: 

I added some notes to the documentation about this Matlab incompatibility and how to work around it in this changeset (http://hg.savannah.gnu.org/hgweb/octave/rev/8ee14c64ab5f).  Closing report.

Rik <rik5>
Group administrator
Wed 14 May 2014 02:50:54 PM UTC, comment #17: 

Behaviour should be similar to TCP, so if you have MATLAB, you could test this code:


echotcpip('on',4012)
t = tcpip('localhost',4012);
fopen(t)
fprintf(t,'%')
A = fread(t, 1);
fclose(t)
echotcpip('off')



Stefan Mahr <dac922>
Wed 14 May 2014 02:24:35 PM UTC, comment #16: 

Sorry, let me clarify some more. Here's what is valid, for printing to stdout:


fprintf(text);
fprintf(fmt, data_or_string_args, ...);


The following is valid for file descriptors opened with fopen:


fprintf(fid, text);
fprintf(fid, fmt, data_or_string_args, ...);


And for instrument control, according to Matlab's public help:


fprintf(obj, text);
fprintf(obj, fmt, text);
fprintf(obj, text, sync_or_async);
fprintf(obj, fmt, text, sync_or_async);


Those are all valid, but that doesn't make them a good idea. What I'm saying is, unless you are completely in control of the text string and know that it contains no % characters, you should always use one of the following:


fprintf('%s', text);
fprintf(fid, '%s', text);
fprintf(obj, '%s', text);


Using fprintf(text) is legal, but not recommended if text may contain a % character because it may be interpreted into something unexpected.

Now I see that instrument control has some heuristics about line terminators, since I guess they assume you are talking to some kind of serial device. I honestly have no idea what instrument control's version of fprintf does with invalid conversion specifiers or with conversions with no following argument. But I would hope that it follows the same rules as normal fprintf, in which case fprintf(obj,'%') and fprintf(obj,'%s') would both result in an empty string being sent to the device.

Mike Miller <mtmiller>
Group Member
Wed 14 May 2014 01:34:07 PM UTC, comment #15: 

Ok, so syntax fprintf(obj, text) is only valid for instrument-control. In this case 'text' is not a format string. Thanks for clarifying.

Stefan Mahr <dac922>
Wed 14 May 2014 12:57:05 PM UTC, comment #14: 

Stefan, that is a separate issue, and is also not correct. If there are no arguments after the conversion string (or equivalently, an empty matrix), Matlab returns an empty string for that example. The first (non-filehandle) argument is always a format string, which is why if you don't want it to be interpreted that way, you must always use fprintf('%s', str).

Mike Miller <mtmiller>
Group Member
Wed 14 May 2014 11:28:29 AM UTC, comment #13: 

Muhali, I think it's logical to produce a literal % with fprintf('%'). There's no argument after the string, so it must not interpreted as format string. I guess MATLAB fprintf('%s') prints out '%s'.

For syntax fprintf(formatstring,argument) it's a complete different behaviour.

Stefan Mahr <dac922>
Wed 14 May 2014 12:02:17 AM UTC, comment #12: 

Ok, consensus says to turn this into a documentation bug. Specifically, the manual section that describes printf-compatible conversion specifiers should describe the Matlab incompatibility and that Octave will generate an error if in invalid specifier is seen. Patches welcome to fix this in the current manual.

Mike Miller <mtmiller>
Group Member
Tue 13 May 2014 04:46:23 PM UTC, comment #11: 

I vote with John. Keep current behavior and document it.

Michael Godfrey <godfrey>
Group Member
Tue 13 May 2014 04:12:01 PM UTC, comment #10: 

fprintf('% %d',1)

produces nothing in Matlab. Producing a literal '%' is done with '%%', so doing it without that, as I suggested in my earlier comment, would not seem to be logical.

Muhali <muhali>
Tue 13 May 2014 03:59:47 PM UTC, comment #9: 


fprintf(text)
fprintf(obj,cmd)

are documented sytax in some cases (simulink and instrument control). So it may be useful to interpret % as literal, if there's no parameter after the string.

What's MATLABs output for this command?

fprintf('% %d',1)


Stefan Mahr <dac922>
Tue 13 May 2014 03:12:47 PM UTC, comment #8: 

Completely agree, either change to make it more Matlab compatible or don't change at all. And I also personally think an error on a bad conversion specifier is a good thing, so I'd keep the current behavior.

There is no documentation that I can see of the Matlab behavior when an unrecognized conversion sequence is given after a % character.

Mike Miller <mtmiller>
Group Member
Tue 13 May 2014 03:08:48 PM UTC, comment #7: 

I think the Matlab behavior is worse than throwing an error.  I'd opt for documenting and keeping the current Octave behavior.

John W. Eaton <jwe>
Group administrator
Tue 13 May 2014 03:01:09 PM UTC, comment #6: 

I see no point in doing something that is incompatible and arguably worse than throwing an error.  So we should either do exactly as Matlab does or keep the current behavior if the Matlab behavior doesn't make sense.

John W. Eaton <jwe>
Group administrator
Tue 13 May 2014 03:00:15 PM UTC, comment #5: 

That is kind of a suspect usage example, though. I mean when that sort of thing comes up in a C program, you have to make sure you escape % characters in your string before ever passing them to a printf-like function. That should definitely be fixed in whatever usage you're seeing this with. The ncdisp function here shouldn't even be using fprintf, it should use puts(msg) instead.

If we're going to change anything, we should make it more Matlab-compatible, so that would be discarding the rest of the string after the bad conversion specifier I guess.

Mike Miller <mtmiller>
Group Member
Tue 13 May 2014 02:59:33 PM UTC, comment #4: 

Instead of


fprintf (msg)


you should use


fprintf ('%s', msg)


John W. Eaton <jwe>
Group administrator
Tue 13 May 2014 02:56:26 PM UTC, comment #3: 

the issue came up with netcdf, where within the ncdisp function a statement like


fprintf(msg)


is used to display certain attributes of a netcdf file. If those attributes contain a "%" (and why should they not?), an error occurs.

As mentioned, ML returns a single quote, so it seems to discard everything starting from the %. Just passing the literal string instead seems more logical to me.

Muhali <muhali>
Tue 13 May 2014 02:48:28 PM UTC, comment #2: 

Does Matlab silently discard unrecognized escape sequences or does it just pass them as literal text?  Either behavior would be easy to do, we just need to know which it is.  I have no problem being compatible in this regard.

John W. Eaton <jwe>
Group administrator
Tue 13 May 2014 02:33:00 PM UTC, comment #1: 

Thanks for your bug report. I think what this is showing is an intentional Matlab incompatibility when invalid/unrecognized conversion specifiers are given to printf/sprintf/fprintf.

When Matlab sees an invalid conversion specifier, let's say %r


sprintf('x = %r, here is the rest', 0)


I think it silently either throws away the invalid one and continues, or it stops converting at that point and returns the string so far. I thought I saw this come up before but I can't find anything in my mailbox at the moment.

When Octave sees an invalid conversion specifier like the above, it errors with the error string you saw. Neither %' nor %" mean anything useful, so Octave prints an error and returns nothing.

Is this an important compatibility that needs to be addressed or is Octave doing the right thing enforcing correct conversion strings be passed to printf-like functions?

Mike Miller <mtmiller>
Group Member
Tue 13 May 2014 12:34:05 PM UTC, original submission:  

Unlike ML, octave apparently does not like


fprintf('''%''')


as a format string, and it returns

error: fprintf: invalid format specified

The same applies for


fprintf("\"%\"")


I am not sure whether the single quote returned by ML is correct here, but at least it does not throw an error.

Muhali <muhali>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by godfrey (Posted a comment)
  • -email is unavailable- added by dac922 (Posted a comment)
  • -email is unavailable- added by jwe (Posted a comment)
  • -email is unavailable- added by mtmiller (Posted a comment)
  • -email is unavailable- added by muhali (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only group members can vote.

     

    Follow 12 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2014-12-30 rik5 StatusConfirmed Fixed
        Open/ClosedOpen Closed
    2014-05-14 mtmiller Summaryfprintf(\'\'\'%\'\'\') throws error manual should describe incompatibility in fprintf on invalid %-sequence
    2014-05-14 mtmiller CategoryOctave Function Documentation
        Severity3 - Normal 2 - Minor
        Item GroupMatlab Compatibility Documentation
        StatusNeed Info Confirmed
        Releasedev 3.8.1
    2014-05-13 mtmiller CategoryNone Octave Function
        Item GroupNone Matlab Compatibility
        StatusNone Need Info
        Operating SystemGNU/Linux Any

    Back to the top

    Powered by Savane 3.13-758e.
    Corresponding source code