sscanf to read file stored in string

J

john.chludzinski

I have an entire file stored in a string. The file is 2 columns of doubles (stored in ASCII, of course). The doubles are separated by an arbitrary number of spaces, maybe tabs too.

sscanf(file_bytes+offset, "%lf %lf", &x, &y) will return the number of "items" read, in this case 2 doubles.

I need to know how to increment "offset" to read the next line?

---John

PS> I looked in FAQs but didn't see anything to answer this question.
 
F

Fred K

I have an entire file stored in a string. The file is 2 columns of doubles (stored in ASCII, of course). The doubles are separated by an arbitrary number of spaces, maybe tabs too.



sscanf(file_bytes+offset, "%lf %lf", &x, &y) will return the number of "items" read, in this case 2 doubles.



I need to know how to increment "offset" to read the next line?


Don't use sscanf(). Use strtod() instead.
 
K

Keith Thompson

I have an entire file stored in a string. The file is 2 columns of
doubles (stored in ASCII, of course). The doubles are separated by an
arbitrary number of spaces, maybe tabs too.

sscanf(file_bytes+offset, "%lf %lf", &x, &y) will return the
number of "items" read, in this case 2 doubles.

I need to know how to increment "offset" to read the next line?


I don't think you can do that with sscanf; it doesn't tell you how many
characters it processed.

Use strtod() instead. Its endptr parameter can be used to get a pointer
to the next character after the last one used in the conversion. It
also has the considerable advantage of being much more robust; if sscanf
reads something that has the syntax of a floating-point number, but is
outside the range of the type (such as "1.0e99999999"), the behavior is
undefined. strtod() can handle such errors.

Calling strtod() repeatedly will give you one double value at a time,
delimited by whitespace (which includes both spaces and newlines).

If you want to detect formatting errors, such as a line that doesn't
have exactly two numbers, you can scan the string for '\n' and space
characters and then call strtod().
 
B

Ben Pfaff

Keith Thompson said:
I have an entire file stored in a string. The file is 2 columns of
doubles (stored in ASCII, of course). The doubles are separated by an
arbitrary number of spaces, maybe tabs too.

sscanf(file_bytes+offset, "%lf %lf", &x, &y) will return the
number of "items" read, in this case 2 doubles.

I need to know how to increment "offset" to read the next line?


I don't think you can do that with sscanf; it doesn't tell you how many
characters it processed.


You can use %n.
 
J

James Kuyper

I have an entire file stored in a string. The file is 2 columns of doubles (stored in ASCII, of course). The doubles are separated by an arbitrary number of spaces, maybe tabs too.

sscanf(file_bytes+offset, "%lf %lf", &x, &y) will return the number of "items" read, in this case 2 doubles.

I need to know how to increment "offset" to read the next line?


For this kind of work, what you need is strtod(), not sscanf().
Warning: untested code. As given below, it's uncompilable: it needs a
context that defines MAX_BYTES, file_bytes, x, and y, and fills in
file_bytes, and declares a function that the code below can be part of.

#include <errno.h>
#include <stdlib.h>
#include
const char *nptr = file_bytes;

for(int i=0; i<MAX_ITEMS && *nptr; i++)
{
char *endptr;

errno = 0;
x = strtod(nptr, &endptr);
if(nptr == endptr)
{
fprintf(stderr, "x[%d]: \"%s\"\n is empty or does "
"not have the form expected by strtod()\n", i, nptr);
break;
}
else if(errno == ERANGE && fabs(x) >= HUGE_VAL)
{
fprintf(stderr, "x[%d]: strtod(\"%s\") overflowed\n", i, nptr);
break;
// ERANGE might or might not also be set on underflow.
}
else if(*endptr == '\0')
{
fprintf(stderr, "file ends without a y value for item %d\n", i);
break;
}
nptr = endptr;

errno = 0;
y = strtod(nptr, &endptr);
// Insert similar error handling code here.
nptr = endptr;
}

The error handling here is just basic, it can be improved. In
particular, you should probably limit the number of bytes that are
printed from nptr: search for the end of the current line, and don't
print beyond that. I've left those details to be filled in by the student.
 
E

Eric Sosman

I have an entire file stored in a string. The file is 2 columns of doubles (stored in ASCII, of course). The doubles are separated by an arbitrary number of spaces, maybe tabs too.

sscanf(file_bytes+offset, "%lf %lf", &x, &y) will return the number of "items" read, in this case 2 doubles.

I need to know how to increment "offset" to read the next line?


You could use

int count;
...
sscanf(file_bytes + offset, "%lf%lf%n", &x, &y, &count);
... error checking ...
offset += count;

Personally, I think it would be easier to use strtod().
PS> I looked in FAQs but didn't see anything to answer this question.

Thanks for checking before posting! Unfortunately, the F
in FAQ stands for "Frequently," not for "All" ;-)
 
L

lawrence.jones

I have an entire file stored in a string. The file is 2 columns of doubles (stored in ASCII, of course). The doubles are separated by an arbitrary number of spaces, maybe tabs too.

sscanf(file_bytes+offset, "%lf %lf", &x, &y) will return the number of "items" read, in this case 2 doubles.

I need to know how to increment "offset" to read the next line?

---John

PS> I looked in FAQs but didn't see anything to answer this question.


See the "%n" format specifier. You might find it more convenient to use
strtod() rather than sscanf().
 
K

Keith Thompson

Ben Pfaff said:
Keith Thompson said:
I have an entire file stored in a string. The file is 2 columns of
doubles (stored in ASCII, of course). The doubles are separated by an
arbitrary number of spaces, maybe tabs too.

sscanf(file_bytes+offset, "%lf %lf", &x, &y) will return the
number of "items" read, in this case 2 doubles.

I need to know how to increment "offset" to read the next line?


I don't think you can do that with sscanf; it doesn't tell you how many
characters it processed.


You can use %n.


Yes, good point.

strtod() is still a better tool for this job, though.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top