octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

minor fscanf problem


From: Pascal A. Dupuis
Subject: minor fscanf problem
Date: Mon, 9 Feb 2004 15:42:16 +0100
User-agent: Mutt/1.5.5.1+cvs20040105i

Hello,

let say that I've a file with the following content:
3.0 2.0 -Inf 1.5

Trying to read all of it as floats:
[a, count]=fscanf(FID,"%f")
a =

  3
  2

count = 2

Reading the following as a string:
[b, newcount]=fscanf(FID, '%s', 'C')
b = Inf
count = 1

As 'Inf' is a valid number, I can add it to 'a' and iterate again.

The problem is that the - sign has be "eaten" by the fscanf('%f'), as the valid
beginning of a float expression.

Fix:
cur_pos = ftell(FID);
[a, count]=fscanf(FID,"%f");
fseek(FID, cur_pos);
a = fscanf(FID, "%f", count);
b = fscanf(FID, '%s', 'C');
[intepret b as 'Inf' and iterate...]

But this is tedious, as the scanning has to be performed twice. Going
back one character on the FID works on some architecture but is not
garanteed to be portable everywhere. To get an idea, reads gnu libc
info pages over ftell and fseek, and in particular the paragraph
entitled "Portable File-Position Functions".

I looked a bit into the source, and, if I understand correctly, the
fscanf main loop sits within do_scanf, which repeatidly calls
do_scanf_conv, where the true scanning is done in OCTAVE_SCAN, which
itself calls octave_scan. Would it be possible there to save the
stream current postion, perform the scanning for one value, and finally
restore the stream position if unsucessfull like this:

template <class T>
std::istream&
octave_scan (std::istream& is, const scanf_format_elt& fmt, T* valptr)
{
  T& ref = *valptr;
  streampos curr_pos = is.tellg();      

  switch (fmt.type)
    {
    case 'o':
      is >> std::oct >> ref;
      break;

    case 'x':
      is >> std::hex >> ref;
      break;

    default:
      is >> ref;
      break;
    }

  // in case of failure, restore the stream position
  if (is.rdstate () & std::ios::failbit)
    is.seekg(curr_pos);
        
  return is;
}


In this case, we're working on _stream_ position, not on _file_
position. The downside is to have to call tellg() for each conversion.

The problem I'm trying to solve is to write a specialised function
that has to read and take some values from a header, and than can
accept any numbers including Inf, NA and NAN.

Best regards

Pascal Dupuis

-- 
Dr. ir. Pascal Dupuis
K. U. Leuven, ESAT/ELECTA (formerly ELEN):  http://www.esat.kuleuven.ac.be/
Kasteelpark Arenberg, 10; B-3001 Leuven-Heverlee, Belgium
Tel. +32-16-32 10 21 -- Fax +32-16-32 19 85



reply via email to

[Prev in Thread] Current Thread [Next in Thread]