- converting a string containing a comma to a number - 12 Updates
- enum initialization - 10 Updates
- enum initialization - 3 Updates
Lynn McGuire <lynnmcguire5@gmail.com>: Nov 09 08:10PM -0600 On 11/9/2017 8:07 PM, Lynn McGuire wrote: > number ? atof and strtod do not work with the comma. > Thanks, > Lynn A string such as 4,800.1 or 3,334.5e9. Thanks, Lynn |
Lew Pitcher <lew.pitcher@digitalfreehold.ca>: Nov 09 10:17PM -0500 Stefan Ram wrote: > #include <iostream> > #include <ostream> > #include <string> Thanks for the C++ example. but, do you have anything in C? -- Lew Pitcher "In Skills, We Trust" PGP public key available upon request |
Alain Ketterlin <alain@universite-de-strasbourg.fr.invalid>: Nov 10 12:38PM +0100 >> Thanks, >> Lynn > A string such as 4,800.1 or 3,334.5e9. Any of atof, strtod, sscanf will happily convert this, *provided* the locale is setup correctly. Check setlocale (std::setlocale), especially the LC_NUMERIC category. See also https://stackoverflow.com/questions/28470656/convert-string-with-thousands-and-decimal-separator-into-double -- Alain. |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Nov 10 02:06PM On 10/11/2017 02:52, Stefan Ram wrote: > { ::std::string s { source }; > s.replace( 1, 1, ""s ); > return s; } Your use of the namespace scoping operator is egregious; ::std is totally unnecessary. Your solution is also non-optimal as it unnecessarily passes by reference: std::string replace(std::string source, const std::string& a, const std::string& b) { source.replace(...); return source; } /Flibble |
scott@slp53.sl.home (Scott Lurndal): Nov 10 02:16PM > IIRC, An implementation of C is not required to support > other locales than the "C" locale, so any code based on > any other locale would not be portable. That would seem to be a total non-sequitor. Every POSIX implementation supports it. If windows doesn't, then switch to posix. |
"James R. Kuyper" <jameskuyper@verizon.net>: Nov 10 09:31AM -0500 On 2017-11-10 06:38, Alain Ketterlin wrote: > Any of atof, strtod, sscanf will happily convert this, *provided* the > locale is setup correctly. Check setlocale (std::setlocale), especially > the LC_NUMERIC category. The C standard provides an official definition of the "decimal-point character", explicitly identifying it as locale-specific, and frequently uses that term when describing the behavior of the functions which convert between floating point numbers and their representations as strings. In particular, strtod() recognizes "a nonempty sequence of decimal digits optionally containing a decimal-point characters, then an optional exponent..." (7.22.1.3p3). However, none of the other members of struct lconv are mentioned anywhere in the standard other than the part describing <locale.h>. For none of those members is there any function in the C standard library whose defined behavior requires it to pay attention to the value of that member in the current locale. The decimal-point character is the only member of that struct for which there's a corresponding item listed in section J.4, which summarizes locale-specific behavior. It is apparently up to the user to write code whose behavior depends upon those values. Note, in particular, that the description of strtod() above makes no mention of the thousands_sep or grouping members of struct lconv. The behavior of atof() and sscanf() are both defined in terms of calls to strtod(), so the same is true of them. > See also > https://stackoverflow.com/questions/28470656/convert-string-with-thousands-and-decimal-separator-into-double C++ differs from C in that there are C++ standard library routines that do have behavior that depend upon values of thousands_sep and grouping in the currently imbued locale, and that link shows how to take advantage of that fact. Note, in particular, that even in C++, std::strtod(), std::atof(), and std::sscanf() are NOT examples of this. Their behavior is the same as the C standard library versions of those routines in this regard. |
legalize+jeeves@mail.xmission.com (Richard): Nov 10 05:54PM [Please do not mail me a copy of your followup] Lew Pitcher <lew.pitcher@digitalfreehold.ca> spake the secret code >> #include <ostream> >> #include <string> >Thanks for the C++ example. but, do you have anything in C? If you want a C example, why are you asking in a C++ newsgroup? Followups redirected back to comp.lang.c++ -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Terminals Wiki <http://terminals-wiki.org> The Computer Graphics Museum <http://computergraphicsmuseum.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
"James R. Kuyper" <jameskuyper@verizon.net>: Nov 10 01:14PM -0500 On 2017-11-10 12:54, Richard wrote: > [Please do not mail me a copy of your followup] > Lew Pitcher <lew.pitcher@digitalfreehold.ca> spake the secret code > <ou35oo$2tf$1@dont-email.me> thusly: ... >> Thanks for the C++ example. but, do you have anything in C? > If you want a C example, why are you asking in a C++ newsgroup? Because the OP (Lynn McGuire) posted to both newsgroups, presumably because Lynn was looking for both a C and a C++ solution (possibly hoping that a single solution might exist that will work in both languages). > Followups redirected back to comp.lang.c++ Followups restored as originally specified. |
jacobnavia <jacob@jacob.remcomp.fr>: Nov 10 09:22PM +0100 Le 10/11/2017 à 03:10, Lynn McGuire a écrit : > A string such as 4,800.1 or 3,334.5e9. > Thanks, > Lynn void EliminateComma(char *src) { char *dst = src; while (*src) { if (*src != ',') *dst++ = *src; src++; } *dst=0; } |
Ben Bacarisse <ben.usenet@bsb.me.uk>: Nov 10 08:44PM I'm just picking a pace to comment really... > } > *dst=0; > } Removing commas, either in place or in a copy, is probably how I'd do this too, but it's also possible that it is not at all what is needed. For example, the input might include other commas that have to be preserved, or the removal of all commas allows input to be parsed which should be treated as an error. Without knowing more about the overall requirement it's hard to give good advice. -- Ben. |
Keith Thompson <kst-u@mib.org>: Nov 10 01:14PM -0800 > } > *dst=0; > } This might be a good first step *if* you don't mind modifying the original string in place. -- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> Working, but not speaking, for JetHead Development, Inc. "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" |
jacobnavia <jacob@jacob.remcomp.fr>: Nov 10 10:22PM +0100 Le 10/11/2017 à 22:14, Keith Thompson a écrit : > This might be a good first step*if* you don't mind modifying the > original string in place. If you do mind, make a copy before... not rocket sicence isn't it? |
Paavo Helde <myfirstname@osa.pri.ee>: Nov 10 01:27AM +0200 On 9.11.2017 22:23, JiiPee wrote: > Thanks, but just thinking another thing: is is a good idea at all using > enums as (option) flags? I read some say online that should use > constants instead. In my experience, enums are much better than static constant integer data members in a class. The latter sometimes require a separate definition outside of the class, which is a hassle. And "sometimes" means depending on the usage of the constant, the compiler, the compiler version and the compiler optimization flags, making this approach pretty fragile. Actually it is very easy to define an enum with bit flag values: enum flags: std::uint8 { A = (1<<0), B = (1<<1), C = (1<<2), // ... }; Also, the bitflags are typically combined, and with the enum approach the result is still legally representable in the same enum type, making this more encapsulated (especially with 'enum class'). With separate integer constants there is no separate type and the compiler does not even warn you if you try to combine incompatible constants. A drawback of bitflag enums is that one also needs to define several one-liners like operator|, operator& for each such enum type for using them smoothly. I believe the new meta-language features will make this a bit easier in the future. hth Paavo |
Xiao Liang <shaw.leon@gmail.com>: Nov 09 06:25PM -0800 在 2017年11月10日星期五 UTC+8上午3:41:47,JiiPee写道: > with a function or something (reducing human error). > Or the only way to do it is to hardcode like that? > I need this in my flags system where I need values 1,2,4,8,16,... Use macro: enum class MyOpt { #define OPT(n) opt ## n = 1 << n OPT(0), OPT(1), OPT(2), OPT(3) #undef OPT }; Or if you have complex initializer: #define OPT(n) opt ## n = opt_value(n) constexpr int opt_value(int n) { if (n == 0) { return 1; } return 2 * opt_value(n - 1); } |
Xiao Liang <shaw.leon@gmail.com>: Nov 09 06:28PM -0800 On Friday, November 10, 2017 at 3:41:47 AM UTC+8, JiiPee wrote: > with a function or something (reducing human error). > Or the only way to do it is to hardcode like that? > I need this in my flags system where I need values 1,2,4,8,16,... Use macro: enum class MyOpt { #define OPT(n) opt ## n = 1 << n OPT(0), OPT(1), OPT(2), OPT(3) #undef OPT }; Or if you have complex initializer: #define OPT(n) opt ## n = opt_value(n) constexpr int opt_value(int n) { if (n == 0) { return 1; } return 2 * opt_value(n - 1); } |
"Öö Tiib" <ootiib@hot.ee>: Nov 09 08:18PM -0800 On Thursday, 9 November 2017 21:41:47 UTC+2, JiiPee wrote: > with a function or something (reducing human error). > Or the only way to do it is to hardcode like that? > I need this in my flags system where I need values 1,2,4,8,16,... If you there are lot of flags (more than 16 and growing) then life has shown that using enum may complicate your future. Use std::bitset as such flag system and keep the enum as index of a flag in it (IOW defaults 0,1,2,3 ...). When there are less flags that unlikely will grow over time then do not overthink it. Either use explicit decimals (1, 2, 4, 8, 16, 32, ...) or hexadecimal (0x01, 0x02, 0x04, 0x08, 0x10, 0x20, ...) or bit shifts (1 << 0, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, ...). It is purely aesthetic preference since every of those will work fine. |
scott@slp53.sl.home (Scott Lurndal): Nov 10 01:44PM >means depending on the usage of the constant, the compiler, the compiler >version and the compiler optimization flags, making this approach pretty >fragile. It's only fragile if one doesn't _always_ add the separate definition as a rule. Prior to typed enums, static const members were the only way to specify unsigned 64-bit constants due to the default int type for enums. Unfortunatly, some of us are unable to take advantage of C++11 and beyond due to circumstances outside of our control and must live with static const members. |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Nov 10 02:07PM On 09/11/2017 20:07, James R. Kuyper wrote: >> Yes I can do it manually, but I would like to do it automatically maybe > This is about as close as you can get to doing it automatically: > enum class MyOpt {opt1=1, opt2, opt3=opt2*2, opt4=opt3*2}; Egregious. opt2=opt1*2 /Flibble |
"Öö Tiib" <ootiib@hot.ee>: Nov 10 06:12AM -0800 On Friday, 10 November 2017 15:45:15 UTC+2, Scott Lurndal wrote: > Unfortunatly, some of us are unable to take advantage of C++11 and > beyond due to circumstances outside of our control and must live with > static const members. Unfortunately there always will be new platform vendors who make some sort of Crap++ compiler instead of standard one and then call it C++ and even ask money for it. For example from Arduino or Texas Instruments one will get such trash. |
"James R. Kuyper" <jameskuyper@verizon.net>: Nov 10 10:03AM -0500 On 2017-11-10 09:07, Mr Flibble wrote: >> enum class MyOpt {opt1=1, opt2, opt3=opt2*2, opt4=opt3*2}; > Egregious. > opt2=opt1*2 I'm simply taking advantage of the default, which is that opt2=opt1+1, which in this case is exactly the same as opt2=opt1*2. I expect any reader of my code to be familiar with that default. Perhaps I'm setting my expectations too high? |
scott@slp53.sl.home (Scott Lurndal): Nov 10 03:09PM >some sort of Crap++ compiler instead of standard one and then >call it C++ and even ask money for it. For example from Arduino or >Texas Instruments one will get such trash. In our case, it is dependence upon third-party object libraries that require certain versions of gcc that don't fully support C++11 and beyond. That's ok with me; the only features from C++11+ that I'd be interested in are typed enums and static_assert. |
Gareth Owen <gwowen@gmail.com>: Nov 10 05:00PM > I'm simply taking advantage of the default, which is that opt2=opt1+1, > which in this case is exactly the same as opt2=opt1*2. I expect any > reader of my code to be familiar with that default. So you've a potential cost (someone not understanding the default - slightly less comprehensible code), and literally no benefit at besides far less typing than it took to explain it. If you're using a pattern, breaking the pattern for *no* *good* *reason* is a poor idea. People like patterns, and people understand patterns. |
ram@zedat.fu-berlin.de (Stefan Ram): Nov 10 12:43AM >Thanks, but just thinking another thing: is is a good idea at all using >enums as (option) flags? I read some say online that should use >constants instead. Or what about main.cpp #include <iostream> #include <ostream> template< int i > constexpr int verify() { static_assert( i >= 1, "i < 1" ); static_assert( i <= 4, "i > 4" ); return i; } template< int i >constexpr int opt = 1<<( verify< i >()- 1 ); int main() { ::std::cout << opt< 1 ><< '\n'; ::std::cout << opt< 2 ><< '\n'; ::std::cout << opt< 3 ><< '\n'; ::std::cout << opt< 4 ><< '\n'; } transcript 1 2 4 8 ? |
ram@zedat.fu-berlin.de (Stefan Ram): Nov 10 02:52AM >A string such as 4,800.1 or 3,334.5e9. #include <iostream> #include <ostream> #include <string> using namespace ::std::literals; /* This definition of "replace" is a stub! The implementation is left as an exercise. */ static ::std::string replace ( ::std::string const & source, ::std::string const &, ::std::string const & ) { ::std::string s { source }; s.replace( 1, 1, ""s ); return s; } int main() { ::std::cout << stod( replace( "4,800.1"s, ","s, ""s ))<< '\n'; ::std::cout << stod( replace( "3,334.5e9"s, ","s, ""s ))<< '\n'; } transcript 4800.1 3.3345e+012 |
ram@zedat.fu-berlin.de (Stefan Ram): Nov 10 12:16PM >Any of atof, strtod, sscanf will happily convert this, *provided* the >locale is setup correctly. IIRC, An implementation of C is not required to support other locales than the "C" locale, so any code based on any other locale would not be portable. |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment