473,804 Members | 3,203 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

sscanf fixed-width integer question

Greetings,

I have a question about parsing a fixed-width integer from a string.

Lines of data are being read from a file having a very strict
column-delimited format. In my example below, columns 0-7 are an integer
and columns 8-23 are a float. In _most_ files, the first few columns of
the float are blank space to make it human readable. But not always.
So, once they have been read from the file, I try to parse out the
different values using something like the following:

/*------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>

int main()
{
char line1[]= " 12 15.796473824857 ";
char line2[]= " 1215.7964738248 571";
int id;
float num;

sscanf(line1, "%8d%16E", &id, &num);
printf("ID= %d\n", id);
printf("NUM= %f\n\n", num);

sscanf(line2, "%8d%16E", &id, &num);
printf("ID= %d\n", id);
printf("NUM= %f\n", num);

return EXIT_SUCCESS;
}
/*------------------------------------------*/

which works in one case and not the other.

I could read the first 8 columns as characters and strtol() them to an
integer. Is there another/better way?

Thanks,

Brent
Nov 14 '05 #1
8 4045
Brent Lievers wrote:
Greetings,

I have a question about parsing a fixed-width integer from a string.

Lines of data are being read from a file having a very strict
column-delimited format. In my example below, columns 0-7 are an integer
and columns 8-23 are a float. In _most_ files, the first few columns of
the float are blank space to make it human readable. But not always.
So, once they have been read from the file, I try to parse out the
different values using something like the following:

/*------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>

int main()
{
char line1[]= " 12 15.796473824857 ";
char line2[]= " 1215.7964738248 571";
int id;
float num;

sscanf(line1, "%8d%16E", &id, &num);
printf("ID= %d\n", id);
printf("NUM= %f\n\n", num);

sscanf(line2, "%8d%16E", &id, &num);
printf("ID= %d\n", id);
printf("NUM= %f\n", num);

return EXIT_SUCCESS;
}
/*------------------------------------------*/

which works in one case and not the other.

I could read the first 8 columns as characters and strtol() them to an
integer. Is there another/better way?


You could temporarily insert a '\0' at position 8 (after
first saving its value of course). Then sscanf() the int.
Subsequently restore the saved position 8, and sscanf() the
float from position 8.

Cheers,

Kees

Nov 14 '05 #2
- Kees van der Bent - wrote:
Brent Lievers wrote:
Greetings,

I have a question about parsing a fixed-width integer from a string.
Lines of data are being read from a file having a very strict
column-delimited format. In my example below, columns 0-7 are an integer
and columns 8-23 are a float. In _most_ files, the first few columns of
the float are blank space to make it human readable. But not always.
So, once they have been read from the file, I try to parse out the
different values using something like the following:

/*------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>

int main()
{
char line1[]= " 12 15.796473824857 ";
char line2[]= " 1215.7964738248 571";
int id;
float num;

sscanf(line1, "%8d%16E", &id, &num);
printf("ID= %d\n", id);
printf("NUM= %f\n\n", num);

sscanf(line2, "%8d%16E", &id, &num);
printf("ID= %d\n", id);
printf("NUM= %f\n", num);

return EXIT_SUCCESS;
}
/*------------------------------------------*/

which works in one case and not the other.

I could read the first 8 columns as characters and strtol() them to an
integer. Is there another/better way?

You could temporarily insert a '\0' at position 8 (after
first saving its value of course). Then sscanf() the int.
Subsequently restore the saved position 8, and sscanf() the
float from position 8.


By reversing the scan order (float first), you don't even have
to restore position 8.

Kees

Nov 14 '05 #3
Brent Lievers wrote:

Greetings,

I have a question about parsing a fixed-width integer from a string.

Lines of data are being read from a file having a very strict
column-delimited format. In my example below, columns 0-7 are an integer
and columns 8-23 are a float. In _most_ files, the first few columns of
the float are blank space to make it human readable. But not always.
So, once they have been read from the file, I try to parse out the
different values using something like the following:

/*------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>

int main()
{
char line1[]= " 12 15.796473824857 ";
char line2[]= " 1215.7964738248 571";
int id;
float num;

sscanf(line1, "%8d%16E", &id, &num);
printf("ID= %d\n", id);
printf("NUM= %f\n\n", num);

sscanf(line2, "%8d%16E", &id, &num);
printf("ID= %d\n", id);
printf("NUM= %f\n", num);

return EXIT_SUCCESS;
}
/*------------------------------------------*/

which works in one case and not the other.

I could read the first 8 columns as characters and strtol() them to an
integer. Is there another/better way?


The problem is with those leading blank spaces: the
"%8d" conversion swallows them *without* counting them
as part of the 8-character field width, so the 8-character
count begins with the first digit encountered. Since the
number of leading spaces (and other whitespace, like the
'\n' at the end of a preceding input line) is variable, you
don't know what field width to use to make the conversion
stop at the desired spot. I can think of no way to get this
to work with just one application of sscanf().

If I were doing this, I'd start by reading the entire line
into a buffer. Then I'd use strtod() to convert the second
number first. Then I'd stuff a '\0' into the buffer at the
eighth position and use strtol() to convert the first number.
(You could use sscanf() in place of both strxxx() functions,
if desired.)

By the way, what's the "%16E" conversion? I've assumed
above that it's something akin to "%16e", but if it's more
esoteric you may need something fancier than strtod() to
imitate it.

--
Er*********@sun .com
Nov 14 '05 #4
In <c6**********@k not.queensu.ca> Brent Lievers <3w**@qlink.que ensu.ca> writes:
I have a question about parsing a fixed-width integer from a string.

Lines of data are being read from a file having a very strict
column-delimited format. In my example below, columns 0-7 are an integer
and columns 8-23 are a float. In _most_ files, the first few columns of
the float are blank space to make it human readable. But not always.
So, once they have been read from the file, I try to parse out the
different values using something like the following:

#include <stdio.h>
#include <stdlib.h>

int main()
{
char line1[]= " 12 15.796473824857 ";
char line2[]= " 1215.7964738248 571";
int id;
float num;

sscanf(line1, "%8d%16E", &id, &num);


"%8d" means: skip any white space characters in the input, then convert
at most 8 digits. It's obvious that this is not going to work for line2,
as the conversion will stop at the decimal point.

To solve the problem, we need two sscanf calls and a char buffer for the
integer input:

char buff[8 + 1] = { 0 };

sscanf(line1, "%8c%16E", buff, &num);
sscanf(buff, "%d", &id); /* or id = atoi(buff); */

You may also want to check the return values of the sscanf calls, to be
sure that the input was OK and you're not propagating garbage into the
rest of the program.

Other solutions require an additional statement and destroy a byte of
input data (can be restored, if necessary), but may have a lower overall
overhead:

num = atof(line1 + 8);
line1[8] = 0;
id = atoi(line1);

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #5
Brent Lievers <3w**@qlink.que ensu.ca> wrote:
I have a question about parsing a fixed-width integer from a string.


<snip>

Thanks to everyone for your responses!

Brent
Nov 14 '05 #6
In <40************ ***@sun.com> Eric Sosman <Er*********@su n.com> writes:
By the way, what's the "%16E" conversion? I've assumed
above that it's something akin to "%16e", but if it's more
esoteric you may need something fancier than strtod() to
imitate it.


14 The conversion specifiers A, E, F, G, and X are also valid and
behave the same as, respectively, a, e, f, g, and x.

or, if you prefer the C89 version:

The conversion specifiers E, G, and X are also valid and behave
the same as, respectively, e, g, and x.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #7
Dan Pop wrote:

In <40************ ***@sun.com> Eric Sosman <Er*********@su n.com> writes:
By the way, what's the "%16E" conversion? I've assumed
above that it's something akin to "%16e", but if it's more
esoteric you may need something fancier than strtod() to
imitate it.


14 The conversion specifiers A, E, F, G, and X are also valid and
behave the same as, respectively, a, e, f, g, and x.

or, if you prefer the C89 version:

The conversion specifiers E, G, and X are also valid and behave
the same as, respectively, e, g, and x.


Aha! Thanks for the information. (Why do you suppose
the fprintf() description lists and describes the upper- and
lower-case specifiers together, while fscanf() shows only the
lower-case forms in the big list and relegates the upper-case
to a separate paragraph? Was the Committee trying to make a
point about the asymmetry of fprintf() and fscanf()?).

--
Er*********@sun .com
Nov 14 '05 #8
In <40************ ***@sun.com> Eric Sosman <Er*********@su n.com> writes:
Dan Pop wrote:

In <40************ ***@sun.com> Eric Sosman <Er*********@su n.com> writes:
> By the way, what's the "%16E" conversion? I've assumed
>above that it's something akin to "%16e", but if it's more
>esoteric you may need something fancier than strtod() to
>imitate it.


14 The conversion specifiers A, E, F, G, and X are also valid and
behave the same as, respectively, a, e, f, g, and x.

or, if you prefer the C89 version:

The conversion specifiers E, G, and X are also valid and behave
the same as, respectively, e, g, and x.


Aha! Thanks for the information. (Why do you suppose
the fprintf() description lists and describes the upper- and
lower-case specifiers together, while fscanf() shows only the
lower-case forms in the big list and relegates the upper-case
to a separate paragraph? Was the Committee trying to make a
point about the asymmetry of fprintf() and fscanf()?).


In fprintf, the behaviour is different. In fscanf, the behaviour is
identical, so fprintf and fscanf *are* assymetrical :-)

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
473
by: Allan Bruce | last post by:
If I have sscanf("FL:%s:%d:%s\n", lGuid, &lID, lFileName); and the last string contains spaces, e.g. my complete string "FL:1234ABCD:3:FileName With Spaces.txt\n" does sscanf just make lFileName the string up to the whitespace? even though I tell it the end of string as at the \n ? Thanks
4
1902
by: ishekara | last post by:
Hi, As per the msdn knowledge base.. i find the following "In an application developed with Microsoft C or C/C++, the sscanf() function is a good alternative to the atof() function to convert a string of digits into a floating-point number. If a string does not represent a valid number, atof() returns the value zero; sscanf() returns more useful error information. The application can use the error value from sscanf() with the...
12
8731
by: Simone Mehta | last post by:
hi All, I am parsing a CSV file. I want to read every row into a char array of reasonable size and then extract strings from it. <snippet> char foo="hello,world,bye,bye,world"; ..... sscanf(foo,"%s%*%s%*%s%*%s%*%s",s1,s2,s3,s4,s5); <snippet/> This is giving me junk .
10
5475
by: baumann | last post by:
hi, 1) first test program code #include <stdio.h> int main(void) { char * file = "aaa 23 32 m 2.23 ammasd"; int i2,i3;
4
2030
by: baumann | last post by:
hi all there has 2 program 1) the first test program code #include <stdio.h> int main(void) {
7
27017
by: nick | last post by:
is it similar to scanf? when i use scanf it can read the words in the screen automatically one after another.i use a char array to store the string,then use sscanf to read the words,but it just only reat out the first word in the string array every time. so if i want to read the words in the string one by one, just like scanf, what should i do? thanks!
9
2981
by: GrispernMix | last post by:
bool variant_t::Convert( fieldtype_t newType ) { if ( newType == fieldType ) { return true; } // // Converting to a null value is easy. //
8
2389
by: Artemio | last post by:
Dear folks, I need some help with using the sscanf() function. I need to parse a string which has several parameters given in a "A=... B=... C=..." way, and each has a different type (one is a text string, another is a decimal, next one is float, etc.). I have GCC 4.0.1 on Mac OS X Tiger. Here is an example of what I am trying to do.
5
3506
by: Alex Mathieu | last post by:
Hi, using sscanf, I'm trying to retrieve something, but nothing seems to work. Here's the pattern: SS%*sþ0þ%6s Heres the data: SS000000395000000000DC-þ0þ799829þ1174503725þ Actually, I would like to retrieve the "799829" from the data, but it always failed. I thought that the "%*sþ0þ" would work as if I was
7
11631
by: gio | last post by:
suppose I have: .... char str1; char str2; int ret; fgets(str1, LEN, stdin); //str1 can contain just '\n' and '\0' ret=sscanf(str1, "%s", str2); ....
0
9708
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10588
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10340
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10324
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10085
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7623
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5527
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5662
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3827
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.