Re: another newbie question

Guido.van.Rossum@cwi.nl
Mon, 15 Aug 1994 10:27:57 +0200

> What is the simplest safe equivalent of C's scanf? I want to read a
> file containing complex numbers of the form (a, b), and store the "a"
> and "b" values in structure fields:
>
> i = 0;
> while (fgets(buf, Buf_Len, infile) != NULL){
> ass(buf[0] = '(', "badly-formatted input line",
> "line", "%d", i, NULL);
> ass(sscanf(buf+1, "%f%f", &(c[i].r), &(c[i].i)) == 2,
> "badly-formatted input line",
> "line", "%d", i, NULL);
> i++;
> }
>
> I know I can do this with readline(), split(), and atof(), but it
> requires a lot of extra lines of error checking (or seems to).

You don't need to write the error checking unless you want a more
subtle error report than a Python stack trace (and your use of an
assertion macro seems to indicate that in C you're happy with that):
in Python, errors like ill-formatted numbers terminate your program
with an exception unless you handle it.

You could try using regular expressions to solve your input problem:

import regex
from string import atoi

rdr = regex.compile(' *( *\([-+0-9.e]*\) *, *\([-+0-9.e]*\) *) *')

while 1:
line = infile.readline()
if not line: break
if rdr.match(line) < 0:
raise ValueError, 'badly-formatted input line'
rr, is = rdr.group(1, 2)
c.append(atoi(rr), atoi(ri))

Note that all forms if ill-formatted input will raise the ValueError
exception (string.atoi raises it when it sees a bad number) so if you
need more subtle error reporting you could rewrite the loop like this:

while 1:
line = infile.readline()
if not line: break
try:
if rdr.match(line) < 0:
raise ValueError, 'badly-formatted input line'
rr, is = rdr.group(1, 2)
c.append(atoi(rr), atoi(ri))
except ValueError, msg:
print 'Line', len(c)+1, 'skipped :', msg

or like this (if you want the bad input to terminate the loop):

try:
while 1:
line = infile.readline()
if not line: break
if rdr.match(line) < 0:
raise ValueError, 'badly-formatted input line'
rr, is = rdr.group(1, 2)
c.append(atoi(rr), atoi(ri))
except ValueError, msg:
print 'Error in line', len(c)+1, ':', msg

--Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl>
<URL:http://www.cwi.nl/cwi/people/Guido.van.Rossum.html>