C++ getting rid of empty string rows - c++

Hi so this code worked 5 minutes ago to do exactly what I needed it to do.
The data is:
Set Field [G],Sheet Resistivity (Gavg) [ohm/sqr]
0.0000E+0,
0.0000E+0,7.270620E+2
1.0000E-2,
1.0000E-2,7.271280E+2
-1.0000E-2,
-1.0000E-2,
-1.0000E-2,7.271290E+2
And my code for it is:
#include <iostream>
#include <fstream>
using namespace std;
int main(){
ifstream ip("/Users/10Exahertz/Documents/Hall Data/Test/data.txt");
if(!ip.is_open()) std::cout << "ERROR: File Open" << '\n';
string x;
string y;
while(getline(ip,x,',')){
getline(ip,y,'\n');
if(y!="")
std::cout <<x<<","<< y << '\n';
}
ip.close();
}
Like I said 5 mintues ago this worked, it got rid of the rows with an empty y string and all was good. But then I went back to the original data file and it didnt work there. I was confused so I put the original data into data.txt and now that one is not working either. Im honestly confused, but what would be the best condition in that if loop to make it so this works.

It sounds like you may have some whitespace that's crept in. I'd use the solution from this answer to trim the whitespace from your y string just to be sure:
#include <iostream>
#include <algorithm>
#include <cctype>
#include <locale>
#include <fstream>
using namespace std;
// trim from start (in place)
static inline void ltrim(std::string &s) {
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int ch) {
return !std::isspace(ch);
}));
}
int main() {
[...]
while(getline(ip,x,',')){
getline(ip,y,'\n');
ltrim(y);
if(y!="")
std::cout <<x<<","<< y << '\n';
}
}

Related

how connect regex replace to function in c++

#include <iostream>
#include <iterator>
#include <regex>
#include <string>
std::string ty(std::string text){
if(text == "brown")
return "true";
else
return "qw";
}
int main()
{
std::string text = "Quick $brown fox";
std::cout << '\n' << std::regex_replace(text, std::regex(R"(\\$(.*))"), ty("$&")) << '\n';
}
i use c++11 . I try without if worked but with if don't work ? i don't know what to do
There's a lot of different things wrong with the original code.
Firstly here's some working code
#include <iostream>
#include <iterator>
#include <regex>
#include <string>
std::string ty(std::string text){
if(text == "brown")
return "true";
else
return "qw";
}
int main()
{
std::string text = "Quick $brown fox";
std::smatch m;
if (std::regex_search(text, m, std::regex(R"(\$([[:alpha:]][[:alnum:]]*))")))
{
std::cout << '\n' << ty(std::string(m[1].first, m[1].second)) << '\n';
}
else
{
std::cout << "\nno match\n";
}
}
Some things that were wrong with the original code
Firstly the function being called was wrong. Use std::regex_search to search for matches in a string. Capture the results in an std::smatch object and then use those results to call the ty function.
The regex was wrong in two different ways. Firstly \\ is wrong because you are using a raw string literal, so only a single backslash is required. Secondly (.*) is wrong because that will match the entire rest of the string. You only want to match the word following the dollar. I've used ([[:alpha:]][[:alnum:]]*) instead. That might not be exactly what you want but it works for this example. You can modify it if you want.

How to split string using CRLF delimiter in cpp?

I have some string :
testing testing
test2test2
these lines are devided by CRLF. I saw that there are : 0d0a0d0a deviding them.
How can I split it using this information?
I wanted to use str.find(CRLF-DELIMITER) but can't semm to figure how
editing :
I already used str.find("textDelimiter"), but now I need it to look for hexa and not search for a string "0d0a0d0a"
Use boost::split to do that. Please also take a look at Boost.Tokenizer.
Here is another way of doing it using regex:
using std::endl;
using std::cout;
using std::string;
using std::vector;
using boost::algorithm::split_regex;
int main()
{
vector<string> res;
string input = "test1\r\ntest2\r\ntest3";
split_regex(res, input, boost::regex("(\r\n)+"));
for (auto& tok : res)
{
std::cout << "Token: " << tok << std::endl;
}
return 0;
}
Here is the way of doing it without Boost:
#include <string>
#include <sstream>
#include <istream>
#include <vector>
#include <iostream>
int main()
{
std::string strlist("line1\r\nLine2\r\nLine3\r\n");
std::istringstream MyStream(strlist);
std::vector<std::string> v;
std::string s;
while (std::getline(MyStream, s))
{
v.push_back(s);
std::cout << s << std::endl;
}
return 0;
}

How to split_regex only once?

The function template boost::algorithm::split_regex splits a single string into strings on the substring of the original string that matches the regex pattern we passed to split_regex. The question is: how can I split it only once on the first substring that matches? That is, is it possible to make split_regex stop after its first splitting? Please see the following codes.
#include <boost/algorithm/string/regex.hpp>
#include <boost/format.hpp>
#include <boost/regex.hpp>
#include <iostream>
#include <locale>
int main(int argc, char *argv[])
{
using namespace std;
using boost::regex;
locale::global(locale(""));
// Create a standard string for experiment.
string strRequestLine("Host: 192.168.0.1:12345");
regex pat(R"(:\s*)", regex::perl | boost::regex_constants::match_stop);
// Try to split the request line.
vector<string> coll;
boost::algorithm::split_regex(coll, strRequestLine, pat);
// Output what we got.
for (const auto& elt : coll)
cout << boost::format("{%s}\n") % elt;
// Exit the program.
return 0;
}
Where shall the codes be modified to have the output like
{Host}
{192.168.0.1:12345}
instead of the current output
{Host}
{192.168.0.1}
{12345}
Any suggestion/hint? Thanks.
Please note that I'm not asking how to do it with other functions or patterns. I'm asking if it's possible for split_regex to split only once and then stop. Because regex object seems to have the ability to stop at the first matched, I wonder that if offering it some proper flags it maybe stop at the first matched.
For your specific input it seems the simple fix is to change the pattern to become R"(:\s+)". Of course, this assumes that there is, at least, one space after Host: and no space between the IP address and the port.
Another alternative would be not to use split_regex() but rather std::regex_match():
#include <iostream>
#include <regex>
#include <string>
int main()
{
std::string strRequestLine("Host: 192.168.0.1:12345");
std::smatch results;
if (std::regex_match(strRequestLine, results, std::regex(R"(([^:]*):\s*(.*))"))) {
for (auto it(++results.begin()), end(results.end()); it != end; ++it) {
std::cout << "{" << *it << "}\n";
}
}
}
Expanding from my comment:
You might be interested in the first sample I listed here: small HTTP response headers parsing function. Summary: use phrase_parse(f, e, token >> ':' >> lexeme[*(char_ - eol)], space, key, value)
Here's a simple sample:
Live On Coliru
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
namespace {
typedef std::string::const_iterator It;
// 2.2 Basic Rules (rfc1945)
static const qi::rule<It, std::string()> rfc1945_token = +~qi::char_( " \t><#,;:\\\"/][?=}{:"); // FIXME? should filter CTLs
}
#include <iostream>
int main()
{
std::string const strRequestLine("Host: 192.168.0.1:12345");
std::string::const_iterator f(strRequestLine.begin()), l(strRequestLine.end());
std::string key, value;
if (qi::phrase_parse(f, l, rfc1945_token >> ':' >> qi::lexeme[*(qi::char_ - qi::eol)], qi::space, key, value))
std::cout << "'" << key << "' -> '" << value << "'\n";
}
Prints
'Host' -> '192.168.0.1:12345'

writing data from right to left in file?

instead of saving data and then reversing it i wanted to know if there is any function that can save the output to the file directly from right to left?
for example if i have this simple code:
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
ofstream fout("filepath");
fout<<"stackoverflow");
return 0;
}
instead of having :
stackoverflow
i want to have:
wolfrevokcats
*this example is just an example don't be mad at me :D
You can reverse the string before writing it. That's the only way I know how to do it because you can't write from "right" to "left"
#include <iostream>
#include <string>
#include <algorithm>
int main(int argc, char **argv) {
std::string thing("my thing");
std::reverse(thing.begin(), thing.end());
std::cout << thing << std::endl;
return 0;
}

Regex search & replace group in C++?

The best I can come up with is:
#include <boost/algorithm/string/replace.hpp>
#include <boost/regex.hpp>
#include <iostream>
using namespace std;
int main() {
string dog = "scooby-doo";
boost::regex pattern("(\\w+)-doo");
boost::smatch groups;
if (boost::regex_match(dog, groups, pattern))
boost::replace_all(dog, string(groups[1]), "scrappy");
cout << dog << endl;
}
with output:
scrappy-doo
.. is there a simpler way of doing this, that doesn't involve doing two distinct searches? Maybe with the new C++11 stuff (although I'm not sure that it's compatible with gcc atm?)
std::regex_replace should do the trick. The provided example is pretty close to your problem, even to the point of showing how to shove the answer straight into cout if you want. Pasted here for posterity:
#include <iostream>
#include <iterator>
#include <regex>
#include <string>
int main()
{
std::string text = "Quick brown fox";
std::regex vowel_re("a|e|i|o|u");
// write the results to an output iterator
std::regex_replace(std::ostreambuf_iterator<char>(std::cout),
text.begin(), text.end(), vowel_re, "*");
// construct a string holding the results
std::cout << '\n' << std::regex_replace(text, vowel_re, "[$&]") << '\n';
}