473,563 Members | 2,805 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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 1453
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,&scor e,&numq);

HTH
--
Frane Roje

Have a nice day

Remove (*dele*te) from email to reply
"mi*****@westbu ryco.com" <Mark Miller> wrote in message
news:2t******** *************** *********@4ax.c om...
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,&scor e,&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.u k> wrote in message
news:c7******** **@newsg1.svr.p ol.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*****@westbu ryco.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:

"Rumpelstiltski nTheMighty 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 "Rumpelstiltski nTheMi" 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*****@westbu ryco.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:

"Rumpelstiltski nTheMighty 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 "Rumpelstiltski nTheMi" 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(*de le*te)@st.htnet .hr> wrote:

[ Please do not top-post. ]
"mi*****@westbu ryco.com" <Mark Miller> wrote in message
news:2t******** *************** *********@4ax.c om...
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,&scor e,&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 "Featheringston ehaughe 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
1575
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 ‘Testxml' beneath) is parsed correctly and with the php sniplet: $counting=count($xmlC->obj_data->DATA->IP_RECORD); //to find out the number of...
16
2869
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 loaded into cache, the slideshow doesn't look very nice. I am not sure how/when to call the slideshow() function to make sure it starts after...
0
1393
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="" Type=""></Item> elements). I need to get out the data for the <Id/>, Name="Authors", Name="Title", and Name="PubDate" elements. Anyone have an idea...
2
1691
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 element names(TemplateB62,TemplateC62 ......) <?xml version='1.0' encoding='UTF-8'?> <xsd:schema targetNamespace="http://tempuri.org/XMLSchema.xsd"...
3
1875
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 version="1.0" encoding="UTF-8"?> <array-list xsi:type="java:java.util.ArrayList" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
6
2304
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> name = NITROGEN;
3
4367
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 the file) with the location. And for a particular section I parse only that section. The file is something like, .... DATAS
3
3300
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: “Unexpected end of file while parsing Name has occurred” isbeing thrown. Following is the part o xml I am trying to read: <CHECK_ITEM_OUT>
3
2692
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 RN(name, regex): """protect using () and give an optional name to a regex""" if name:
3
1665
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 "rag" ,"rock","yahoo"to my list. I do not want to add any <subsignals"name value" to the list.i want
0
7665
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...
0
7583
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7888
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. ...
0
7950
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...
0
5213
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3643
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...
0
3626
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2082
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
0
924
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

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.