I have an output of a string that is:
I need to print out only the parts that are between"tele": and then the ",". for example the first one i need to print out is hel. In the above string output. "text":"hel","source": is the first part. Every where there is a "tele": and the "," i need to be printed.
the code i have written so far prints out only the first one and is shown below
int comm_poss;
string econ;
tax= mes.find("tele");
econ=mes.substr(tax,15);
cout<<"msg test : "<<econ;
This prints out tele":"hel"," but not the other part that is between the "tele" and ","
how do i print only whats between those two and make the code do it multiple times?
thanks
EDIT: the other part in the output is "tele":"FIRS","code":" found near the end
Save yourself some trouble and use a JSON parser. For example using JsonCpp library and reading the JSON file from stdin (untested):
Json::Value root;
std::cin >> root;
for (int i = 0; i < root.size(); i++) {
std::string text = root[i]["text"].asString();
std::cout << text << std::endl;
}
Could something like this help.
string txt_test;
size_t poss_text;
poss_text= replyMsg.find("text:\":\""); // Search for text":"
replyMsg=replyMsg.substr(poss_text + 8); // Get rest of string
// Add 8 to get beyond text":"
poss_text= replyMsg.find("\","); // Search for ",
txt_test = replyMsg.substr(0, poss_text); // Get from start to ",
cout<< "msg test : " << txt_test;
You should however always check whether your string were found:
if (poss_text != std::string::npos)
{
// Found - so go on
}
else
{
// Not found - stop now
}
Now you can add the loop:
int main()
{
string replyMsg = "HEJtext:\":\"first\",\"hhhtext:\":\"second\",";
string txt_test;
size_t poss_text = 1;
while(poss_text != std::string::npos) // Loop while there is still something in replyMsg
{
poss_text= replyMsg.find("text:\":\""); // Search for text":"
if (poss_text != std::string::npos)
{
replyMsg=replyMsg.substr(poss_text + 8); // Get rest of string
// Add 8 to get beyond text":"
poss_text= replyMsg.find("\","); // Search for ",
if (poss_text != std::string::npos)
{
txt_test = replyMsg.substr(0, poss_text); // Get from start to ",
cout<< "msg test : " << txt_test << std::endl ;
replyMsg=replyMsg.substr(poss_text); // Prepare for next search
}
}
}
return 0;
}
This is a working solution.
I will not use any library since you probably want to know how to do it from scratch.
1. Using Strtok() with delim(':') and checking if the 6 characters to
the left is equal to "text", If TRUE, then pickup all characters to the right
until you hit ",".
2. When you're picking up characters to the right, to avoid reading past your domain, modify the content string by adding a '$' symbol to the end.
#include <iostream>
void get_text(char * token);
int main(){
char =content[]="586162004425048066\",\"text\":\"hel\",\"source\":...\"text\":\"yo\";$";
char * token;
token=strtok(content,":");
get_text(token);
while(token=strtok(NULL,":")){
get_text(token);
}
}
void get_text(char * token){
unsigned int len=strlen(token);
std::string temp;
if (len>=6){ // Reading the 6 characters to the left and storing it in temp
for (int i=-6; i<0; i++){
temp=temp+token[len+i];
}
}
if (temp=="\"text\""){
temp="";
unsigned i=len;
while(token[i]!=',' and token[i]!='$'){ // retrieve characters to the right until you hit a ',' or '$' (which indicates end of line as a boundary condition)
temp=temp+token[i];
i++;
}
std::cout<<temp;
}
}
OUTPUT
"hey" "yo"
Related
I'm currently working in C++, getting an HTTP response from a request that I write into a .txt file using ostream. This happens asynchronously and I don't want to change this.
Once the data is done being written, I want to read from the file
{"data":{"request":[{"type":"City","query":"London, United Kingdom"}],"weather":[{"date":"2013-04-21","astronomy".....
~somehow~ prettify the string using either an outside library like nlohmann/json or other(?) and then
a)print it to the console and
b) save it in a different file (pretty.json)
I am having trouble understanding which method to use from:
https://github.com/nlohmann/json
Any ideas how to approach this?
I was thinking getting the file line by line until I hit EOF into a sort of "buffer" and then running _json on that and saving the solution which can be displayed on the console...
My code so far
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
#include <iostream>
#include <sstream>
#include "json.hpp"
using namespace utility; // string conversion
using namespace web; // URI
using namespace web::http; // HTTP commands
using namespace web::http::client; // HTTP Client features
using namespace concurrency::streams; // Asynch streams, like Node
using json = nlohmann::json;
int main()
{
auto fileStream = std::make_shared<ostream>();
// Open stream to output file.
pplx::task<void> requestTask = fstream::open_ostream(U("results.txt"))
.then([=](ostream outFile)
{
*fileStream = outFile;
http_client client //gets the info
return client.request(methods::GET, stringBuilder.to_string());
})
.then([=](http_response response) // set up response handler
{
printf("Received response status code:%u\n", response.status_code());
return response.body().read_to_end(fileStream->streambuf());
})
.then([=](size_t) // close file stream
{
return fileStream->close();
})
.then([=]()
{
nlohmann::json j;
std::ifstream i;
i.open("results.txt"); // ?? <<< === this is where my question is
});
// Wait for all the outstanding I/O to complete, handle exceptions
try
{
requestTask.wait();
}
catch (const std::exception &e)
{
printf("Error exception:%s\n", e.what());
}
return 0;
}
SOLUTION:
.then([=]()
{
// read a JSON file
std::ifstream readFromFile("results.txt");
if (readFromFile.is_open()) {
nlohmann::json j;
readFromFile >> j;
// write prettified JSON to another file
std::ofstream writeToFile("pretty.json");
writeToFile << std::setw(4) << j << std::endl;
readFromFile.close();
writeToFile.close();
}
else {
std::cout << "unable to open file";
}
});
You have two choices to prettify with nlohmann.
Uses dump which produces a string
int indent = 4;
nlohmann::json data;
data.dump(indent);
Or use the stream output overload with field width set
std::ofstream o("pretty.json");
o << std::setw(4) << data << std::endl;
I am trying to read in a csv file with an unknown number of rows. I tried using vector of vector approach but it wont compile.
vector<vector<double> > data;
ifstream file("data.csv");
int i = 0;
while (iss.good())
{
vector<int> row;
for (int j = 0; j < 2; j++) {
string val;
getline(iss, val, ',');
stringstream convertor(val);
cout << val << endl;
row.push_back(val);
}
data.push_back(row);
i++;
}
Thanks for the tip but even with the edit, the code doesnt compile. Welp.
Error message:
Q7.cc:18:10: error: ‘iss’ was not declared in this scope
Q7.cc:28:26: error: no matching function for call to ‘std::vector<int>::push_back(std::string&)’
the first line
vector<vector<double>> data;
has the fragment >> which is interpreted as a stream operator. It must look like
vector<vector<double> > data;
Note the space!
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>.
I'm currently working with CUSPARSE. I'm having trouble because I don't know how to print a complex number. For example, when I write:
cuComplex a;
a.x=1.2;
a.y=2.2;
How do I print the varable a?
I've tried :
cout<< a;
but it doesn't work.
You will need to overload the << operator to take in cuComplex and cuDoubleComplex data types.
std::ostream& operator<<(std::ostream& strm, const cuComplex& in)
{
char sgn[2] = "+-"
strm << in.x << sgn[in.y < 0] << " i"<< std::abs(in.y);
return strm;
}
You can do the same for cuDoubleComplex
The data in std::complex is identical to the corresponding data in a cuComplex, i.e. you can reinterpret_cast pointers (and therefore arrays, too) of one type to the other – it works in practise and is, I think, actually guaranteed by C++11, you can test it like this:
namespace check_stdComplexdouble_to_cuDoubleComplex_binary_compatibility{
using std::complex;
const complex<double> testarr[] = { complex<double>(0.,.5)
, complex<double>(1.,1.5) };
const cuDoubleComplex* cucomplexd
= reinterpret_cast<const cuDoubleComplex*>(testarr);
auto tester() -> bool {
assert( cuCreal(cucomplexd[0])==0. && cuCimag(cucomplexd[0])==.5
&& cuCreal(cucomplexd[1])==1. && cuCimag(cucomplexd[1])==1.5 );
return true;
}
const bool ok = tester();
bool good(){return ok;}
};
If you call a CUBLAS function that's supposed to read/write from/to an std::complex<float>, you can just give it a reinterpret_casted pointer, e.g.
std::complex<double> result;
xhandle->cublasstat = yhandle->cublasstat
= cublasZdotc( *xhandle->cublashandle
, xhandle->vect_dimension
, xhandle->vector, 1
, yhandle->vector, 1
, reinterpret_cast<cuDoubleComplex*>(&result) );
Is there a way to directly display the content of a query in Mysql using C?
What I mean is:
through mysql shell if I type : SELECT * FROM table_name; I get the query result in a neat and formatted way.
If I want to do the same thing using Api C I have to write several lines of codes and the final result is far from being nice (at least this is my personal experience )
For example :
void display_Table1(MYSQL *conn)
{
int jj,ii;
char query[512];
sprintf(query, "SELECT * FROM Table1 ;");
if (mysql_query (conn, query)) {
printf("\nErrore query:\n");
printf("%s", mysql_error(conn),"\n");
result = mysql_store_result(conn);
if (result) {
num_rows = mysql_num_rows(result);
num_fields =mysql_num_fields(result);
//printf("Number of rows=%u Number of fields=%d \n", num_rows,num_fields);
//printf(" ");
}
else
{
printf("Result set is empty");
}
// Print column headers
fields = mysql_fetch_fields(result);
for(jj=0; jj < num_fields; jj++)
{
printf("\n%s\t\t",fields[jj].name);
}
printf("\n\t ");
// print query results
while(row = mysql_fetch_row(result)) // row pointer in the result set
{
for(ii=0; ii < num_fields; ii++)
{
printf("%s\t", row[ii] ? row[ii] : "NULL"); // Not NULL then print
}
printf("\n");
}
if(result)
{
mysql_free_result(result);
result = NULL;
}
}
}
That's a knotty problem to solve. I get headers one after the other in a vertical way.
I also get
Commands out of sync; you can't run this command now
Firstly, there is no direct way to print out a formatted display. What you can do, is use
MYSQL_FIELD *field = mysql_fetch_field (resultset);
col_len = field->max_length;
if(col_len < strlen(field->name))
col_len = strlen(field->name);
to find out the maximum width of a column, and the space the data accordingly.