Not to be confused with how to split a string parsing wise, e.g.:
Split a string in C++?
I am a bit confused as to how to split a string onto multiple lines in c++.
This sounds like a simple question, but take the following example:
#include <iostream>
#include <string>
main() {
//Gives error
std::string my_val ="Hello world, this is an overly long string to have" +
" on just one line";
std::cout << "My Val is : " << my_val << std::endl;
//Gives error
std::string my_val ="Hello world, this is an overly long string to have" &
" on just one line";
std::cout << "My Val is : " << my_val << std::endl;
}
I realize that I could use the std::string append() method, but I was wondering if there was any shorter/more elegant (e.g. more pythonlike, though obviously triple quotes etc. aren't supported in c++) way to break strings in c++ onto multiple lines for sake of readability.
One place where this would be particularly desirable is when you're passing long string literals to a function (for example a sentence).
Don't put anything between the strings. Part of the C++ lexing stage is to combine adjacent string literals (even over newlines and comments) into a single literal.
#include <iostream>
#include <string>
main() {
std::string my_val ="Hello world, this is an overly long string to have"
" on just one line";
std::cout << "My Val is : " << my_val << std::endl;
}
Note that if you want a newline in the literal, you will have to add that yourself:
#include <iostream>
#include <string>
main() {
std::string my_val ="This string gets displayed over\n"
"two lines when sent to cout.";
std::cout << "My Val is : " << my_val << std::endl;
}
If you are wanting to mix a #defined integer constant into the literal, you'll have to use some macros:
#include <iostream>
using namespace std;
#define TWO 2
#define XSTRINGIFY(s) #s
#define STRINGIFY(s) XSTRINGIFY(s)
int main(int argc, char* argv[])
{
std::cout << "abc" // Outputs "abc2DEF"
STRINGIFY(TWO)
"DEF" << endl;
std::cout << "abc" // Outputs "abcTWODEF"
XSTRINGIFY(TWO)
"DEF" << endl;
}
There's some weirdness in there due to the way the stringify processor operator works, so you need two levels of macro to get the actual value of TWO to be made into a string literal.
Are they both literals? Separating two string literals with whitespace is the same as concatenation: "abc" "123" is the same as "abc123". This applies to straight C as well as C++.
I don't know if it is an extension in GCC or if it is standard, but it appears you can continue a string literal by ending the line with a backslash (just as most types of lines can be extended in this manor in C++, e.g. a macro spanning multiple lines).
#include <iostream>
#include <string>
int main ()
{
std::string str = "hello world\
this seems to work";
std::cout << str;
return 0;
}
Related
I would like to extract several sets of numbers from a string and paste them into another string accordingly.
Let's say there is a dialog and we get the WndCaption as String A (input string).
String A: Voltage: 2.0V, Current:0.4A, Resistance: 5.0Ω, Power: 1.5W.
String A is a dynamic input, it depends on the WndCaption of the dialog. For example, String A also can be The apple is inside column: 12, row: 3, box: 5.
String B (input reference string) is exactly the same as String A except the numbers are replaced by delimiter. It is used to extract the numbers from String A.
String B: Voltage: %fV, Current:%fA, Resistance: %fΩ, Power: %fW.
Then this is String C (output reference string),
String C: The answers are %fV; %fA; %fΩ; %fW.
String B and String C are paired together that get from a database (.txt file) using std::vector<>::data.
Question is: how can I extract that 4 sets of number and paste them into String C and get the final output as The answers are 2.0V; 0.4A; 5.0Ω; 1.5W.?
I tried to implement the split and merge method but it seems not possible for this situation. Any idea?
I've impelemented code below as an example what can be done.
I didn't understand what exact steps to achieve your task, but I understood that you need two things - first finding and extracting matches of some substring inside input string using regular expressions or something, second compose new string by putting inside some substrings found on first stage.
In my code below I implemented both stages - first extracting substrings using regular expression, second composing new string.
I used functions and objects from standard C++ module std::regex. Also I coded a special helper function string_format(format, args...) to be able to do formatting of composed result, formatting is achieved through described here formatting specifiers.
You may achieve your goal by repeating next code few times by first extracting necessary substring and the composing result formatted string.
Next code can be also run online here! or here!
#include <regex>
#include <string>
#include <regex>
#include <iostream>
#include <stdexcept>
#include <memory>
using namespace std;
// Possible formatting arguments are described here https://en.cppreference.com/w/cpp/io/c/fprintf
template<typename ... Args>
std::string string_format( const std::string& format, Args ... args )
{
size_t size = snprintf( nullptr, 0, format.c_str(), args ... ) + 1; // Extra space for '\0'
if( size <= 0 ){ throw std::runtime_error( "Error during formatting." ); }
std::unique_ptr<char[]> buf( new char[ size ] );
snprintf( buf.get(), size, format.c_str(), args ... );
return std::string( buf.get(), buf.get() + size - 1 ); // We don't want the '\0' inside
}
int main() {
try {
string str = "abc12345DEF xyz12ABcd";
cout << "Input string [" << str << "]." << endl;
string sre0 = "\\d+[A-Z]+";
// https://en.cppreference.com/w/cpp/header/regex
std::regex re0(sre0);
vector<string> elems;
std::sregex_token_iterator iter(str.begin(), str.end(), re0, 0);
std::sregex_token_iterator end;
while (iter != end) {
elems.push_back(*iter);
++iter;
cout << "matched [" << elems.back() << "] " << endl;
}
string fmt = "New String part0 \"%s\" and part1 \"%s\" and some number %d.";
string formatted = string_format(fmt.c_str(), elems.at(0).c_str(), elems.at(1).c_str(), 987);
cout << "Formatted [" << formatted << "]." << endl;
return 0;
} catch (exception const & ex) {
cout << "Exception: " << ex.what() << endl;
return -1;
}
}
Code output:
Input string [abc12345DEF xyz12ABcd].
matched [12345DEF]
matched [12AB]
Formatted [New String part0 "12345DEF" and part1 "12AB" and some number 987.].
You should definitely use regex to perform that task. They're more flexible and can parse almost anything.
In case the format is very limited, and will never ever change, you might get away by using sscanf. Here's an example program :
#include <iostream>
#include <string>
int main()
{
char input[100];
int param1, param2, param3;
char output[100];
sprintf( input, "%s", "AA123BBB45CCCCC6789DDDD" ); // your input
sscanf( input, "AA%dBBB%dCCCCC%dDDDD", ¶m1, ¶m2, ¶m3); // parse the parameters
sprintf(output, "E%dFF%dGGG%dHHHH", param1, param2, param3); // print in output with your new format
printf("%s", output);
return(0);
}
Post-edit :
That answer doesn't make any sense anymore, but I'll leave it like that.
My advice remains : use regexes.
I would like to convert a hex-value ("206564697374754f") to a string (from hex to ascii). These hex-values are from gdb, so the contents are "reversed" by every two. (So the exact hex-value I need to convert is "4f75747369..."). reverse2() reverses the string appropriately, but it needs to now be converted to hex (hence the "0x", then atoi()).
The following code is what I have so far, but I run into a runtime-error. What is the issue, and is there a better way of doing this?
#include <bits/stdc++.h>
using namespace std;
void reverse2s(string str)
{
for (int i=str.length()-2; i>=0; i-=2) {
string hx="0x"+str[i]+str[i+1];
cout << (char)(std::stoi( hx ));
}
}
// Driver code
int main(void)
{
string s = "206564697374754f";
reverse2s(s);
return (0);
}
The expression "0x"+str[i]+str[i+1]; does not do what you think. "0x" is a character array (not a string). Since str[i] is a character, the addition will add convert that character to an int, and perform a pointer addition. This results in Undefined Behavior.
To do the string concatenation you're expecting, you need to create a string object first:
string hx="0x"s+str[i]+str[i+1];
"0x"s will create an actual string literal to append characters to.
Well it seems like you're just trying to print it as hex,
so you could do
std::cout << std::hex << 5 << std::endl; // prints 0x5
If you don't care about performance:
std::stringstream s;
s << std::hex << num:
s.str(); // std::string containing your number as hex
If you do care about performance I have no clue
This should work:
#include <iostream>
#include <strstream>
#include <string>
int main()
{
std::strstream s1; // dynamic buffer
s1 << std::hex << 12345 << std::endl;
std::cout << "buffer: '" << s1.str() << "'\n";
s1.freeze(false);
return 0;
}
Part 2 on encoding characters in C++ (by User123).
<- Go to the previous post.
I was yesterday making some code, and Paul Sanders in this question told me useful solution: He told me not to use std::cout << "something"; but to use std::wcout << L"something";.
But I have another problem. Now I want to do something like this (some special characters, but in array):
#include <iostream>
using namespace std;
string myArray[2] = { "łŁšđřžőšě", "×÷¤ßł§ř~ú" };
int main()
{
cout << myArray[0] << endl << myArray[1];
return 0;
}
But now I get something really unusual:
│úܰקÜý
θĄ▀│ž°~˙
If I add L in front of the array, I get (Visual Studio 2019):
C++ initialization with '{...}' expected for aggregate object
How can I represent these special characters but in the array?
#include <iostream>
using namespace std;
wstring myArray[2] = { L"łŁšđřžőšě", L"×÷¤ßł§ř~ú" };
int main()
{
wcout << myArray[0] << endl << myArray[1];
return 0;
}
L can only be applied directly to string literals. The result is a string literal of type wchar_t[] (wide character) rather then the usual char_t[] (narrow character), so you cannot save it in a string. You need to save it in a wstring. And to output a wstring you need to pass it to wcout, not cout.
I need to validate a string that is at least 5 characters long, contains at least one upper-case letter, at least one lower-case letter, at least one digit and no other characters except the dash and the underscore. I've tested this in other languages and it apparently works:
^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[0-9a-zA-Z_\-]{5,}$
However, in C++, this simple test program validates strings such as "AasdA" as correct input. I know I am missing something glaringly obvious, but after much research I cannot tell what is wrong. Maybe it's something to do with the way getline() stores strings. Here is my code:
#include <iostream>
#include <regex>
#include <string>
using namespace std;
int main() {
string test;
do {
cout << "Test: ";
getline(cin, test);
if (regex_match(test, regex("^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[0-9a-zA-Z_\-]{5,}$"))) {
cout << "True." << endl;
} else {
cout << "False." << endl;
}
} while (test != "");
return 0;
}
You need to double the backslashes in your string constant:
if (regex_match(test, regex("^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])[0-9a-zA-Z_\\-]{5,}$"))) {
Is this example code valid?
std::string x ="There are";
int butterflies = 5;
//the following function expects a string passed as a parameter
number(x + butterflies + "butterflies");
The main question here is whether I could just pass my integer as part of the string using the + operator. But if there are any other errors there please let me know :)
C++ doesn't do automatic conversion to strings like that. You need to create a stringstream or use something like boost lexical cast.
You can use stringstream for this purpose like that:
#include <iostream>
#include <sstream>
using namespace std;
int main()
{
stringstream st;
string str;
st << 1 << " " << 2 << " " << "And this is string" << endl;
str = st.str();
cout << str;
return 0;
}
A safe way to convert your integers to strings would be an excerpt as follows:
#include <string>
#include <sstream>
std::string intToString(int x)
{
std::string ret;
std::stringstream ss;
ss << x;
ss >> ret;
return ret;
}
Your current example will not work for reasons mentioned above.
No, it wouldn't work. C++ it no a typeless language. So it can't automatically cast integer to string. Use something like strtol, stringstream, etc.
More C than C++, but sprintf (which is like printf, but puts the result in a string) would be useful here.