This question already has answers here:
Representing big numbers in source code for readability?
(5 answers)
Closed 9 years ago.
In Ada it is possible to write numbers with underscores for separating digits, which greatly improves readability. For example: 1_000_000 (which is equivalent to 1000000)
Is there some similar way for C++?
EDIT: This is question about source code, not I/O.
As of C++14, you can use ' as a digit group separator:
auto one_m = 1'000'000;
Previous versions of C++ did not support this natively. There were two major workarounds:
Using user-defined literals in C++11; this would allow you to write code as follows:
auto x = "1_000_000"_i;
(Writing this as a constexpr would be trickier – but is definitely possible.)
Using a straightforward macro, which would allow the following code:
auto x = NUM(1,000,000);
There is no way to do this currently. There is, however, a proposal to introduce digit separators (N3499). They haven't yet chosen which character they'd like to use as a separator though. The current suggestions are:
Space: 4 815 162 342
Grave accent: 4`815`162`342
Single quote: 4'815'162'342
Underscore: 4_815_162_342
Unfortunately, they all have problems as described in the proposal.
You can take the hacky approach by using a user-defined literal:
long long operator "" _s(const char* cstr, size_t)
{
std::string str(cstr);
str.erase(std::remove(str.begin(), str.end(), ','), str.end());
return std::stoll(str);
}
int main()
{
std::cout << "4,815,162,342"_s << std::endl;
}
This will print out:
4815162342
It simply removes all of the commas from the given literal and converts it to an integer.
int main()
{
int x = 1e6;
}
you can always just define a variadic macro, used like N(123,456,678). it's a bit more trouble than it's worth, though. in particular, you may have to workaround some visual c++ peculiarities for portable code for counting arguments.
What you are looking for is perfectly possible by imbue()ing the I/O stream with the appropriate locale facet (in this case, num_put).
(This is assuming you are talking about I/O. If you are talking about the source itself, that is not possible as of C++11.)
Related
This question already has answers here:
No match for 'operator==' in a simple string code
(4 answers)
Closed 8 years ago.
#include<iostream>
#include<cstdlib>
#include<string>
using namespace std;
int main()
{
string A1;
cin>>A1;
if(A1==0)
{
cout<<"Success!";
}
else
{
cout<<"Failure!";
}
system("PAUSE");
return 0;
}
Beginner in C++. I`m trying to compare the value of a string keyed in to 0 using the == operator. Above is my sample of code. How do I solve this problem in the simplest manner? Thank you.
Consider writing if(A1 == "0"). The C++ std::string class overloads the == operator to allow this.
To check if the string is empty, write if (A1.empty()) or if (!A1.size()). I prefer the second formulation as it's consistent with other C++ standard library objects.
Personally I prefer to use the compare method on std::string instead. This makes your code more readable by other developers (e.g. Java developers would hate to see == in this context).
C++ is a strongly typed language. 0 by itself is a number. "0" is a string literal. There are functions which can do conversions, eg. std::stoi (String to Integer) and std::to_string (Lots of things to string), though.
So you have quite a few possible solutions here, to get the types equal. There's no real best solution for such a simplified case.
This question already has answers here:
Why allow concatenation of string literals?
(10 answers)
Closed 9 years ago.
#include <iostream>
#include <string>
int main() {
std::string str = "hello " "world" "!";
std::cout << str;
}
The following compiles, runs, and prints:
hello world!
see live
It seems as though the string literals are being concatenated together, but interestingly this can not be done with operator +:
#include <iostream>
#include <string>
int main() {
std::string str = "hello " + "world";
std::cout << str;
}
This will fail to compile.
see live
Why is this behavior in the language? My theory is that it is allows strings to be constructed with multiple #include statements because #include statements are required to be on their own line. Is this behavior simply possible due to the grammar of the language, or is it an exception that was added to help solve a problem?
Adjacent string literals are concatenated we can see this in the draft C++ standard section 2.2 Phases of translation paragraph 6 which says:
Adjacent string literal tokens are concatenated
In your other case, there is no operator+ defined to take two *const char**.
As to why, this comes from C and we can go to the Rationale for International Standard—Programming Languages—C and it says in section 6.4.5 String literals:
A string can be continued across multiple lines by using the backslash–newline line continuation, but this requires that the continuation of the string start in the first position of the next line. To permit more flexible layout, and to solve some preprocessing problems (see §6.10.3), the C89 Committee introduced string literal concatenation. Two string literals in a row are pasted together, with no null character in the middle, to make one combined string literal. This addition to the C language allows a programmer to extend a string literal beyond the end of a physical line without having to use the backslash–newline mechanism and thereby destroying the indentation scheme of the program. An explicit concatenation operator was not introduced because the concatenation is a lexical construct rather than a run-time operation.
without this feature you would have to do this to continue a string literal over multiple lines:
std::string str = "hello \
world\
!";
which is pretty ugly.
Like #erenon said, the compiler will merge multiple string literals into one, which is especially helpful if you want to use multiple lines like so:
cout << "This is a very long string-literal, "
"which for readability in the code "
"is divided over multiple lines.";
However, when you try to concatenate string-literals together using operator+, the compiler will complain because there is no operator+ defined for two char const *'s. The operator is defined for the string class (which is totally different from C-strings), so it is legal to do this:
string str = string("Hello ") + "world";
The compiler concatenates the string literals automatically into a single one.
When the compiler sees "hello " + "world"; is looking for a global + operator which takes two const char* ... And since by default there is none it fails.
The "hello " "world" "!" is resolved by the compiler as a single string. This allows you to have concatenated strings written over multiple lines .
In the first example, the consecutive string literals are concatenated by magic, before compilation has properly started. The compiler sees a single literal, as if you'd written "hello world!".
In the second example, once compilation has begun, the literals become static arrays. You can't apply + to two arrays.
Why is this behavior in the language?
This is a legacy of C, which comes from a time when memory was a precious resource. It allows you to do quite a lot of string manipulation without requiring dynamic memory allocation (as more modern idioms like std::string often do); the price for that is some rather quirky semantics.
This question already has an answer here:
std::stringstream strange behaviour
(1 answer)
Closed 9 years ago.
I have a string with lots of different characters similar to: "$: " "213.23453"
How do i extract the double value 213.23453 and store it in a variable, it's C++/C and i cant use lambdas.
You can use "poor man's regex" of the sscanf function to skip over the characters prior to the first digit, and then reading the double, like this:
char *str = "\"$: \" \"213.23453\"";
double d;
sscanf(str, "%*[^0-9]%lf", &d);
Note the asterisk after the first percentage format: it instructs sscanf to read the string without writing its content into an output buffer.
Here is a demo on ideone.
Use a regular expression.
[$]?[0-9]*(\.)?[0-9]?[0-9]?
This should match those with a $ sign and those without.
Boost.Regex is a very good regular expression library
Personally, I find Boost.Xpressive much nicer to work with. It is a header-only library and it has some nice features such as static regexes (regexes compiled at compile time).
If you're using a C++11 compliant compiler, use std::regex unless you have good reason to use something else.
Pure C++ solution could be to manually cut off the trash characters preceding the number (first digit identified by std::isdigit) and then just construct a temporary istringstream object to retrieve the double from:
std::string myStr("$:. :$$#&*$ :213.23453$:#$;");
// find the first digit:
int startPos = 0;
for (; startPos < myStr.size(); ++startPos)
if (std::isdigit(myStr[startPos])) break;
// cut off the trash:
myStr = myStr.substr(startPos, myStr.size() - startPos);
// retrieve the value:
double d;
std::istringstream(myStr) >> d;
but C-style sscanf with appropriate format specified would suffice here as well :)
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How to convert a single char into an int
Well, I'm doing a basic program, wich handles some input like:
2+2
So, I need to add 2 + 2.
I did something like:
string mys "2+2";
fir = mys[0];
sec = mys[2];
But now I want to add "fir" to "sec", so I need to convert them to Int.
I tried "int(fir)" but didn't worked.
There are mulitple ways of converting a string to an int.
Solution 1: Using Legacy C functionality
int main()
{
//char hello[5];
//hello = "12345"; --->This wont compile
char hello[] = "12345";
Printf("My number is: %d", atoi(hello));
return 0;
}
Solution 2: Using lexical_cast(Most Appropriate & simplest)
int x = boost::lexical_cast<int>("12345");
Solution 3: Using C++ Streams
std::string hello("123");
std::stringstream str(hello);
int x;
str >> x;
if (!str)
{
// The conversion failed.
}
Alright so first a little backround on why what you attempted didn't work. In your example, fir is declared as a string. When you attempted to do int(fir), which is the same as (int)fir, you attempted a c-style cast from a string to an integer. Essentially you will get garbage because a c-style cast in c++ will run through all of the available casts and take the first one that works. At best your going to get the memory value that represents the character 2, which is dependent upon the character encoding your using (UTF-8, ascii etc...). For instance, if fir contained "2", then you might possibly get 0x32 as your integer value (assuming ascii). You should really never use c-style casts, and the only place where it's really safe to use them are conversions between numeric types.
If your given a string like the one in your example, first you should separate the string into the relevant sequences of characters (tokens) using a function like strtok. In this simple example that would be "2", "+" and "2". Once you've done that you can simple call a function such as atoi on the strings you want converted to integers.
Example:
string str = "2";
int i = atoi(str.c_str()); //value of 2
However, this will get slightly more complicated if you want to be able to handle non-integer numbers as well. In that case, your best bet is to separate on the operand (+ - / * etc), and then do a find on the numeric strings for a decimal point. If you find one you can treat it as a double and use the function atof instead of atoi, and if you don't, just stick with atoi.
Have you tried atoi or boost lexical cast?
I want to encrypt/encode a string at compile time so that the original string does not appear in the compiled executable.
I've seen several examples but they can't take a string literal as argument. See the following example:
template<char c> struct add_three {
enum { value = c+3 };
};
template <char... Chars> struct EncryptCharsA {
static const char value[sizeof...(Chars) + 1];
};
template<char... Chars>
char const EncryptCharsA<Chars...>::value[sizeof...(Chars) + 1] = {
add_three<Chars>::value...
};
int main() {
std::cout << EncryptCharsA<'A','B','C'>::value << std::endl;
// prints "DEF"
}
I don't want to provide each character separately like it does. My goal is to pass a string literal like follows:
EncryptString<"String to encrypt">::value
There's also some examples like this one:
#define CRYPT8(str) { CRYPT8_(str "\0\0\0\0\0\0\0\0") }
#define CRYPT8_(str) (str)[0] + 1, (str)[1] + 2, (str)[2] + 3, (str)[3] + 4, (str)[4] + 5, (str)[5] + 6, (str)[6] + 7, (str)[7] + 8, '\0'
// calling it
const char str[] = CRYPT8("ntdll");
But it limits the size of the string.
Is there any way to achieve what I want?
I think this question deserves an updated answer.
When I asked this question several years ago, I didn't consider the difference between obfuscation and encryption. Had I known this difference then, I'd have included the term Obfuscation in the title before.
C++11 and C++14 have features that make it possible to implement compile-time string obfuscation (and possibly encryption, although I haven't tried that yet) in an effective and reasonably simple way, and it's already been done.
ADVobfuscator is an obfuscation library created by Sebastien Andrivet that uses C++11/14 to generate compile-time obfuscated code without using any external tool, just C++ code. There's no need to create extra build steps, just include it and use it. I don't know a better compile-time string encryption/obfuscation implementation that doesn't use external tools or build steps. If you do, please share.
It not only obuscates strings, but it has other useful things like a compile-time FSM (Finite State Machine) that can randomly obfuscate function calls, and a compile-time pseudo-random number generator, but these are out of the scope of this answer.
Here's a simple string obfuscation example using ADVobfuscator:
#include "MetaString.h"
using namespace std;
using namespace andrivet::ADVobfuscator;
void Example()
{
/* Example 1 */
// here, the string is compiled in an obfuscated form, and
// it's only deobfuscated at runtime, at the very moment of its use
cout << OBFUSCATED("Now you see me") << endl;
/* Example 2 */
// here, we store the obfuscated string into an object to
// deobfuscate whenever we need to
auto narrator = DEF_OBFUSCATED("Tyler Durden");
// note: although the function is named `decrypt()`, it's still deobfuscation
cout << narrator.decrypt() << endl;
}
You can replace the macros DEF_OBFUSCATED and OBFUSCATED with your own macros. Eg.:
#define _OBF(s) OBFUSCATED(s)
...
cout << _OBF("klapaucius");
How does it work?
If you take a look at the definition of these two macros in MetaString.h, you will see:
#define DEF_OBFUSCATED(str) MetaString<andrivet::ADVobfuscator::MetaRandom<__COUNTER__, 3>::value, andrivet::ADVobfuscator::MetaRandomChar<__COUNTER__>::value, Make_Indexes<sizeof(str) - 1>::type>(str)
#define OBFUSCATED(str) (DEF_OBFUSCATED(str).decrypt())
Basically, there are three different variants of the MetaString class (the core of the string obfuscation). Each has its own obfuscation algorithm. One of these three variants is chosen randomly at compile-time, using the library's pseudo-random number generator (MetaRandom), along with a random char that is used by the chosen algorithm to xor the string characters.
"Hey, but if we do the math, 3 algorithms * 255 possible char keys (0 is not used) = 765 variants of the obfuscated string"
You're right. The same string can only be obfuscated in 765 different ways. If you have a reason to need something safer (you're paranoid / your application demands increased security) you can extend the library and implement your own algorithms, using stronger obfuscation or even encryption (White-Box cryptography is in the lib's roadmap).
Where / how does it store the obfuscated strings?
One thing I find interesting about this implementation is that it doesn't store the obfuscated string in the data section of the executable.
Instead, it is statically stored into the MetaString object itself (on the stack) and the algorithm decodes it in place at runtime. This approach makes it much harder to find the obfuscated strings, statically or at runtime.
You can dive deeper into the implementation by yourself. That's a very good basic obfuscation solution and can be a starting point to a more complex one.
Save yourself a heap of trouble down the line with template metaprogramming and just write a stand alone program that encrypts the string and produces a cpp source file which is then compiled in. This program would run before you compile and would produce a cpp and/or header file that would contain the encrypted string for you to use.
So here is what you start with:
encrypted_string.cpp and encrypted_string.h (which are blank)
A script or standalone app that takes a text file as an input and over writes encrypted_string.cpp and encrypted_string.h
If the script fails, your compiling will fail because there will be references in your code to a variable that does not exist. You could get smarter, but that's enough to get you started.
The reason why the examples you found can't take string literals as template argument is because it's not allowed by the ISO C++ standard. That's because, even though c++ has a string class, a string literal is still a const char *. So, you can't, or shouldn't, alter it (leads to undefined behaviour), even if you can access the characters of such an compile-time string literal.
The only way I see is using defines, as they are handled by the preprocessor before the compiler. Maybe boost will give you a helping hand in that case.
A macro based solution would be to take a variadic argument and pass in each part of the string as a single token. Then stringify the token and encrypt it and concatenate all tokens. The end result would look something like this
CRYPT(m y _ s t r i n g)
Where _ is some placeholder for a whitespace character literal. Horribly messy and I would prefer every other solution over this.
Something like this could do it although the Boost.PP Sequence isn't making it any prettier.
#include <iostream>
#include <boost/preprocessor/stringize.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#define GARBLE(x) GARBLE_ ## x
#define GARBLE_a x
#define GARBLE_b y
#define GARBLE_c z
#define SEQ (a)(b)(c)
#define MACRO(r, data, elem) BOOST_PP_STRINGIZE(GARBLE(elem))
int main() {
const char* foo = BOOST_PP_SEQ_FOR_EACH(MACRO, _, SEQ);
std::cout << foo << std::endl;
}