Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Understanding invalid user input

93 views
Skip to first unread message

Joseph Hesse

unread,
Nov 10, 2021, 3:50:58 AM11/10/21
to
/*
I am trying to understand the intricacies of invalid user input to a
statement like "cin >> x" where x is of some data type.
I wrote the following function, "PrintBuffer" to print the internal
buffer of cin.
Here is a run of the program

$ ./a.out
Enter Double
xx2.5yy
You entered x = 0
xx2.5yy
^C
$

It sort of worked, it showed the buffer but not the final newline and it
hung so I had to ^C to end the program.
My question is, how do I fix the function?

Thank you,
Joe
*/
================================================
#include <iostream>
using namespace std;

void PrintBuffer(istream &s)
{
cout << s.rdbuf() << "--" << endl;
}

int main()
{
double x{17.5};
cout << "Enter Double" << endl;
cin >> x;
cout << "You entered x = " << x << endl;
PrintBuffer(cin);
return 0;
}

Öö Tiib

unread,
Nov 10, 2021, 5:17:49 AM11/10/21
to
Posted program shouldn't produce described output. The "--" is clearly
missing from that. Maybe you run some other program or some
previous version of it that was designed to hung?

Ben Bacarisse

unread,
Nov 10, 2021, 6:11:06 AM11/10/21
to
嘱 Tiib <oot...@hot.ee> writes:

> On Wednesday, 10 November 2021 at 10:50:58 UTC+2, Joseph Hesse wrote:
>> /*
>> I am trying to understand the intricacies of invalid user input to a
>> statement like "cin >> x" where x is of some data type.
>> I wrote the following function, "PrintBuffer" to print the internal
>> buffer of cin.
>> Here is a run of the program
>>
>> $ ./a.out
>> Enter Double
>> xx2.5yy
>> You entered x = 0
>> xx2.5yy
>> ^C
>> $
>>
>> It sort of worked, it showed the buffer but not the final newline and it

It does show the newline, but they are hard to see! If the newline were
not being shown it, you'd see

$ ./a.out
Enter Double
xx2.5yy
You entered x = 0
xx2.5yy^C
$

>> hung so I had to ^C to end the program.

It's waiting for input. You can use ^D to close the input stream and
you will get the rest of the output.

>> My question is, how do I fix the function?

Hm... I don't think there is a well-defined way to see the content of
the internal buffer, but you can show the progress of the input in other
ways. For example using gcount().

>> Thank you,
>> Joe
>> */
>> ================================================
>> #include <iostream>
>> using namespace std;
>>
>> void PrintBuffer(istream &s)
>> {
>> cout << s.rdbuf() << "--" << endl;
>> }
>>
>> int main()
>> {
>> double x{17.5};
>> cout << "Enter Double" << endl;
>> cin >> x;
>> cout << "You entered x = " << x << endl;
>> PrintBuffer(cin);
>> return 0;
>> }
>
> Posted program shouldn't produce described output. The "--" is clearly
> missing from that. Maybe you run some other program or some
> previous version of it that was designed to hung?

I get the reported behaviour. After printing the stream buffer, the
program is waiting for input. Closing the input (usually ^D) causes
the -- to be output.

I can't see what cout << s.rdbuf() is defined to do. It appears
consumes input rather than simply printing the buffer contents.

--
Ben.

Bonita Montero

unread,
Nov 10, 2021, 9:11:53 AM11/10/21
to
Better use C++17's from_chars().

#include <iostream>
#include <charconv>
#include <utility>
#include <cstring>

using namespace std;

int main()
{
auto parseDouble = []( char const *str ) -> pair<bool, double>
{
double value;
from_chars_result fcr = from_chars( str, str + strlen( str ), value );
if( fcr.ec != errc() || *fcr.ptr )
return pair<bool, double>( false, 0.0 );
return pair<bool, double>( true, value );
};
cout << "enter value" << endl;
string dStr;
cin >> dStr;
pair<bool, double> pd = parseDouble( dStr.c_str() );
if( !pd.first )
{
cout << "invalid value" << endl;
return EXIT_FAILURE;
}
cout << "you entered: " << pd.second << endl;
}

Bonita Montero

unread,
Nov 10, 2021, 9:32:14 AM11/10/21
to
Better solution:

#include <iostream>
#include <charconv>
#include <utility>
#include <cstring>
#include <limits>

using namespace std;

int main()
{
auto parseDouble = []( string const &str ) -> double
{
double value;
from_chars_result fcr = from_chars( str.c_str(), str.c_str() + strlen(
str.c_str() ), value );
if( fcr.ec != errc() || *fcr.ptr )
return std::numeric_limits<double>::quiet_NaN();
return value;
};
cout << "enter value" << endl;
string dStr;
cin >> dStr;
double d = parseDouble( dStr );
if( isnan( d ) )
{
cout << "invalid value" << endl;
return EXIT_FAILURE;
}
cout << "you entered: " << d << endl;
}

Joseph Hesse

unread,
Nov 10, 2021, 10:16:18 AM11/10/21
to
It does produce the output I gave. I cut the program out of the
posting, compiled it with g++ and executed a.out. I am running Fedora
35 Linux.

Alf P. Steinbach

unread,
Nov 10, 2021, 11:21:04 AM11/10/21
to
When you parse the input string you can use `std::getline` instead of
`>>` formatted input.

Conversely, when you use `>>` you can let `>>` parse the input.

I see no advantage in both using `>>` and parsing the input.


- Alf

Dozi...@thekennel.co

unread,
Nov 10, 2021, 12:13:15 PM11/10/21
to
Or alternatively dump most of that over complicated crap and just use strtof()
C++ reinventing the wheel once aqain.

Bonita Montero

unread,
Nov 11, 2021, 1:33:27 AM11/11/21
to
Does it parse non-parseable values into a NaN ?

Bonita Montero

unread,
Nov 11, 2021, 1:36:40 AM11/11/21
to
How get parsing-errors signalled when using getline or operator >> ?


Juha Nieminen

unread,
Nov 11, 2021, 1:54:22 AM11/11/21
to
Joseph Hesse <jo...@gmail.com> wrote:
> using namespace std;

Out of curiosity, where did you learn to write that?

Joseph Hesse

unread,
Nov 11, 2021, 3:55:38 AM11/11/21
to
I don't remember where I first learned it. I've been writing C++
programs on and off for the last 20 years. In order to avoid writing
lots of "std::cout" kind of statements I use it. I wouldn't use it in
production code. The code I presented was just to test something.

Out of curiosity, why do you ask?

Dozi...@thekennel.co

unread,
Nov 11, 2021, 4:59:06 AM11/11/21
to
On Thu, 11 Nov 2021 07:33:09 +0100
Why not read the man page. You check the pointer return values instead, no
isnan() required.

Juha Nieminen

unread,
Nov 11, 2021, 6:42:29 AM11/11/21
to
Because I'm fascinated by what I find to be a rather odd psychological
aversion that many people have towards the "std::" prefix, usually for
no logical nor rational reason.

(And no, I'm not asking for your rationale or reasons. I have heard it
all a million times. Nothing is even close to convincing, sorry. I'm
just explaining what I find interesting about this.)

I'm also curious about how "using namespace std;" became so ubiquitous.
Why did its use spread like a wildfire, and persists to this day?
Where do people learn it? Why do people use it? Is it cargo cult
programming? Do people just see it being used in tutorials and examples,
and start repeating it with no second thought about it? Why does there
seem to be such a strong instinct to write that line in order to get
rid of the "std::" prefix? You see it all the time, and it just puzzles
me where this tidbit of habit comes from and how people learn it.

Perhaps the psychology behind it is closely related to the psychology
behind so many programmers using variable and function names that are
needlessly short to the point of being detrimental to the readability
and understandability of the code.

(I think one quintessential example of this is POSIX: If you look at
all the names, function names, macro names, variable names... defined
by POSIX, you'll notice a clear pattern of brevity over clarity in many
cases. Sure, POSIX itself is not really to blame here, because it simply
officially standardized what was an bunch of unofficial "standards",
and it just took most of the existing stuff as-is, without wanting to
change it, for backwards compatibility. However, regardless of who is
responsible for those names, it just quite clearly shows the
brevity-over-clarity psychology behind it.)

Bonita Montero

unread,
Nov 11, 2021, 7:04:07 AM11/11/21
to
I don't see any big difference when using strtof.
It would result in almost the same code.

Bonita Montero

unread,
Nov 11, 2021, 7:07:02 AM11/11/21
to
Am 11.11.2021 um 12:42 schrieb Juha Nieminen:

> Because I'm fascinated by what I find to be a rather odd psychological
> aversion that many people have towards the "std::" prefix, usually for
> no logical nor rational reason.

Writing using namespace std is ok ! People know std::'s symbols
and no library writer has his own symbols that collide with std::.

> I'm also curious about how "using namespace std;" became so ubiquitous.

You're compulsive and intolerant. It's just a matter of taste.

Juha Nieminen

unread,
Nov 11, 2021, 8:11:22 AM11/11/21
to
Bonita Montero <Bonita....@gmail.com> wrote:
> I don't see any big difference when using strtof.
> It would result in almost the same code.

Actually what strtof() accepts as input depends on the current locale,
while the input format of from_chars() is fixed and does not depend
on the locale.

This can seriously bite you in the posterior when you assume that,
for example, the decimal point of the ascii representation of the
number will be a '.'. The locale might change strtof() to assume
it's ',' instead, and you'll get weird results (where the
decimal part isn't parsed, and ends the parsing at the dot.)

Juha Nieminen

unread,
Nov 11, 2021, 8:16:38 AM11/11/21
to
Bonita Montero <Bonita....@gmail.com> wrote:
> Am 11.11.2021 um 12:42 schrieb Juha Nieminen:
>
>> Because I'm fascinated by what I find to be a rather odd psychological
>> aversion that many people have towards the "std::" prefix, usually for
>> no logical nor rational reason.
>
> Writing using namespace std is ok ! People know std::'s symbols
> and no library writer has his own symbols that collide with std::.

Using the std:: prefix make the code easier to understand.
For example, suppose you see this line of code:

if(equal(a, b, c))

do you know what function is that calling? If you don't happen to remember
if there's a standard library function with that name, you'll probably
think that it's some custom function, and you'll have no idea what kind
of parameters it's taking (and why it's taking three of them).

Contrast that with:

if(std::equal(a, b, c))

Now there's no doubt and no ambiguity. You know *exactly* where that
function is (in the standard library), even if you didn't know that such
a function exists in the standard library. If you do know the function,
then you'll also know that 'a', 'b' and 'c' there are some kind of
iterators, and you know what the function is doing. (Without that
knowledge you would have no idea what 'a', 'b' and 'c' are.)

All that just thanks to a little "std::" there.

> You're compulsive and intolerant. It's just a matter of taste.

Look who's talking.

Bonita Montero

unread,
Nov 11, 2021, 8:27:35 AM11/11/21
to
Am 11.11.2021 um 14:16 schrieb Juha Nieminen:
> Bonita Montero <Bonita....@gmail.com> wrote:
>> Am 11.11.2021 um 12:42 schrieb Juha Nieminen:
>>
>>> Because I'm fascinated by what I find to be a rather odd psychological
>>> aversion that many people have towards the "std::" prefix, usually for
>>> no logical nor rational reason.
>>
>> Writing using namespace std is ok ! People know std::'s symbols
>> and no library writer has his own symbols that collide with std::.
>
> Using the std:: prefix make the code easier to understand.

That's a matter of taste.

James Kuyper

unread,
Nov 11, 2021, 8:32:30 AM11/11/21
to
On 11/11/21 8:11 AM, Juha Nieminen wrote:
...
> Actually what strtof() accepts as input depends on the current locale,
> while the input format of from_chars() is fixed and does not depend
> on the locale.
>
> This can seriously bite you in the posterior when you assume that,
> for example, the decimal point of the ascii representation of the
> number will be a '.'. The locale might change strtof() to assume
> it's ',' instead, and you'll get weird results (where the
> decimal part isn't parsed, and ends the parsing at the dot.)

Or, you can get precisely the results you desire, if you're reading
digit strings in the format that's appropriate to the current locale.
The solution, as always, it to make sure that the current locale is the
correct one for what you're currently trying to do.

Paavo Helde

unread,
Nov 11, 2021, 9:13:44 AM11/11/21
to
This is not possible in general. The locale is process global, so it
will fail if I want to work with some human-readable data in current
user locale in one thread, and with some machine-readable fixed data
format in another thread.

Calling setlocale() in a multithreaded program after startup is
extremely problematic and will cause UB if another thread is executing
any locale-dependent function at the same time.

An option would be to use a stream with imbued locale, but this won't
work for things discussed here, like strtof().

In practice one should use functions like strtof() for locale-specific
things, and functions like from_chars() for fixed data formats. As an
extra bonus, the latter often work significantly faster.


james...@alumni.caltech.edu

unread,
Nov 11, 2021, 10:58:28 AM11/11/21
to
On Thursday, November 11, 2021 at 1:33:27 AM UTC-5, Bonita Montero wrote:
> Am 10.11.2021 um 18:12 schrieb Dozi...@thekennel.co:
...
> > Or alternatively dump most of that over complicated crap and just use strtof()
> > C++ reinventing the wheel once aqain.

The C++ standard defines std::stof() as calling std::strtof() when passed a narrow
string, and it defines std::num_get<>::do_get() as calling std::strtof() if the final
argument is a float. Therefore, C++ is not reinventing the wheel, it's re-using the
wheel invented by C.

> Does it parse non-parseable values into a NaN ?

That doesn't make sense - if it's non-parseable, how could it be parsed?

There's several different things that could prevent a string from being parsed. All
of them are reported back to the caller, one way or another. However, in none of
those cases is the value returned a NaN. A NaN is only returned when the
correct parse of that string indicates that the returned value should be a NaN.
C++ doesn't explain this directly, cross-referencing the C standard for it's
description of strtof():

"If the subject sequence is empty or does not have the expected form, no
conversion is performed; the value of nptr is stored in the object pointed to by
endptr , provided that endptr is not a null pointer." (7.22.1.5p7).

"If no conversion could be performed, zero is returned. If the correct value
overflows and default rounding is in effect (7.12.1), plus or minus ... HUGE_VALF
... is returned (according to the ... sign of the value), and the value of the macro
ERANGE is stored in errno . If the result underflows (7.12.1), the functions return
a value whose magnitude is no greater than the smallest normalized positive
number in the return type; whether errno acquires the value ERANGE is
implementation-defined." (7.22.1.5p10).

Bonita Montero

unread,
Nov 11, 2021, 11:06:54 AM11/11/21
to
Am 11.11.2021 um 16:58 schrieb james...@alumni.caltech.edu:
> On Thursday, November 11, 2021 at 1:33:27 AM UTC-5, Bonita Montero wrote:
>> Am 10.11.2021 um 18:12 schrieb Dozi...@thekennel.co:
> ...
>>> Or alternatively dump most of that over complicated crap and just use strtof()
>>> C++ reinventing the wheel once aqain.
>
> The C++ standard defines std::stof() as calling std::strtof() when passed a narrow
> string, and it defines std::num_get<>::do_get() as calling std::strtof() if the final
> argument is a float. Therefore, C++ is not reinventing the wheel, it's re-using the
> wheel invented by C.
>
>> Does it parse non-parseable values into a NaN ?
>
> That doesn't make sense - if it's non-parseable, how could it be parsed?

NaN might be a proper representation for invalid values depending on
what you're parsing.

Rest of your nonsense unread.

james...@alumni.caltech.edu

unread,
Nov 11, 2021, 1:09:09 PM11/11/21
to
On Thursday, November 11, 2021 at 11:06:54 AM UTC-5, Bonita Montero wrote:
> Am 11.11.2021 um 16:58 schrieb james...@alumni.caltech.edu:
> > On Thursday, November 11, 2021 at 1:33:27 AM UTC-5, Bonita Montero wrote:
...
> >> Does it parse non-parseable values into a NaN ?
> >
> > That doesn't make sense - if it's non-parseable, how could it be parsed?
> NaN might be a proper representation for invalid values depending on
> what you're parsing.

If it's not parseable, a parsing function other than strtof() might produce a NaN
anyway - but by definition it could not do so by parsing it, but only by recognizing it
as unparseable. However, as specified in the text I cited from the standard, that's not
what strtof() does with unparseable input - it's required to return 0.

strtof() can produce a NaN, but to make that happen you have to pass it a
parseable string starting with an optional + or - sign, and followed by either NAN
or NAN(n-char-sequence).
The n-char-sequence can carry an arbitrary mix of digits and nondigits.
Contrary from what you might conclude from the name. a nondigit is not defined as
"anything that isn't a digit". Rather, nondigits are defined by 6.2.4.1p2 as including only
' _', a-z or A-Z.

The n-char-sequence is used, in an implementation-defined way, to determine the
corresponding NaN payload, which can be retrieved using getpayload().

> Rest of your nonsense unread.

It's not nonsense - or at least, if it is nonsense, it's not mine. Most of that message
was simply a direct quote from the relevant standard. If you had bothered to read it,
it would have answered your question.

Bonita Montero

unread,
Nov 11, 2021, 1:27:33 PM11/11/21
to
Am 11.11.2021 um 19:08 schrieb james...@alumni.caltech.edu:
> On Thursday, November 11, 2021 at 11:06:54 AM UTC-5, Bonita Montero wrote:
>> Am 11.11.2021 um 16:58 schrieb james...@alumni.caltech.edu:
>>> On Thursday, November 11, 2021 at 1:33:27 AM UTC-5, Bonita Montero wrote:
> ...
>>>> Does it parse non-parseable values into a NaN ?
>>>
>>> That doesn't make sense - if it's non-parseable, how could it be parsed?
>> NaN might be a proper representation for invalid values depending on
>> what you're parsing.
>
> If it's not parseable, a parsing function other than strtof() might produce a NaN
> anyway - but by definition it could not do so by parsing it, but only by recognizing it
> as unparseable. However, as specified in the text I cited from the standard, that's not
> what strtof() does with unparseable input - it's required to return 0.
>
> strtof() can produce a NaN, but to make that happen you have to pass it a
> parseable string starting with an optional + or - sign, and followed by either NAN
> or NAN(n-char-sequence).
> The n-char-sequence can carry an arbitrary mix of digits and nondigits.
> Contrary from what you might conclude from the name. a nondigit is not defined as
> "anything that isn't a digit". Rather, nondigits are defined by 6.2.4.1p2 as including only
> ' _', a-z or A-Z.

strof() wouln't make a big difference.

Alf P. Steinbach

unread,
Nov 11, 2021, 2:48:10 PM11/11/21
to
> How get parsing-errors signalled when using getline […]

#include <iostream>
#include <charconv>
#include <optional>
#include <string>
#include <string_view>
using namespace std;

auto parse_double( const string_view s )
-> optional<double>
{
const auto p_begin = s.data();
const auto p_end = p_begin + s.size();
double value;
const from_chars_result fcr = from_chars( p_begin, p_end, value );
if( fcr.ec != errc() or fcr.ptr < p_end ) { return {}; }
return value;
}

int main()
{
cout << "Enter a number: " ;
string s;
getline( cin, s );
if( const optional<double> parsed = parse_double( s ) ) {
cout << "You entered: " << parsed.value() << endl;
return EXIT_SUCCESS;
}
cout << "Invalid value." << endl;
return EXIT_FAILURE;
}


> […] or operator >> ?

#include <ctype.h>

#include <charconv>
#include <limits>
#include <iostream>
#include <limits>
#include <optional>
using namespace std;

auto input_double()
-> optional<double>
{
double value;
cin >> value;
const bool ok = (not cin.fail()) and ::isspace(cin.peek());
cin.clear();
return (ok? optional<double>( value ) : nullopt);
};

int main()
{
cout << "Enter a number: " ;
if( const optional<double> parsed = input_double() ) {
cout << "You entered: " << parsed.value() << endl;
return EXIT_SUCCESS;
}
cout << "Invalid value." << endl;
return EXIT_FAILURE;
}


As presented the only difference is that with `getline` one deals with
and consumes one line of input at a time, whereas with `>>` one deals
with and consumes one whitespace-separated "word" of input at a time.

However, when code maintenance introduces a little `setlocale` the
`getline` + `from_chars` parsing will still use '.' as fractional part
delimiter, whereas the `>>` code may then use ',' as delimiter. Which is
part of the reason for C++17 introduction of `from_chars`.

So, it's not perfect.


- Alf

Mike Terry

unread,
Nov 11, 2021, 3:35:42 PM11/11/21
to
Maybe you've misunderstood what rdbuf() is doing. It returns a pointer
to the stream's (cin's) internal basic_streambuf object. When you pipe
this to cout, effectively you are copying one stream (stdin) to the
other (stdout). Characters will be read from the basic_streambuf and
written to cout, continuing until EOF is encountered. (I.e. the
basic_streambuf represents the full stream from stdin, not just some
portion which is currently in memory...)

So that explains why the program hangs - it's waiting for more input.
Also that's why you don't see the "--" or final newline. You could
enter control-Z to terminate stdin, and you'd see the missing output,
but that's probably not what you want.

Others have suggested what is mostly alternative ways of parsing stuff.
If you want to pursue your original intention, just fixing the bug, then
you don't want to pipe the whole stdin stream into cout! One approach
would be to read one line of input to a string, then create a
istringstream on the string buffer for testing your extract operations.
The end of the istringstream stream occurs at the end of the string. E.g.

================================================
#include <iostream>
using namespace std;

void PrintBuffer(istream &s)
{
cout << s.rdbuf() << "--" << endl;
}

int main()
{
double x{17.5};
cout << "Enter Double" << endl;
string s;
cin >> s;
istringstream istr (s);
istr >> x;
cout << "You entered x = " << x << endl;
PrintBuffer(istr);
return 0;
}
================================================


Mike.

Öö Tiib

unread,
Nov 11, 2021, 5:12:45 PM11/11/21
to
On Thursday, 11 November 2021 at 13:42:29 UTC+2, Juha Nieminen wrote:
>
> I'm also curious about how "using namespace std;" became so ubiquitous.
> Why did its use spread like a wildfire, and persists to this day?
> Where do people learn it? Why do people use it? Is it cargo cult
> programming? Do people just see it being used in tutorials and examples,
> and start repeating it with no second thought about it? Why does there
> seem to be such a strong instinct to write that line in order to get
> rid of the "std::" prefix? You see it all the time, and it just puzzles
> me where this tidbit of habit comes from and how people learn it.

It is so as Bjarne Stroustrup teached that with his examples from day he
added namespaces into C++ programming language .
Now Bjarne's coding guidelines suggest narrowing the usage of it somewhat ...
<http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rs-using>
... but no one apparently reads that.

Additionally there now are innumerable "competitive programming sites"
like TopCoder, CodeForces, CodeChef, CodeGolf where C++ participants
habitually start their works with two lines:

#include <bits/stdc++.h>
using namespace std;


Juha Nieminen

unread,
Nov 12, 2021, 2:26:47 AM11/12/21
to
Öö Tiib <oot...@hot.ee> wrote:
> It is so as Bjarne Stroustrup teached that with his examples from day he
> added namespaces into C++ programming language .

I suppose that explains a lot.

Alf P. Steinbach

unread,
Nov 12, 2021, 4:41:39 AM11/12/21
to
`using namespace std;` is commonly used because it's practical for small
programs; a work saver.

Adoption of that practice in other cases, e.g. in the global namespace
in a header, happens because people use simple behavior patterns without
understanding them. Much like applying the brakes after driving at high
speed into a hairpin turn. Nowadays car automation (ABS) may prevent the
most serious consequences, but that wasn't so when I learned to drive.

One can argue that such people should not be coding in C++, and I
believe that Bjarne originally assumed that such people would not be
coding in C++. Maybe that C++ users would be like the programmers he
knew at AT&T Bell Labs. But the language became just too popular,
analogous to the eternal September of Usenet.

- Alf

wij

unread,
Nov 12, 2021, 5:53:20 AM11/12/21
to
To understand the intricacies of invalid user input, you have to define your own.

The standard ones from C/C++ are almost not suitable for commercial programs.
The only useful cases are writing small demo. programs (except programs that
are 'defined' to use stream i/o).
If you mean testing for iostream, IMO, work/burden is super heavy, reward is little.

Manfred

unread,
Nov 12, 2021, 11:21:31 AM11/12/21
to
Agreed,
Also considering that when writing a book the choice of the audience
impacts the contents of the book.
In other words, if Bjarne had written the book as a sort of C++ for
dummies, then it wouldn't have been of much use or interest for
professional programmers.

Jorgen Grahn

unread,
Nov 13, 2021, 3:20:47 AM11/13/21
to
On Thu, 2021-11-11, Paavo Helde wrote:
> 11.11.2021 15:32 James Kuyper kirjutas:
>> On 11/11/21 8:11 AM, Juha Nieminen wrote:
>> ...
>>> Actually what strtof() accepts as input depends on the current locale,
>>> while the input format of from_chars() is fixed and does not depend
>>> on the locale.
>>>
>>> This can seriously bite you in the posterior when you assume that,
>>> for example, the decimal point of the ascii representation of the
>>> number will be a '.'. The locale might change strtof() to assume
>>> it's ',' instead, and you'll get weird results (where the
>>> decimal part isn't parsed, and ends the parsing at the dot.)

There's also the difference between what the locale says and what
users really expect. Here in LC_NUMERIC=sv_SE, pi is officially
written 3,14:

% LC_NUMERIC=sv_SE printf "%f\n" 3.14159265
3,141593

But noone writes it that way when the context is computing or
engineering. It's not just programmers who expect to write 3.14 in
their programs: almost /anyone/ using a computer or even a pocket
calculator expect to see a dot.

I still feel the locale system, as designed, was a mistake. But it's
too late to do anything about it, except adding locale-less interfaces
like we see here.

...
> In practice one should use functions like strtof() for locale-specific
> things, and functions like from_chars() for fixed data formats. As an
> extra bonus, the latter often work significantly faster.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Jorgen Grahn

unread,
Nov 20, 2021, 5:12:10 PM11/20/21
to
On Fri, 2021-11-12, Juha Nieminen wrote:
I don't know: I don't see lots of people read his books[1].

I also don't think he ever taught 'using namespace std' ... but The
C++ Programming Language examples /do/ omit the prefix, and perhaps it
doesn't explain clearly why.

/Jorgen

[1] Except me. I like his writing and I think I'm heavily influenced
by his style, which I find blends well with Unix styles.

Ben Bacarisse

unread,
Nov 20, 2021, 5:31:27 PM11/20/21
to
Jorgen Grahn <grahn...@snipabacken.se> writes:

> On Fri, 2021-11-12, Juha Nieminen wrote:
>> ?? Tiib <oot...@hot.ee> wrote:
>>> It is so as Bjarne Stroustrup teached that with his examples from day he
>>> added namespaces into C++ programming language .
>>
>> I suppose that explains a lot.
>
> I don't know: I don't see lots of people read his books[1].
>
> I also don't think he ever taught 'using namespace std' ... but The
> C++ Programming Language examples /do/ omit the prefix, and perhaps it
> doesn't explain clearly why.

The two Stroustrup books I have on C++ pre-date namespaces. Maybe
"using namespace std" was a simple way to avoid re-writing lots of
examples? Even if he was scrupulous in updating his examples, I bet
many course notes and online tutorial that spanned that period in the
language's evolution just took the easy option!

--
Ben.

Jorgen Grahn

unread,
Nov 20, 2021, 5:32:58 PM11/20/21
to
On Thu, 2021-11-11, Juha Nieminen wrote:
...

[avoiding std::. You may remember that I agree here, so won't comment.]

> Perhaps the psychology behind it is closely related to the psychology
> behind so many programmers using variable and function names that are
> needlessly short to the point of being detrimental to the readability
> and understandability of the code.
>
> (I think one quintessential example of this is POSIX: If you look at
> all the names, function names, macro names, variable names... defined
> by POSIX, you'll notice a clear pattern of brevity over clarity in many
> cases. Sure, POSIX itself is not really to blame here, because it simply
> officially standardized what was an bunch of unofficial "standards",
> and it just took most of the existing stuff as-is, without wanting to
> change it, for backwards compatibility. However, regardless of who is
> responsible for those names, it just quite clearly shows the
> brevity-over-clarity psychology behind it.)

YMMV. I find the POSIX names ("len" instead of "length" and so on)
help clarity, just like the one-character names in science.

Like I think I've said before, I think it's a matter of your
background, and perhaps of how your brain is wired.

I wish it was easier to rewire. For example, I cannot learn to
ignore hungarian notation. I can see a namespace "NLog", and even
after several years of seeing these, I have to stop and think before
my brain can accept that this is really the Log namespace -- not a
namespace for some special N Log, where N stands for "Native", or
"Neutron", or "Natural number" or something.

/Jorgen

Manfred

unread,
Nov 20, 2021, 10:52:11 PM11/20/21
to
On 11/20/2021 11:11 PM, Jorgen Grahn wrote:
> On Fri, 2021-11-12, Juha Nieminen wrote:
>> ?? Tiib <oot...@hot.ee> wrote:
>>> It is so as Bjarne Stroustrup teached that with his examples from day he
>>> added namespaces into C++ programming language .
>>
>> I suppose that explains a lot.
>
> I don't know: I don't see lots of people read his books[1].

I don't know how many read his books, I have met several who, unlike me,
question his programming style, though.

>
> I also don't think he ever taught 'using namespace std' ... but The
> C++ Programming Language examples /do/ omit the prefix, and perhaps it
> doesn't explain clearly why.
>
> /Jorgen
>
> [1] Except me. I like his writing and I think I'm heavily influenced
> by his style, which I find blends well with Unix styles.
>

I like it too, TC++PL has the occasional mistake here and there, but all
in all there's no question it's a pretty good book, I believe.
0 new messages