473,748 Members | 2,672 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

getline - sort of

This must be a FAQ - or several FAQs - but I can't quite seem
to pin it down.

I need to read a string from stdin which I will then process as digits
with sscanf. I need to limit the # of chars read, and discard the
rest of the line. I also need to detect when more or fewer chars
are input. Something like GNU getline I guess.

Is there a standard portable way to do this w/a library function,
or do I just write it myself and process input a single char at
a time?

This must come up all the time. Sorry to be such a pinhead. Drivers
I can handle. User input, that another thing entirely...

Thanks,
Bill
--
William D Waddington
wi************* ***@beezmo.com
"Even bugs...are unexpected signposts on
the long road of creativity..." - Ken Burtch
Jan 16 '08 #1
20 2100

"Bill Waddington" <wi************ ****@beezmo.com wrote in message
This must be a FAQ - or several FAQs - but I can't quite seem
to pin it down.

I need to read a string from stdin which I will then process as digits
with sscanf. I need to limit the # of chars read, and discard the
rest of the line. I also need to detect when more or fewer chars
are input. Something like GNU getline I guess.

Is there a standard portable way to do this w/a library function,
or do I just write it myself and process input a single char at
a time?

This must come up all the time. Sorry to be such a pinhead. Drivers
I can handle. User input, that another thing entirely...
There's no really good way of getting an unbounded input line.

Probably if the input is line-delimited numbers, your best bet is to call
fgets() with a suitably over-lrage buffer.
Reject any input for which there is no trailing newline.
Then call strtod() to convert the .line to a number.

char buff[256];
double x;
char *end;

fgets(buff, 256, stdin);
if(!strchr(buff , "\n'))
{
evil person is passing you a bad line that is over long
}
x = strtod(buff, &end);
if(end == buff)
{
evil person passed a line that was not a number
}

at this point x holds the number, end the addfress of the last character
after it. You might discard, or process further.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Jan 16 '08 #2
Malcolm McLean wrote, On 16/01/08 17:39:
>
"Bill Waddington" <wi************ ****@beezmo.com wrote in message
>This must be a FAQ - or several FAQs - but I can't quite seem
to pin it down.

I need to read a string from stdin which I will then process as digits
with sscanf. I need to limit the # of chars read, and discard the
rest of the line. I also need to detect when more or fewer chars
are input. Something like GNU getline I guess.

Is there a standard portable way to do this w/a library function,
or do I just write it myself and process input a single char at
a time?

This must come up all the time. Sorry to be such a pinhead. Drivers
I can handle. User input, that another thing entirely...
There's no really good way of getting an unbounded input line.

Probably if the input is line-delimited numbers, your best bet is to
call fgets() with a suitably over-lrage buffer.
Since the OP has a requirement for an upper limit an overly large buffer
is *not* required. The OP needs a buffer of the correct size allowing
for the newline and /0 termination.
Reject any input for which there is no trailing newline.
Where did the OP say reject? The OP should use lack of a newline to
indicate too long a line and loop to discard the rest, and an early
newline to indicate too short a line.
Then call strtod() to convert the .line to a number.
Where did the OP specify a floating point number? I agree that the strto
functions are generally easier to use than sscanf but as the OP does not
mention decimal points or signs strtoul is more likely to be of use.
char buff[256];
Manifest constants are bad.
double x;
char *end;

fgets(buff, 256, stdin);
Here you repeat your manifest constant leading to a higher chance of
introducing bugs.

Either #define (or enum) the buffer size of use sizeof on the buffer (it
it will be the buffer not a pointer passed in, which seems likely.

Also fgets returns a value. Failure to check it means you will not know
if an end-of-file or error occurs, both of which *can* occur on stdin.
if(!strchr(buff , "\n'))
strchr takes the character as an int value, NOT a (pointer to) string.
Also the OP probably wants to use the value returned to find out how
long the line was. So that should be more like:
eolptr = strchr(buff,'\n ');
if (!eolptr)
{
evil person is passing you a bad line that is over long
Do a loop reading until you get either EOF or /n. I would use getc
rather than fgetc for this since it is intended to be a macro and
therefore makes the optimisers job easier.
}
else
linelen = eolptr-buf;
x = strtod(buff, &end);
if(end == buff)
{
evil person passed a line that was not a number
Or something that started with something other than white space or a
number. We do not know that this is invalid and it might be why the OP
wants to use sscanf.
}

at this point x holds the number, end the addfress of the last character
after it. You might discard, or process further.
Or it could contain an INF or NAN. Also errno should be checked (having
been zeroed prior to the call) so that overflow can easily be detected.
--
Flash Gordon
Jan 16 '08 #3
"Flash Gordon" <sp**@flash-gordon.me.ukwro te in message
>
>at this point x holds the number, end the addfress of the last character
after it. You might discard, or process further.

Or it could contain an INF or NAN. Also errno should be checked (having
been zeroed prior to the call) so that overflow can easily be detected.
That's why strtod is the better choice, unless you really need massive and
accurate integers.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Jan 16 '08 #4
On Wed, 16 Jan 2008 11:24:21 -0600, Bill Waddington wrote
(in article <s2************ *************** *****@4ax.com>) :
This must be a FAQ - or several FAQs - but I can't quite seem
to pin it down.

I need to read a string from stdin which I will then process as digits
with sscanf. I need to limit the # of chars read, and discard the
rest of the line. I also need to detect when more or fewer chars
are input. Something like GNU getline I guess.
Richard has this on his website, which seems to cover the general idea
pretty well, I suspect it might be helpful to you.

http://www.cpax.org.uk/prg/writings/fgetdata.php

--
Randy Howard (2reply remove FOOBAR)
"The power of accurate observation is called cynicism by those
who have not got it." - George Bernard Shaw

Jan 16 '08 #5
Malcolm McLean wrote, On 16/01/08 18:42:
"Flash Gordon" <sp**@flash-gordon.me.ukwro te in message
>>
>>at this point x holds the number, end the addfress of the last
character after it. You might discard, or process further.

Or it could contain an INF or NAN. Also errno should be checked
(having been zeroed prior to the call) so that overflow can easily be
detected.
That's why strtod is the better choice, unless you really need massive
and accurate integers.
You not using strtod properly is a reason why it should be used? Strange
argument. Anyway...

With strtod you need to check the end pointer, errno and *also* check
for INF and NAN (they can be explicitly supplied by the user and that
might not be flagged). If you only expect integers you *also* have to
check that the user entered an integer (entering 0.5 should in my
opinion not be considered correct). You also have to be concerned about
whether the range of exactly represented integers is large enough.

With strtoul you have to check the end pointer and errno. If the valid
range is smaller than unsigned long you also have to check the range.

Hmm, a description under half the length suggests to me that it is a LOT
simpler to use strtoul, strtoull, strtol or strtoll depending on valid
range.

Also you should note that strtoul etc are actually *designed* for
integers unlike strtod. It is generally best to use a tool designed for
the job when one is available rather than some other tool.
--
Flash Gordon
Jan 16 '08 #6

"Flash Gordon" <sp**@flash-gordon.me.ukwro te in message
Malcolm McLean wrote, On 16/01/08 18:42:
>"Flash Gordon" <sp**@flash-gordon.me.ukwro te in message
>>>
at this point x holds the number, end the addfress of the last
character after it. You might discard, or process further.

Or it could contain an INF or NAN. Also errno should be checked (having
been zeroed prior to the call) so that overflow can easily be detected.
That's why strtod is the better choice, unless you really need massive
and accurate integers.

You not using strtod properly is a reason why it should be used? Strange
argument. Anyway...

With strtoul you have to check the end pointer and errno. If the valid
range is smaller than unsigned long you also have to check the range.

Hmm, a description under half the length suggests to me that it is a LOT
simpler to use strtoul, strtoull, strtol or strtoll depending on valid
range.
If the user passes NAN or INF, it is an open question what the correct
behaviour should be. Having the double set to that value is a good start.
If he passes something non-numeric, endptr will pick it up.
>
Also you should note that strtoul etc are actually *designed* for integers
unlike strtod. It is generally best to use a tool designed for the job
when one is available rather than some other tool.
Generally, yes, you shoyuld, use functions as designed.

In fact strtol and related functions are driven more by the idea that data
is integers, becasue that's what the machine can crunch efficiently.
Generally data is numerical when it is not strings. It is easier to let
corrupt data be represented as massive flaoting point numbers which can then
be filtered out during sanity checks further down the line, rather than try
to build a parser for integers.

The exception might be super-safe applications where you don't want even the
remote chance that something like 10.000000000000 001 would be changed into
an integral 10 and accepted, when in fact you want to reject such input.
However needing that level of safety is rare.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
Jan 16 '08 #7
Bill Waddington wrote:
This must be a FAQ - or several FAQs - but I can't quite seem
to pin it down.

I need to read a string from stdin which I will then process as digits
with sscanf. I need to limit the # of chars read, and discard the
rest of the line. I also need to detect when more or fewer chars
are input. Something like GNU getline I guess.

Is there a standard portable way to do this w/a library function,
or do I just write it myself and process input a single char at
a time?

This must come up all the time. Sorry to be such a pinhead. Drivers
I can handle. User input, that another thing entirely...

Other responders seem to be pointing to solutions of a
related but different problem: Reading an entire line without
knowing how long it might be. Your task seems simpler, and
there's no need to commit canaricide with cannons.

Since you know an upper limit on the line length, you can
use a char array of the appropriate size (including room for
the '\n' and the '\0'), and read a line into it with fgets().
Then use strchr() to find the '\n' at the end of the line. If
a newline is found, fgets() got an entire line and the position
of the newline gives you its length. If not, the line was too
long and part of it remains unread, or else you've reached end-
of-input in a malformed file that lacks a '\n' at the end of its
final line. Either way, you can skip the rest of the line (or
detect the newline-less final line), by calling getc() or getchar()
in a loop until it returns '\n' or EOF.

--
Er*********@sun .com
Jan 16 '08 #8
On Wed, 16 Jan 2008 14:47:50 -0500, Eric Sosman <Er*********@su n.com>
wrote:
>Bill Waddington wrote:
>This must be a FAQ - or several FAQs - but I can't quite seem
to pin it down.

I need to read a string from stdin which I will then process as digits
with sscanf. I need to limit the # of chars read, and discard the
rest of the line. I also need to detect when more or fewer chars
are input. Something like GNU getline I guess.

Is there a standard portable way to do this w/a library function,
or do I just write it myself and process input a single char at
a time?

This must come up all the time. Sorry to be such a pinhead. Drivers
I can handle. User input, that another thing entirely...


Other responders seem to be pointing to solutions of a
related but different problem: Reading an entire line without
knowing how long it might be.
True. I know how long the useful input might be, but need to
allow for less or more and discard any extra input safely.
>Your task seems simpler, and there's no need to commit
canaricide with cannons.
>Since you know an upper limit on the line length, you can
use a char array of the appropriate size (including room for
the '\n' and the '\0'), and read a line into it with fgets().
Then use strchr() to find the '\n' at the end of the line. If
a newline is found, fgets() got an entire line and the position
of the newline gives you its length. If not, the line was too
long and part of it remains unread, or else you've reached end-
of-input in a malformed file that lacks a '\n' at the end of its
final line. Either way, you can skip the rest of the line (or
detect the newline-less final line), by calling getc() or getchar()
in a loop until it returns '\n' or EOF.
That, or just grind along w/getc() or getchar() from the start.

If I read all the suggestions correctly, the bottom line is code
it up or borrow it somewhere, but there isn't a single standard
lib way to do it.

Thanks to all,
Bill
--
William D Waddington
wi************* ***@beezmo.com
"Even bugs...are unexpected signposts on
the long road of creativity..." - Ken Burtch
Jan 16 '08 #9
Malcolm McLean wrote, On 16/01/08 19:16:
>
"Flash Gordon" <sp**@flash-gordon.me.ukwro te in message
>Malcolm McLean wrote, On 16/01/08 18:42:
>>"Flash Gordon" <sp**@flash-gordon.me.ukwro te in message

at this point x holds the number, end the addfress of the last
character after it. You might discard, or process further.

Or it could contain an INF or NAN. Also errno should be checked
(having been zeroed prior to the call) so that overflow can easily
be detected.

That's why strtod is the better choice, unless you really need
massive and accurate integers.

You not using strtod properly is a reason why it should be used?
Strange argument. Anyway...

With strtoul you have to check the end pointer and errno. If the valid
range is smaller than unsigned long you also have to check the range.

Hmm, a description under half the length suggests to me that it is a
LOT simpler to use strtoul, strtoull, strtol or strtoll depending on
valid range.
If the user passes NAN or INF, it is an open question what the correct
behaviour should be. Having the double set to that value is a good start.
If he passes something non-numeric, endptr will pick it up.
>>
Also you should note that strtoul etc are actually *designed* for
integers unlike strtod. It is generally best to use a tool designed
for the job when one is available rather than some other tool.
Generally, yes, you shoyuld, use functions as designed.

In fact strtol and related functions are driven more by the idea that
data is integers, becasue that's what the machine can crunch efficiently.
No, they are driven by the idea the there are a lot of situations where
you are dealing with integers.
Generally data is numerical when it is not strings.
I do a lot of interfacing with other systems. A lot of the time the
numbers are provided as integers (numbers of pennies etc.)
It is easier to let
corrupt data be represented as massive flaoting point numbers which can
then be filtered out during sanity checks further down the line, rather
than try to build a parser for integers.
You do not have to build a parser for integers, those nice library
writers have done the job for you.
The exception might be super-safe applications where you don't want even
the remote chance that something like 10.000000000000 001 would be
changed into an integral 10 and accepted, when in fact you want to
reject such input. However needing that level of safety is rare.
No, the exception is where the requirement is to accept an integer, and
this is a very common situation.
--
Flash Gordon
Jan 16 '08 #10

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

Similar topics

11
37913
by: John | last post by:
Hello all, I am trying to read in lines into a buffer from a file. Normally I would do this very low-level, but I have come to the conclusion I must stop doing everything the hard way. So, I thought I would try <fstream>. The code below causes an infinite loop in the while() statement. Debugging, I see that the buffer just has a 0 in the first position, and nothing else.
2
3556
by: Vikram | last post by:
Hi, I don't remember if it happened previously, but nowadays I'm having problem with using cin.getline function and cin>> function simultaneously. I have Visual Studio 6. If I use cin.getline function at first and then I use the cin>> function then the next time cin.getline function does not work.
5
7751
by: vknid | last post by:
Hello, I have a question. Its probably a very newbish question so please be nice hehe. =D I have been reading through C++ Programming Fundamentals, and have come a crossed an example program that shows how to use the 'getline' function. It said: "The getline function allows you to specify how many bytes you will get from the users input. Each character the user's types takes up one byte. So if, in the getline function, you specify...
1
2149
by: ma740988 | last post by:
Consider: ifstrem MyFile("extractMe.txt"); string Str; getline(MyFile, Str); getline above extracts the contents of MyFile and place into the string object. Deduced using FROM/TO logic I could state getline's first parameter supports "FROM". The second parameter supports "TO". // later
10
5617
by: Skywise | last post by:
I keep getting the following error upon compiling: c:\c++ files\programs\stellardebug\unitcode.h(677) : error C2664: 'class istream &__thiscall istream::getline(char *,int,char)' : cannot convert parameter 1 from 'const char *' to 'char *' Conversion loses qualifiers I have a data file called Standard.udf The Data File (not the problem): The data in the file is in text format, and was created using a function in this program with...
14
3885
by: KL | last post by:
I am so lost. I am in a college course for C++, and first off let me state I am not asking for anyone to do my assignment, just clarification on what I seem to not be able to comprehend. I have a ..txt file that I want to read into a multi-dimensional string array. Each line of the file needs to be read into the array. OK..sounds easy enough, but I can't get the getline(file_name array_name) to work. So...I am thinking it is definitely...
18
8253
by: Amadeus W. M. | last post by:
I'm trying to read a whole file as a single string, using the getline() function, as in the example below. I can't tell what I'm doing wrong. Tried g++ 3.2, 3.4 and 4.0. Thanks! #include <iostream> #include <fstream> #include <cstdlib> #include <string>
6
5294
by: Dave | last post by:
In .Net 2003 if a line, read from a text file is larger than a size parameter, the ifstream getline(buff, sze) put the file pointer to the EOF, so next peek() returns EOF. I saw this problem also when size was 2000 but line was 1200 bytes long. There is no such problem with .Net 2002 For .Net 2003 I used : #include <string> #include <fstream>
33
25221
by: Chen shuSheng | last post by:
I have a code: --------------------------- #include <iostream.h> #include <stdlib.h> int main() { int max=15; char line; getline(line,max); system("PAUSE");
3
25209
by: JackC | last post by:
Hi, How do i use stringstreams getline function to extract lines from an existing string? Say i have: string strlist = "line1\r\nLine2\r\nLine3\r\n"; I want to extract each line out into a vector array of strings, but i cant get stringstream working :(
0
8832
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 synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9381
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
9332
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
9254
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
6799
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
6078
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 into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4879
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3316
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
2
2791
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.