So I just noticed something weird about opening .txt files in sublime that were created in vim.
It seems sublime adds an empty line at the end of the .txt file. For example, if I use vim/gedit to type the following 2 line file:
1
2
When I open this .txt file in Sublime, it opens as
1
2
~
where I have used "~" to represent an empty line. Could someone try this and tell me if it's the same for you?
This is the code I was using that doesn't seem to work when I create the .txt file in sublime:
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
int main()
{
int a;
int b;
ifstream inFile;
bool validInputFound;
inFile.open("inputVals.txt");
if (inFile.fail())
{
cout << "Unable to open input file!" << endl;
exit(1);
}
validInputFound = false;
while (!validInputFound)
{
inFile >> a;
if (inFile.eof())
{
cout << "EOF before reading a" << endl;
exit(2);
}
else if (inFile.fail())
{
inFile.clear();
inFile.ignore(200, '\n');
}
else
{
validInputFound = true;
}
}
cout << "Read a: " << a << endl;
validInputFound = false;
while (!validInputFound)
{
inFile >> b;
if (inFile.eof())
{
cout << "EOF before reading b" << endl;
exit(2);
}
else if (inFile.fail())
{
inFile.clear();
inFile.ignore(200, '\n');
}
else
{
validInputFound = true;
}
}
cout << "Read b: " << b << endl;
cout << "Sum: " << a + b << endl;
inFile.close();
return (0);
}
The expected output is:
Read a: 1
Read b: 2
Sum: 3
But if you create the inputVals.txt file in Sublime, you obtain:
Read a: 1
EOF before reading b
It looks like vim adds the newline and not the Sublime Text.
As to why: Why would Vim add a new line at the end of a file?
Related
In this convoluted example, two for loops are started by boost::asio::spawn() asynchronously. The first for loop prints an odd number every 1000us and the second one prints an even number every 1000us.
I expect the output to be something like 1 2 3 4 5 6 and then the 'Throw an error' message should be printed to stderr by the call to cerr.
However, the exception is actually thrown in loop.run() so it is not caught by the try catch block.
Can someone point out how to properly catch the runtime_error when calling spawn()? Does spawn() not reraise the exception thrown in the spawned coroutine to its parent scope?
using namespace std;
using namespace boost::asio;
using boost::posix_time::microseconds;
io_service loop;
spawn(loop, [&loop](yield_context yield)
{
try
{
spawn(loop, [&loop](yield_context yield)
{
deadline_timer timer{loop};
for(unsigned i = 0; i < 3; ++i)
{
cout << i * 2 + 1 << endl;
timer.expires_from_now(microseconds(1000));
timer.async_wait(yield);
}
throw runtime_error("Throw an error");
});
spawn(loop, [&loop](yield_context yield)
{
deadline_timer timer{loop};
for(unsigned i = 0; i < 3; ++i)
{
cout << (i + 1) * 2 << endl;
timer.expires_from_now(microseconds(1000));
timer.async_wait(yield);
}
});
} catch(const runtime_error& ex)
{
cerr << ex.what() << endl;
}
});
loop.run();
All handlers are invoked by the service loop, meaning you always need to handle errors: Should the exception thrown by boost::asio::io_service::run() be caught?
Sidenote: In the case of coroutines, it's my experience that catching by reference is a bit tricky. This more than likely has to do with the lifetime of the coroutine stack itself.
You can demonstrate it using:
while (true) {
try {
loop.run();
break;
} catch(std::runtime_error ex) {
std::cerr << "L:" << __LINE__ << ": " << ex.what() << "\n";
}
}
Other Notes
Note that passing error_code errors can be done in two ways across idiomatic Asio interfaces, including Coroutines: How to set error_code to asio::yield_context
Full Sample
Simply adapting your sample to be selfcontained:
Live On Coliru
#include <iostream>
#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/asio/high_resolution_timer.hpp>
using namespace std::chrono_literals;
int main() {
boost::asio::io_service loop;
spawn(loop, [&loop](boost::asio::yield_context yield)
{
try
{
spawn(yield, [&loop](boost::asio::yield_context yield)
{
boost::asio::high_resolution_timer timer{loop};
for(unsigned i = 0; i < 3; ++i)
{
std::cout << i * 2 + 1 << std::endl;
timer.expires_from_now(100ms);
timer.async_wait(yield);
}
throw std::system_error(ENOENT, std::system_category(), "Throw an error");
//throw boost::system::system_error(ENOENT, boost::system::system_category(), "Throw an error");
});
spawn(yield, [&loop](boost::asio::yield_context yield)
{
boost::asio::high_resolution_timer timer{loop};
for(unsigned i = 0; i < 3; ++i)
{
std::cout << (i + 1) * 2 << std::endl;
timer.expires_from_now(100ms);
timer.async_wait(yield);
}
});
} catch(const std::runtime_error& ex)
{
std::cerr << "L:" << __LINE__ << ": " << ex.what() << "\n";
}
});
while (true) {
try {
loop.run();
break;
} catch(std::runtime_error ex) {
std::cerr << "L:" << __LINE__ << ": " << ex.what() << "\n";
}
}
}
Prints
1
2
3
4
5
6
L:49: Throw an error: No such file or directory
BONUS:
Doing the extra approach with generalized competion token and async_result:
Live On Coliru
#include <iostream>
#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/asio/high_resolution_timer.hpp>
using namespace std::chrono_literals;
boost::asio::io_service loop;
template <typename Token>
auto async_foo(bool success, Token&& token)
{
typename boost::asio::handler_type<Token, void(boost::system::error_code, int)>::type
handler (std::forward<Token> (token));
boost::asio::async_result<decltype (handler)> result (handler);
boost::asio::yield_context yield(token);
boost::asio::high_resolution_timer timer{loop};
for(unsigned i = 0; i < 3; ++i) {
std::cout << (i * 2 + (success?0:1)) << std::endl;
timer.expires_from_now(100ms);
timer.async_wait(yield);
}
if (success)
handler(42);
else
throw boost::system::system_error(ENOENT, boost::system::system_category(), "Throw an error");
return result.get();
}
int main() {
auto spawn_foo = [](bool success) {
spawn(loop, [=](boost::asio::yield_context yield) {
try
{
int answer = async_foo(success, yield);
std::cout << "async_foo returned " << answer << std::endl;
} catch(const std::runtime_error& ex)
{
std::cerr << "L:" << __LINE__ << ": " << ex.what() << std::endl;
}
});
};
spawn_foo(true);
spawn_foo(false);
loop.run();
}
Prints
0
1
2
3
4
5
async_foo returned 42
L:45: Throw an error: No such file or directory
My JSON is this:
{
"apps":[
{
"id":"x",
"val":"y",
}
]
}
I can get id's value "x" by looping, and exiting when it.first is id:
for (const ptree::value_type &app : root.get_child("apps"))
{
for (const ptree::value_type &it : app.second) {
if (it.first == "id") {
std::cout << it.second.get_value<std::string>().c_str() << std::endl;
}
}
}
What I want, however, is to get the id's value by something like this:
std::cout << root.get<std::string>("apps[0].id").c_str() << std::endl;
Of course this displays nothing to me, for I am probably using wrong syntax accessing 1st element of the apps array. It might be that this has to be done in a different way all together.
I have found only this ugly and dangerous method:
std::cout << root.get_child("apps").begin()->second.begin()->second.get_value<std::string>().c_str() << std::endl;
I cannot really use it this way as it won't throw an exception when the array is empty, it will core dump!
Below is the whole program to make it easier for any one who wants to help:
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
using boost::property_tree::ptree;
int main()
{
std::stringstream ss("{\"apps\":[{\"id\":\"x\",\"val\":\"y\"}]}");
ptree root;
read_json(ss, root);
for (const ptree::value_type &app : root.get_child("apps"))
{
for (const ptree::value_type &it : app.second) {
if (it.first == "id") {
std::cout << it.second.get_value<std::string>().c_str() << std::endl;
}
}
}
std::cout << root.get_child("apps").begin()->second.begin()->second.get_value<std::string>().c_str() << std::endl;
return 0;
}
As the docs say, array elements are nodes with "" keys.
If you're after the first element, you're in luck:
root.get("apps..id", "")
The .. in the path selects the first empty key
Live On Coliru
#include <boost/property_tree/json_parser.hpp>
#include <iostream>
using boost::property_tree::ptree;
int main() {
std::stringstream ss(R"({"apps":[{"id":"x","val":"y"}]})");
ptree root;
read_json(ss, root);
std::cout << root.get("apps..id", "") << "\n";
}
BONUS
If you need to address elements other than the first, write a helper function. This would be a good start:
#include <string>
#include <stdexcept> // std::out_of_range
template <typename Tree>
Tree query(Tree& pt, typename Tree::path_type path) {
if (path.empty())
return pt;
auto const head = path.reduce();
auto subscript = head.find('[');
auto name = head.substr(0, subscript);
auto index = std::string::npos != subscript && head.back() == ']'
? std::stoul(head.substr(subscript+1))
: 0u;
auto matches = pt.equal_range(name);
if (matches.first==matches.second)
throw std::out_of_range("name:" + name);
for (; matches.first != matches.second && index; --index)
++matches.first;
if (index || matches.first==matches.second)
throw std::out_of_range("index:" + head);
return query(matches.first->second, path);
}
Here's some live tests using it:
Live On Coliru
#include <boost/property_tree/json_parser.hpp>
#include <iostream>
using boost::property_tree::ptree;
int main() {
std::stringstream ss(R"({
"apps": [
{
"id": "x",
"val": "y",
"id": "hidden duplicate"
},
{
"id": "a",
"val": "b"
}
]
})");
ptree root;
read_json(ss, root);
for (auto path : {
"apps..id", "apps.[0].id", // (equivalent)
//
"apps.[0].id[]", // invalid
"apps.[0].id[0]", // x
"apps.[0].id[1]", // hidden duplicate
"apps.[1].id", // a
"apps.[1].id[0]", // a
"apps.[1].id[1]", // out of range
"apps.[2].id", // out of range
"drinks" // huh, no drinks at the foo bar
}) try {
std::cout << "Path '" << path << "' -> ";
std::cout << query(root, path).get_value<std::string>() << "\n";
} catch(std::exception const& e) {
std::cout << "Error: " << e.what() << "\n";
}
}
Prints:
Path 'apps..id' -> x
Path 'apps.[0].id' -> x
Path 'apps.[0].id[]' -> Error: stoul
Path 'apps.[0].id[0]' -> x
Path 'apps.[0].id[1]' -> hidden duplicate
Path 'apps.[1].id' -> a
Path 'apps.[1].id[0]' -> a
Path 'apps.[1].id[1]' -> Error: index:id[1]
Path 'apps.[2].id' -> Error: index:[2]
Path 'drinks' -> Error: name:drinks
As I try to compile my code, I get this error:
1>Main.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: class std::basic_string,class std::allocator > const & __cdecl sql::SQLException::getSQLState(void)const " (__imp_?getSQLState#SQLException#sql##QBAABV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##XZ) referenced in function __catch$57778
Now there are a couple more, but I think solving this one, will solve the others as well.
I'm trying to get a SQL connection from an WinCe 6.0 Device to a Server.
First thoughts: Do I need to import the .dll/.lib files to my WinCe device?
Here's my code:
include <windows.h>
include <ScanCApi.h>
include <iostream>
include <cppconn/driver.h>
include <cppconn/exception.h>
include <cppconn/resultset.h>
include <cppconn/statement.h>
include <stdlib.h>
int wmain() {
try {
sql::Driver *driver;
sql::Connection *con;
sql::Statement *stmt;
sql::ResultSet *res;
/* Create a connection */
driver = get_driver_instance();
con = driver->connect("tcp://127.0.0.1:3306", "root", "root");
/* Connect to the MySQL test database */
con->setSchema("test");
stmt = con->createStatement();
res = stmt->executeQuery("SELECT 'Hello World!' AS _message");
while (res->next()) {
std::cout << "\t... MySQL replies: ";
/* Access column data by alias or column name */
std::cout << res->getString("_message") << std::endl;
std::cout << "\t... MySQL says it again: ";
/* Access column data by numeric offset, 1 is the first column */
std::cout << res->getString(1) << std::endl;
}
delete res;
delete stmt;
delete con;
} catch (sql::SQLException &e) {
std::cout << "# ERR: SQLException in " << __FILE__;
std::cout << "(" << __FUNCTION__ << ") on line " << __LINE__ <<
std::endl;
std::cout << "# ERR: " << e.what();
std::cout << " (MySQL error code: " << e.getErrorCode();
std::cout << ", SQLState: " << e.getSQLState() << " )" << std::endl;
}
return 0;
}
void HtmltoPDF::ConvertHtmltoPDF(std::string htmlTextData)
{
wkhtmltopdf_global_settings *global_settings;
wkhtmltopdf_object_settings *object_settings;
wkhtmltopdf_converter *Converter;
wkhtmltopdf_init(true);
global_settings = wkhtmltopdf_create_global_settings();
wkhtmltopdf_set_global_setting(global_settings, "out", "..\\DownloadPDF\\Example.pdf");
object_settings = wkhtmltopdf_create_object_settings(); // create input **object** to store the setting
//const char* a = "..\\Template\\VartLitePDF.html";
//wkhtmltopdf_set_object_setting(object_settings, "page", a); //pathway for the html file.
//wkhtmltopdf_set_object_setting(object_settings, "web.enableJavascript", "true"); //enable javascript.
Converter = wkhtmltopdf_create_converter(global_settings); //create the converter to convert the page.
wkhtmltopdf_add_object(Converter, object_settings, htmlTextData.c_str());
if (!wkhtmltopdf_convert(Converter)) //Perform the actual conversion.
fprintf(stderr, "Convertion failed!");
std::cout << "httpErrorCode : " << wkhtmltopdf_http_error_code(Converter) << std::endl;
const char* b = "..\\DownloadPDF\\Example.pdf";
HtmltoPDF::setReportGeneratedURL(b);
wkhtmltopdf_destroy_converter(Converter); //delete the object after the object is fully convert.
std::cout << wkhtmltopdf_deinit() << "\n"; //close the function after used.
}
int main()
{
string path;
cout << "Path file : ";
cin >> path;
cout << endl;
GetData *data;
GetData::createGetDataObject(&data);
data->GetString(path);
cout << data->GetString(path) << endl << endl;
string htmltext = data->GetString(path);
cout << endl;
HtmltoPDF *PDF;
HtmltoPDF::createPDFObject(&PDF);
PDF->ConvertHtmltoPDF(htmlTextData);
cout << "ABCD" << endl;
system("PAUSE");
return 0;
}
htmlTextData => is a html content and convert it into string.
First of all, it ables to display a full complete PDF with tables and images. After the second run (No closed the pogram) but it shows only data document and without any tables and images..
May I know what is the reason it caused?
Thanks..
I had the same problem just now, and by removing wkhtmltopdf_deinit() it worked. I don't know why and what other problems may arise but that's good for me so I don't think more of it.
Suppose I have a double Eigen matrix and I want to write it to a csv file. I find the way of writing into a file in raw format but I need commas between entries. Here is the code I foudn for simple writing.
void writeToCSVfile(string name, MatrixXd matrix)
{
ofstream file(name.c_str());
if (file.is_open())
{
file << matrix << '\n';
//file << "m" << '\n' << colm(matrix) << '\n';
}
}
Using format is a bit more concise:
// define the format you want, you only need one instance of this...
const static IOFormat CSVFormat(StreamPrecision, DontAlignCols, ", ", "\n");
...
void writeToCSVfile(string name, MatrixXd matrix)
{
ofstream file(name.c_str());
file << matrix.format(CSVFormat);
}
Here is what I came up;
void writeToCSVfile(string name, MatrixXd matrix)
{
ofstream file(name.c_str());
for(int i = 0; i < matrix.rows(); i++){
for(int j = 0; j < matrix.cols(); j++){
string str = lexical_cast<std::string>(matrix(i,j));
if(j+1 == matrix.cols()){
file<<str;
}else{
file<<str<<',';
}
}
file<<'\n';
}
}
This is the MWE to the solution given by Partha Lal.
// eigen2csv.cpp
#include <Eigen/Dense>
#include <iostream>
#include <fstream>
// define the format you want, you only need one instance of this...
// see https://eigen.tuxfamily.org/dox/structEigen_1_1IOFormat.html
const static Eigen::IOFormat CSVFormat(Eigen::StreamPrecision, Eigen::DontAlignCols, ", ", "\n");
// writing functions taking Eigen types as parameters,
// see https://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.html
template <typename Derived>
void writeToCSVfile(std::string name, const Eigen::MatrixBase<Derived>& matrix)
{
std::ofstream file(name.c_str());
file << matrix.format(CSVFormat);
// file.close() is not necessary,
// desctructur closes file, see https://en.cppreference.com/w/cpp/io/basic_ofstream
}
int main()
{
Eigen::MatrixXd vals = Eigen::MatrixXd::Random(10, 3);
writeToCSVfile("test.csv", vals);
}
Compile with g++ eigen2csv.cpp -I<EigenIncludePath>.