I know this question is asked for several times, but none of the answer fits with my need.
So I have this string
Sep=1, V_Batt=7.40, I_Batt=-559.63, V_SA=7.20, I_SA=-0.55, I_MB=500.25, V_5v=4.95, I_5v=446.20, V_3v=3.28, I_3v=3.45, S=0, T_Batt=25.24, T_SA1=22.95, T_SA2=-4.86
I want to get all of the number after the "=" sign and make a new string like
1,7.40,559.63,7.20,0.55,500.25,4.95,446.20,3.28,3.45,0,25.24,22.95,4.68
Can anyone help me to solve the problem. I have used stringstream but I got all 0 for my output
Thank you
Based on a corrected understanding of what's actually desired, I'd do things quite differently than I originally suggested. Under the circumstances, I agree with Stephen Webb that a regular expression is probably the right way to go, though I differ as to the right regex to use, and a bit in how to use it (though the latter is probably as much about habits I've formed as anything else).
#include <regex>
#include <iostream>
#include <string>
int main()
{
using iter = std::regex_token_iterator<std::string::const_iterator>;
std::string s = "Sep=1, V_Batt=7.40, I_Batt=-559.63, V_SA=7.20,
" I_SA=-0.55, I_MB=500.25, V_5v=4.95, I_5v=446.20,"
" V_3v=3.28, I_3v=3.45, S=0, T_Batt=25.24, T_SA1=22.95,"
" T_SA2=-4.86";
std::regex re(R"#([A-Z][^=]*=([-\.\d]+))#");
auto begin = iter(s.begin(), s.end(), re, 1);
iter end;
for (auto i = begin; i!= end; ++i)
std::cout << *i << ", ";
std::cout << '\n';
}
Result:
1, 7.40, -559.63, 7.20, -0.55, 500.25, 4.95, 446.20, 3.28, 3.45, 0, 25.24, 22.95, -4.86,
If the number of arguments and their order are known, you can use snprintf like this:
char str[100];
int Sep=1;
double V_Batt = 7.40, I_Batt = 559.63;// etc ...
snprintf(str, 100, "%d,%.2f,%.2f", Sep, V_Batt, I_Batt); //etc...
// str = 1,7.40,559.63
Open your file with fopen() function.
It returns you the File* variable. Of course, if already available your chars, just skip this step.
Use this File variable to get each char, let's say, by means of fgetc().
Check the content of obtained char variable and make what you want with it, eventually insert some comma in your new string, as necessary
That's exactly what std::regex_iterator is for.
#include <regex>
#include <iostream>
#include <string>
int main()
{
const std::string s = "Sep=1, V_Batt=7.40, I_Batt=-559.63, V_SA=7.20, I_SA=-0.55, I_MB=500.25, V_5v=4.95, I_5v=446.20, V_3v=3.28, I_3v=3.45, S=0, T_Batt=25.24, T_SA1=22.95, T_SA2=-4.86";
std::regex re("[-\\d\\.]+");
auto words_begin = std::sregex_iterator(s.begin(), s.end(), re);
auto words_end = std::sregex_iterator();
for (std::sregex_iterator i = words_begin; i != words_end; ++i)
std::cout << (*i).str() << ',';
std::cout << "\n";
}
The output of the above complete program is this.
1,7.40,-559.63,7.20,-0.55,500.25,5,4.95,5,446.20,3,3.28,3,3.45,0,25.24,1,22.95,2,-4.86,
Related
I have a project to write a program that receives a polynomial string from the user up to the 5th power (ex. x^3+6x^2+9x+24) and prints out all the real and imaginary roots. The coefficients should be stored in a dynamic array.
The problem is getting these coefficients from the string. One of the coefficients can be a 0 (ex. 2x^2-18) so I can't store the coefficients from left to right by using an increment, because in this case a=2, b=-18, and c has no value, which is wrong.
Another problem is if the coefficient is 1, because in this case nothing will be written beside the x for the program to read (ex. x^2-x+14). Another problem is if the user adds a space, several, or none (ex. x ^3 +4x^ 2- 12 x + 1 3).
I have been thinking of pseudocode for a long time now, but nothing is coming to mind. I thought of detecting numbers from left to right and reading numbers and stopping at x, but the first and second problems occur. I thought of finding each x and then checking the numbers before it, but the second problem occurs, and also I don't know how big the number the user inputs.
Here is another Regex that you can use to get your coefficients after deleting whitespace characters:
(\d*)(x?\^?)(\d*)
It uses groups (indicated by the brackets). Every match has 3 groups:
Your coefficient
x^n, x or nothing
The exponent
If (1) is null (e.g. does not exist), it means your coefficient is 1.
If (2) and (3) are null, you have the last single number without x.
If only (3) is null, you have a single x without ^n.
You can try some examples on online regex sites like this one, where you can see the results on the right.
There are many tutorials online how to use Regex with C++.
You should normalize your input string, for example, remove all space then parse coefficients.
Let see my example. Please change it for your case.
#include <iostream>
#include <regex>
#include <iterator>
#include <string>
#include <vector>
#include <algorithm>
int main(int argc, char *argv[]) {
std::string input {argv[1]};
input.erase(remove_if(input.begin(), input.end(), isspace), input.end());
std::cout << input << std::endl;
std::vector<int> coeffs;
std::regex poly_regex(R"(\s*\+?\-?\s*\d*\s*x*\^*\s*\d*)");
auto coeff_begin = std::sregex_iterator(input.begin(), input.end(), poly_regex);
auto coeff_end = std::sregex_iterator();
for (std::sregex_iterator i = coeff_begin; i != coeff_end; ++i) {
std::smatch match = *i;
std::string match_str = match.str();
// std::cout << " " << match_str << "\n";
std::size_t plus_pos = match_str.find('+');
std::size_t minus_pos = match_str.find('-');
std::size_t x_pos = match_str.find('x');
if (x_pos == std::string::npos) {
std::cout << match_str.substr(plus_pos + 1) << std::endl;
} else if (x_pos == 0) {
std::cout << 1 << std::endl;
} else if (minus_pos != std::string::npos) {
if (x_pos - minus_pos == 1) std::cout << -1 << std::endl;
else std::cout << match_str.substr(minus_pos, x_pos - minus_pos) << std::endl;
}
else {
std::cout << match_str.substr(plus_pos + 1, x_pos - plus_pos - 1) << std::endl;
}
}
for (auto i: coeffs) std::cout << i << " ";
return 0;
}
I want to extract string between open and close bracket.So if the content is
145(5)(7)
the output must be
5
7
I tried with C++ STL TR1 using below code
const std::tr1::regex pattern("\\((.*?)\\)");
// the source text
std::string text= "145(5)(7)";
const std::tr1::sregex_token_iterator end;
for (std::tr1::sregex_token_iterator i(text.begin(),
text.end(), pattern);
i != end;
++i)
{
std::cout << *i << std::endl;
}
I am getting the output as,
(5)
(7)
I want the output without delimiters.
Please help me to meet my requirement using STL TR1.
You need to use sregex_iterator instead of sregex_token_iterator and then access the submatches via .str(n):
const std::tr1::regex pattern1("\\((.*?)\\)");
std::string text= "145(5)(7)";
const std::tr1::sregex_iterator end;
for (std::tr1::sregex_iterator i(text.begin(),
text.end(), pattern1);
i != end;
++i)
{
std::cout << (*i).str(1) << std::endl;
}
I want to achieve such a result:
Before:
有人可能会问:“那情绪、欲望、冲动、强迫症有什么区别呢?”
After:
有人可能会问 那情绪 欲望 冲动 强迫症有什么区别呢
To space replace Chinese punctuation symbols.
I tried to use replace and replace_if function but failed. The code like this:
char myints[] = "有人可能会问:“那情绪、欲望、冲动、强迫症有什么区别呢?”";
std::vector<char> myvector ;
std::replace_if (myvector.begin(), myvector.end(), "\\pP", " ");
std::cout << "myvector contains:";
for (std::vector<char>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
Assuming you did mean to use a regular expression, rather than a character-by-character replacement function... Here's what I meant by using std::regex_replace. There's probably a more elegant regex that generalizes with fewer surprises, but at least this works for your example.
#include <regex>
#include <string>
int main()
{
std::wstring s(L"有人可能会问:“那情绪、欲望、冲动、强迫症有什么区别呢?”");
// Replace each run of punctuation with a space; use ECMAScript grammar
s = std::regex_replace(s, std::wregex(L"[[:punct:]]+"), L" ");
// Remove extra space at ends of line
s = std::regex_replace(s, std::wregex(L"^ | $"), L"");
return (s != L"有人可能会问 那情绪 欲望 冲动 强迫症有什么区别呢"); // returns 0
}
I am using VC++ 10 in a project. Being new to C/C++ I just Googled, it appears that in standard C++ doesnt have regex? VC++ 10 seems to have regex. However, how do I do a regex split? Do I need boost just for that?
Searching the web, I found that many recommend Boost for many things, tokenizing/splitting string, parsing (PEG), and now even regex (though this should be build in ...). Can I conclude boost is a must have? Its 180MB for just trivial things, supported naively in many languages?
C++11 standard has std::regex. It also included in TR1 for Visual Studio 2010. Actually TR1 is available since VS2008, it's hidden under std::tr1 namespace. So you don't need Boost.Regex for VS2008 or later.
Splitting can be performed using regex_token_iterator:
#include <iostream>
#include <string>
#include <regex>
const std::string s("The-meaning-of-life-and-everything");
const std::tr1::regex separator("-");
const std::tr1::sregex_token_iterator endOfSequence;
std::tr1::sregex_token_iterator token(s.begin(), s.end(), separator, -1);
while(token != endOfSequence)
{
std::cout << *token++ << std::endl;
}
if you need to get also the separator itself, you could obtain it from sub_match object pointed by token, it is pair containing start and end iterators of token.
while(token != endOfSequence)
{
const std::tr1::sregex_token_iterator::value_type& subMatch = *token;
if(subMatch.first != s.begin())
{
const char sep = *(subMatch.first - 1);
std::cout << "Separator: " << sep << std::endl;
}
std::cout << *token++ << std::endl;
}
This is sample for case when you have single char separator. If separator itself can be any substring you need to do some more complex iterator work and possible store previous token submatch object.
Or you can use regex groups and place separators in first group and the real token in second:
const std::string s("The-meaning-of-life-and-everything");
const std::tr1::regex separatorAndStr("(-*)([^-]*)");
const std::tr1::sregex_token_iterator endOfSequence;
// Separators will be 0th, 2th, 4th... tokens
// Real tokens will be 1th, 3th, 5th... tokens
int subMatches[] = { 1, 2 };
std::tr1::sregex_token_iterator token(s.begin(), s.end(), separatorAndStr, subMatches);
while(token != endOfSequence)
{
std::cout << *token++ << std::endl;
}
Not sure it is 100% correct, but just to illustrate the idea.
Here an example from this blog.
You'll have all your matches in res
std::tr1::cmatch res;
str = "<h2>Egg prices</h2>";
std::tr1::regex rx("<h(.)>([^<]+)");
std::tr1::regex_search(str.c_str(), res, rx);
std::cout << res[1] << ". " << res[2] << "\n";
I thought the boost regex engines would be faster than boost::algorithm
This simple test shows algo beating the regex engines by a wide margin
This is the entire test program Did I miss something?
#include "boost/algorithm/string.hpp"
#include "boost/regex.hpp"
#include "boost/xpressive/xpressive.hpp"
#include "boost/progress.hpp"
#include <iostream>
int main()
{
boost::timer tm;
const int ITERATIONS = 10000000;
{
std::string input("This is his face");
tm.restart();
for( int i = 0; i < ITERATIONS; ++i)
{
boost::algorithm::replace_all(input,"his","her");
}
std::cout << "boost::algorithm: " << tm.elapsed()/60 << std::endl;
}
{
std::string input("This is his face");
boost::regex expr("his");
std::string format("her");
tm.restart();
for( int i = 0; i < ITERATIONS; ++i)
{
boost::regex_replace( input, expr, format );
}
std::cout << "boost::regex: " << tm.elapsed()/60 << std::endl;
}
{
std::string input("This is his face");
boost::xpressive::sregex expr = boost::xpressive::as_xpr("his");
std::string format("her");
tm.restart();
for( int i = 0; i < ITERATIONS; ++i)
{
boost::xpressive::regex_replace(input, expr, format);
}
std::cout << "boost::xpressive: " << tm.elapsed()/60 << std::endl;
}
return 0;
}
regex can handle all kinds of regular expression (for example something like "My.*Test" can be matched in a text like "I wonder how many classes called MySumTest have been written?"). They are more powerful but less performant than algorithms for finding a pattern in a text
I don't find this all that surprising; simple things usually are faster. In higher level languages, say JavaScript, it's usually a win to delegate string processing down to a regular expression because there's so much overhead even doing a simple loop in an interpreted language, but the same reasoning doesn't apply to compiled languages like C++.
Anyway, I would say you should use boost string algorithms over regex where it is reasonable to do so, because boost::regex introduces a runtime dependency (it uses an external .so file) while the algorithms are basically inline code generators, and you should use regexes only where you need them... say looking for an floating point number:
[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?
would you want to try that without regular expressions?