473,321 Members | 1,667 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,321 software developers and data experts.

Parsing elements from a string

I'm obviously new to C, and have been trying different things to get
this done, but I'm at the end of the line and need some suggestions.

I am reading a string in from a user, in the form of a name, score,
and number of questions. It will be something like: Mark 98.2 20
all separated by spaces. I want to move each element into a temporary
variable so I can work with it, but thats where I'm running into
trouble. In a perfect world I would first move "Mark" to a variable,
work with it, then move "98.2", etc...

Any pointers or tips to methods, pages I might read, etc would be
appreciated. Thanks very much all.

Mark Miller

Nov 14 '05 #1
7 1438
I think sscanf() is what you are looking for.
Maybe something like this.
float score;

int numq;

char name[21];

char line[81];

gets(line);

sscanf(line,"%s %f %d",&name,&score,&numq);

HTH
--
Frane Roje

Have a nice day

Remove (*dele*te) from email to reply
"mi*****@westburyco.com" <Mark Miller> wrote in message
news:2t********************************@4ax.com...
I'm obviously new to C, and have been trying different things to get
this done, but I'm at the end of the line and need some suggestions.

I am reading a string in from a user, in the form of a name, score,
and number of questions. It will be something like: Mark 98.2 20
all separated by spaces. I want to move each element into a temporary
variable so I can work with it, but thats where I'm running into
trouble. In a perfect world I would first move "Mark" to a variable,
work with it, then move "98.2", etc...

Any pointers or tips to methods, pages I might read, etc would be
appreciated. Thanks very much all.

Mark Miller

Nov 14 '05 #2

"Frane Roje"
char name[21];
char line[81];

gets(line);
If you're going to use gets() then make the buffer at least 1000. This still
won't protect you from malicious overflows. Chuck Falconer's ggets() is a
drop in replacement.
sscanf(line,"%s %f %d",&name,&score,&numq);
Here you have the same problem, a name of over 20 characters will corrupt
memory. However you can get round this by adding a width specifier.
You also need to check the return value to make sure all fields were
converted.


Nov 14 '05 #3
"Malcolm" <ma*****@55bank.freeserve.co.uk> wrote in message
news:c7**********@newsg1.svr.pol.co.uk...

I just wanted to give an idea, so I appologize for any
mistakes in my solution 'cause it's intention was to give
an idea not a complete solution.

--
Frane Roje

Have a nice day

Remove (*dele*te) from email to reply
Nov 14 '05 #4
"mi*****@westburyco.com" wrote:

I'm obviously new to C, and have been trying different things to get
this done, but I'm at the end of the line and need some suggestions.

I am reading a string in from a user, in the form of a name, score,
and number of questions. It will be something like: Mark 98.2 20
all separated by spaces. I want to move each element into a temporary
variable so I can work with it, but thats where I'm running into
trouble. In a perfect world I would first move "Mark" to a variable,
work with it, then move "98.2", etc...

Any pointers or tips to methods, pages I might read, etc would be
appreciated. Thanks very much all.

Mark Miller


char string[] = "Mark 98.2 20";
char name[20+1];
double score;
int questions;
if (sscanf(string, "%20s %lf %d", name, &score, &questions) == 3) {
printf ("The name is %s\n", name);
printf ("The score is %f\n", score);
printf ("There are %d questions\n", questions);
}
else {
printf ("The input is indecipherable\n");
}

There are two important points to note here. First, you not
only apply sscanf() to the input string to pick apart the pieces,
but you also check that sscanf() actually found all three. This
defends against user input like "Mark Spitz 28.9 XX".

The second point has to do with the use of "%20s" instead
of the all-too-easy "%s". The problem with the latter is that
it will accept as much input as the user cares to type, even
if it's much too long for the name[] array:

"RumpelstiltskinTheMighty 98.2 20"

could cause considerable grief without such a check. It's not
altogether perfect, because the irascible dwarf might be upset
by having his name rendered as "RumpelstiltskinTheMi" and put a
curse on you ... Still, it's better than storing the five
characters "ghty" (do you see all five?) into non-existent places
and having completely unpredictable things happen.

sscanf() can be made to do more elaborate tricks, and there
are other approaches that don't use sscanf() at all -- but with
what I judge to be your current grasp of C, it might be better
to leave those for another day.

--
Er*********@sun.com
Nov 14 '05 #5
Eric Sosman wrote:
"mi*****@westburyco.com" wrote:

I am reading a string in from a user, in the form of a name,
score, and number of questions. It will be something like:
Mark 98.2 20 all separated by spaces. I want to move each
element into a temporary variable so I can work with it, but
thats where I'm running into trouble. In a perfect world I
would first move "Mark" to a variable, work with it, then
move "98.2", etc...

Any pointers or tips to methods, pages I might read, etc
would be appreciated. Thanks very much all.


char string[] = "Mark 98.2 20";
char name[20+1];
double score;
int questions;
if (sscanf(string, "%20s %lf %d", name, &score, &questions) == 3) {
printf ("The name is %s\n", name);
printf ("The score is %f\n", score);
printf ("There are %d questions\n", questions);
}
else {
printf ("The input is indecipherable\n");
}

There are two important points to note here. First, you not
only apply sscanf() to the input string to pick apart the pieces,
but you also check that sscanf() actually found all three. This
defends against user input like "Mark Spitz 28.9 XX".

The second point has to do with the use of "%20s" instead
of the all-too-easy "%s". The problem with the latter is that
it will accept as much input as the user cares to type, even
if it's much too long for the name[] array:

"RumpelstiltskinTheMighty 98.2 20"

could cause considerable grief without such a check. It's not
altogether perfect, because the irascible dwarf might be upset
by having his name rendered as "RumpelstiltskinTheMi" and put a
curse on you ... Still, it's better than storing the five
characters "ghty" (do you see all five?) into non-existent places
and having completely unpredictable things happen.

sscanf() can be made to do more elaborate tricks, and there
are other approaches that don't use sscanf() at all -- but with
what I judge to be your current grasp of C, it might be better
to leave those for another day.


Considering the OP's experience, your solution is probably the
most practical, but omits the problem of getting the line in the
first place, and how to recover from an error. The OP whould
under NO circumstances use gets(), regardless of recommendations
elsethread. Similarly, he should not be tempted to replace sscanf
with scanf, because error recovery will become a bear.

Even if sscanf succeeds in inputting various fields, there are
probably range and other validity checks to be applied. The
interactive programmers work is never done :-)

--
fix (vb.): 1. to paper over, obscure, hide from public view; 2.
to work around, in a way that produces unintended consequences
that are worse than the original problem. Usage: "Windows ME
fixes many of the shortcomings of Windows 98 SE". - Hutchison
Nov 14 '05 #6
"Frane Roje" <frane.roje(*dele*te)@st.htnet.hr> wrote:

[ Please do not top-post. ]
"mi*****@westburyco.com" <Mark Miller> wrote in message
news:2t********************************@4ax.com...
I am reading a string in from a user, in the form of a name, score,
and number of questions. It will be something like: Mark 98.2 20
all separated by spaces. I want to move each element into a temporary
variable so I can work with it, but thats where I'm running into
trouble. In a perfect world I would first move "Mark" to a variable,
work with it, then move "98.2", etc...
I think sscanf() is what you are looking for.
Maybe something like this.
Possibly sscanf() is what he wants, but this _certainly_ isn't it. You
are asking for trouble, the way you've done it.
float score;
int numq;
char name[21];
char line[81];

gets(line);
Never, ever, _ever_ use gets(). Not even for a throwaway, one-shot
program. Ever. It cannot be used safely. Yes, people may say "but I know
how I'm running my program, and I know that I'll never enter more than
80 characters, and I know that...". People like that are going to get
themselves electrocuted one day, because they know there isn't any
current on that pair of wires...
Besides, the only, very vague, advantage gets() may have over fgets() in
some eyes, the fact that you don't have to worry about any newline at
the end of the buffer, is negated by the use of sscanf(), anyway.

Use this instead:

fgets(line, sizeof line, stdin);
sscanf(line,"%s %f %d",&name,&score,&numq);


First of all, sscanf() using %s without any size limit is nearly as
dangerous as gets(). Nearly, because if you know that the string you
copy into is as large as the input buffer, you also know that you cannot
possibly overrun the output... but that isn't the case, here. What if
someone enters "Featheringstonehaughe 14.4 27"?
Moreover, %s only reads a single word. "Joannes Paulus II 3.0 -4" would
cause problems. Granted, this one is less simple to overcome; you'd need
to find the first float, or the last two tokens, and then read
everything up to that.
Also, &name is a pointer to an array of char, not a pointer to a char.
All you need is name; or if you think it's clearer, &name[0].

Another problem is that you do not check how many fields you read
succesfully. This may not seem a problem if you assume that all input is
perfect, but wait until someone enters "Jack", enter, "18.4", enter,
"12", enter, and see what happens if you try to use the resulting
scores. sscanf() returns a value; read it, and complain if it isn't what
you expected it to be.

Richard
Nov 14 '05 #7
On Tue, 04 May 2004 21:23:14 +0200, Frane Roje wrote:

gets(line);


Fools and those who have bought bad books use gets(). Everyone else uses
fgets() or the sadly nonstandard ggets().

No, I don't care /why/ you posted that code. I don't care how informal
it's supposed to be. It's crap, and it will only give students of the
language the wrong idea.

--
yvoregnevna gjragl-guerr gjb-gubhfnaq guerr ng lnubb qbg pbz
To email me, rot13 and convert spelled-out numbers to numeric form.
"Makes hackers smile" makes hackers smile.

Nov 14 '05 #8

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

Similar topics

0
by: marco | last post by:
I'm trying to parse a xml bookmarkpage with php. I found a very useful example script about how you can parse a xml document with php. The scriptworks really smooth. The xml test document (See...
16
by: Terry | last post by:
Hi, This is a newbie's question. I want to preload 4 images and only when all 4 images has been loaded into browser's cache, I want to start a slideshow() function. If images are not completed...
0
by: bj0011 | last post by:
I am trying to parse an XML file obtained from a public WebService (see below). This file does not seem to be loading into a .NET XmlDocument right (I think it is because of all of the <Item Name=""...
2
by: Mike | last post by:
Hi! I have an Excel 2003 Schema I need to parse to extract elements names. I am puzzled which System.Xml object can help me. Here's the example of my schema: I need to get a collection of...
3
by: GeRmIc | last post by:
How do you find if the returned XML string does not contain any record/elements? The XML string i receive just has the structure if there are not records, How do I check for this? <?xml...
6
by: giulianodammando | last post by:
In the development of a simple numerical simulation software i need to read some initialization parameters from a file that looks like: # Global Setup species = 1; \begin{specie}<1>...
3
by: toton | last post by:
Hi, I have some ascii files, which are having some formatted text. I want to read some section only from the total file. For that what I am doing is indexing the sections (denoted by .START in...
3
by: Anup Daware | last post by:
Hi Group, I am facing a strange problem here: I am trying to read xml response from a servlet using XmlTextWriter. I am able to read the read half of the xml and suddenly an exception:...
3
by: aspineux | last post by:
My goal is to write a parser for these imaginary string from the SMTP protocol, regarding RFC 821 and 1869. I'm a little flexible with the BNF from these RFC :-) Any comment ? tests= def...
3
by: raghudr | last post by:
Hi all, I am parsing a .xml file.My main intention is to retrieve the name value of node "Signal":- "Name Value" which is "rag". i want to store only the <signal"name value" that is only...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 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 former...

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.