Parsing HHMMSS come from NMEA - c++

I have a trouble with NMEA data(gpzda). The problem is explained below.
NMEA Data : $GPZDA,011856.00,17,03,2018,,*61
My Parsing Code.
char hour[2] = { 0 };
for (int i=0; i < 2; i++) hour[i] = utctime[i];
info.tm_hour = atoi(hour);
char min[2] = { 0 };
for (int i=0; i < 2; i++) min[i] = utctime[i + 2];
info.tm_min = atoi(min);
char sec[2] = { 0 };
for (int i=0; i < 2; i++) sec[i] = utctime[i + 4];
info.tm_sec = atoi(sec);
cout << info.tm_year << " | " << info.tm_mon << " | " << info.tm_mday << " | " << info.tm_hour << " | " << info.tm_min << " | " << info.tm_sec << endl;
The code is well working, but some time the hour value is strange like a "126". I thought that "6" is add from another memory. How to parse this data to well work?

You should zero terminate your strings, so declare each one to be of size 3.
char hour[3] = { 0 };
and so on

Related

Converting littleEndian via QDataStream

i want to send some integers (int32_t) via network.
For this I convert the integers first and send them.
p.x = 129;
p.y = 42;
p.d = counter++;
converted[0] = htonl(p.x);
converted[1] = htonl(p.y);
converted[2] = htonl(p.d);
if ( (bytes = send(socket, (char *)converted, pointSize, 0)) < 0)
{
std::cerr << "bytes = " << bytes << std::endl;
}
Then Qt should do the work, so I tried a QDataStream conversion but that failed, values > 128 got negative. So currently I do a conversion like this:
while ( socket->bytesAvailable() > 0 )
{
//qDebug() << "Data received" << socket->bytesAvailable();
m_data.append(socket->readAll());
//qDebug() << "Buffer " << m_data.size();
if (m_data.size() >= sizeOfPoint)
{
Point x;
QByteArray b = m_data.left(sizeOfPoint);
for (int i = 0; i < 4; i++)
{
x.x += (u_int8_t) b[i] << 8*(3-i);
}
for (int i = 4; i < 8; i++)
{
x.y += (u_int8_t) b[i] << 8*(7-i);
}
for (int i = 8; i < 12; i++)
{
x.d += (u_int8_t) b[i] << 8*(11-i);
}
//x.x = (u_int8_t) (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
//x.y = (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | (b[7]);
//x.d = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11];
//x.d = b[10] << 8;
//x.d = (b[11]);
//QDataStream in(buffer.data());
//in.setByteOrder(QDataStream::LittleEndian);
//in >> conv[1];
//in >> conv[2];
qDebug() << "Data provided " << x.x << " " << x.y << " "<< x.d;
m_data.remove(0, sizeOfPoint);
}
}
What is the best way to convert these integers, the for loop seems not optimal for me.
Thank you

How to visualize Caffe deep learning process's individual layer output in C++?

I am using Caffe for deep learning. My program is in C++.
Every iteration of forward at net_->Forward(&loss);, we pass through all layers as defined in the prototxt file and how can I visualize each layer's output in C++.
Inside net.cpp file inside Caffe library, this loop iterate to forward layer by layer.
template <typename Dtype>
Dtype Net<Dtype>::ForwardFromTo(int start, int end) {
CHECK_GE(start, 0);
CHECK_LT(end, layers_.size());
Dtype loss = 0;
for (int i = start; i <= end; ++i) {
//cout << "Forwarding " << layer_names_[i] << endl;
Dtype layer_loss = layers_[i]->Forward(bottom_vecs_[i], top_vecs_[i]);
loss += layer_loss;
if (debug_info_) { ForwardDebugInfo(i); }
}
return loss;
}
top_vecs_[i] is output of each layer and how can I visualize it?
According to Shai's suggestion, what I did is as follow inside ForwardDebugInfo().
for (int top_id = 0; top_id < top_vecs_[layer_id].size(); ++top_id) {
Blob<Dtype>& blob = *top_vecs_[layer_id][top_id];
const string& blob_name = blob_names_[top_id_vecs_[layer_id][top_id]];
string name = blob_name;
for (int i = 0; i < name.length(); ++i) {
if (name[i] == '/')
name[i] = '_';
}
string foldname = "images/"+name;
if (stat(foldname.c_str(), &st) == -1) {
mkdir(foldname.c_str(), 0700);
}
//cout<<"blob_name " << blob_name << " layer_id is " << layer_id << " blob.num() " << blob.num() << " blob.channels() " << blob.channels() << " blob.height() " << blob.height() << " blob.width() " << blob.width() << endl;
///////Plotting output of individual layer
if(blob.height()>1 && blob.width()>1){
cv::Size ss(blob.width(), blob.height());
Dtype* data = blob.mutable_cpu_data();
for(int k=0; k < blob.channels(); k++)
{
cv::Mat channel(ss, CV_32FC1, data);
stringstream s;
s << k;
cv::imwrite(foldname+"/"+s.str()+".jpg",channel*255.0);
channel.release();
data += ss.area();
}
}
// mainImg.release();
/////////////////////////////////////////
const Dtype data_abs_val_mean = blob.asum_data() / blob.count();
LOG_IF(INFO, Caffe::root_solver())
<< " [Forward] "
<< "Layer " << layer_names_[layer_id]
<< ", top blob " << blob_name
<< " data: " << data_abs_val_mean;
}

What is wrong with my function for Lagrange?

GsVec curve_eval::eval_lagrange(float t, float numberofsegmentsn, const GsArray<GsVec>& ctrlpnts) //f(t) = sum of p.i * B.i(t)
{
//float interval = 1 / numberofsegmentsn; //so if 4, then 0.25
float interval = 1 / ctrlpnts.size();
//remember that for interval that is put in above, it's based on numbers of ctrlpnts
//for lagrange, let t
GsVec ft(0.0f, 0.0f, 0.0f);
int sizeofctrlpnts = ctrlpnts.size();
float result = 0;
std::cout << "interval = " << interval << " \\ number of segments = " << numberofsegmentsn << " \\ ctrlpnts.size() = " << ctrlpnts.size() << "\n";
float tt = 0;
float ti[50] = { 0 };
float tj[50] = { 0 }; //only this might be used
for (int x = 0; x < ctrlpnts.size(); x++) //changed from 'numberofsegmentsn'
{
tj[x] = tt;//
std::cout << "tt in tj[" << x << "]= " << tt << "\n";
tt = tt + interval;
}
float tb = 1;
tt = 1;
int i = 0;
for (int i = 0; i < ctrlpnts.size(); i ++)
{
tt = 1;
tb = 1;
for (int j = 0; j < ctrlpnts.size(); j++) //
{
if (i != j)
{
std::cout << "Before cal: i = " << i << " :: j = " << j << " :: tt = " << tt << " :: tb = " << tb << " :: t = " << t << " :: tj[i" << j << "] = " << tj[j] << " :: tj[j" << i << "] = " << tj[i] << "\n";
tt = (t - tj[j]) * tt;
tb = (tj[i] - tj[j])* tb;
std::cout << "After cal: tt = " << tt << " :: tb = " << tb << "\n";
}
//t gotta change
}
result = tt / tb;
ft = ft+(ctrlpnts[i]*result);
}
return ft;
Above is my written algorithm for Lagrange function for opengl.
Following link is the screenshot of the formula that i had to impliment, http://imgur.com/gkuaxVm.
I have been tweaking it for awhile, and i can't seem to find what is wrong with it.

segmentation fault for string function argument

I have a simple main code that gives me segmentation fault when calling a function. In the following code, I have two functions, the first one works correctly but the program doesn't enter the second one and gives me segmentation fault error. Is there any reason for that? I have made sure about the following:
The variables o and c are not out of bound.
cn is initialized correctly.
I have a read-only access to cm and argv. Plus it does not even enter the function evaluate
Here is the code:
void print_cm(vector<vector<int> > *cm, char* gtf);
void evaluate(vector<vector<int> > *cm, char* gtf);
int main(int argc, char** argv)
{
int o = 2; // It is initialized
int c = 4; // It is initialized
vector<vector<int> > cm; // It is initialized
if (argc>4)
print_cm(&cm, argv[o]);
if (argc>4)
{
cout << argv[c] << endl; // Works
// The following also works
for (int i=0; i<cm.size(); i++)
for (int j=0; j<cm[i].size(); j++)
cout << cm[i][j] << " ";
// The following causes segmentation fault;
evaluate(&cm, argv[c]);
}
return 0;
}
void evaluate(vector<vector<int> > *cm, char* gtf)
{
// Read-only access to cm and gtf
}
void print_cm(vector<vector<int> > *cm, char* gtf)
{
// Read-only access to cm and gtf
}
Here is the complete code:
#include "includes/Utility.h"
#include "includes/Graph.h"
void print_cm(vector<vector<int> > *cores, char* output);
void evaluate(vector<vector<int> > const *cm, char* gtf);
int main(int argc, char** argv)
{
int g = -1, c = -1, o = -1;
for (int i=1; i<argc-1; i++)
if (argv[i][0]=='-')
{
if (argv[i][1]=='g')
g = i + 1;
else if (argv[i][1]=='c')
c = i + 1;
else if (argv[i][1]=='k')
ki = i + 1;
else if (argv[i][1]=='s')
si = i + 1;
else if (argv[i][1]=='o')
o = i + 1;
}
Graph G;
if (c>0) G.read_input(argv[g], argv[c]);
else G.read_input(argv[g]);
if (ki > 0)
{
int k = atoi(argv[ki]);
cout << k << endl;
}
if (si > 0)
{
int s = atoi(argv[si]);
cout << s << endl;
}
// Find communities
vector<vector<int> > cores;
G.partitioning(&cores);
if (o>0)
print_cm(&cores, argv[o]);
if (c>0)
{
cout << "here" << endl;
for (size_t i=0; i<cores.size(); i++)
for (size_t j=0; j<cores[i].size(); j++)
if (cores.at(i).at(j)<0) cout << "here";
cout << "here" << endl;
evaluate(&cores, argv[c]);
}
}
return 0;
}
void print_cm(vector<vector<int> > *cores, char* output)
{
ofstream out;
out.open(output);
for(size_t i=0; i<(*cores).size(); i++)
{
for(size_t j=0; j<(*cores)[i].size(); j++)
out << (*cores)[i][j] << " ";
out << endl;
}
out.close();
return ;
}
void evaluate(vector<vector<int> > const *cm, char* gtf)
{
// we evaluate precision, recall, F1 and F2
vector<vector<int> > gt;
ifstream in;
char str[100000000];
in.open(gtf);
while(in.getline(str, 100000000))
{
stringstream s;
s << str;
int a;
gt.resize(gt.size()+1);
while (s >> a) gt[gt.size()-1].push_back(a);
}
in.close();
cout << "==================== Evaluation Results ====================" << endl;
int imax = 0;
for(size_t i=0; i<(*cm).size(); i++)
imax = max(imax, *max_element((*cm)[i].begin(), (*cm)[i].end()));
for(size_t i=0; i<gt.size(); i++)
imax = max(imax, *max_element(gt[i].begin(), gt[i].end()));
vector<bool> flag(imax, false);
vector<double> recall((*cm).size(), 0), precision((*cm).size(), 0), f1((*cm).size(), 0), f2((*cm).size(), 0);
int overlap;
double size = 0;
for(size_t i=0; i<(*cm).size(); i++)
{
// evaluate
size += (double) (*cm)[i].size();
for(size_t j=0; j<(*cm)[i].size(); j++)
flag[(*cm)[i][j]] = true;
double p, r, ff1, ff2;
for(size_t j=0; j<gt.size(); j++)
{
overlap = 0;
for(size_t k=0; k<gt[j].size(); k++)
if (flag[gt[j][k]]) overlap++;
p = (double) overlap / (double) (*cm)[i].size();
if (p > precision[i])
precision[i] = p;
r = (double) overlap / (double) gt[j].size();
if (r > recall[i])
recall[i] = r;
ff1 = (double) 2*(p*r)/(p+r);
if (ff1 > f1[i])
f1[i] = ff1;
ff2 = (double) 5*(p*r)/(4*p + r);
if (ff2 > f2[i])
f2[i] = ff2;
}
for(size_t j=0; j<(*cm)[i].size(); j++)
flag[(*cm)[i][j]] = false;
}
double Recall = 0, Precision = 0, F1 = 0, F2 = 0;
for(size_t i=0; i<(*cm).size(); i++)
{
Recall += recall[i];
Precision += precision[i];
F1 += f1[i];
F2 += f2[i];
}
cout << "+--------------+--------------+--------------+--------------+" << endl;
cout << "| " << setiosflags( ios::left ) << setw(10) << "Precision";
cout << " | " << setiosflags( ios::left ) << setw(10) << "Recall";
cout << " | " << setiosflags( ios::left ) << setw(10) << "F1-measure";
cout << " | " << setiosflags( ios::left ) << setw(10) << "F2-measure";
cout << " |" << endl;
cout << "| " << setiosflags( ios::left ) << setw(10) << Precision/(*cm).size() ;
cout << " | " << setiosflags( ios::left ) << setw(10) << Recall/(*cm).size();
cout << " | " << setiosflags( ios::left ) << setw(10) << F1/(*cm).size();
cout << " | " << setiosflags( ios::left ) << setw(10) << F2/(*cm).size();
cout << " |" << endl;
cout << "+--------------+--------------+--------------+--------------+" << endl;
cout << "Number of communities: " << (*cm).size() << endl;
cout << "Average community size: " << size/(*cm).size() << endl;
return ;
}
char str[100000000];
This is in your evaluate function. This are 100 million bytes, or about 95 MB that you're allocating on the stack.
Typical stack sizes are far less than that, around 1 MB.
So apart from possible other problems this is most likely causing a stack overflow.
When entering the function, the stack frame gets extended to be large enough to hold the local variables. As soon as the stack is used then (to write a default value) you're accessing invalid (non stack, thankfully protected) memory.

Problems with reading a text-file and putting the tokens into a 2D matrix

I have a problem reading a text file and putting in the tokens from the text file into a 2-D matrix.
Here are my codes:
std::vector< vector <std::string> > my_matrix(10, vector <std::string>(10));
ifstream myReadFile;
myReadFile.open("class_data.txt", ios_base::in);
char output[100];
if (myReadFile.is_open()) {
if (!myReadFile.eof()) {
myReadFile >> output;
char* token = NULL;
char* context = NULL;
char delims[] = " ,\t\n";
token = strtok_s(output, delims, &context);
if (token != NULL)
{
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
my_matrix[i][j] = *token;
cout << "token = " << token << endl;
cout << "matrix = " << my_matrix[i][j] << endl;
token = strtok_s(NULL, delims, &context);
}
}
}
}
}
std::cout.width(3); std::cout << left << "ID";
std::cout.width(9); std::cout << left << "Project1";
std::cout.width(9); std::cout << left << "Project2";
std::cout.width(9); std::cout << left << "Project3";
std::cout.width(9); std::cout << left << "Project4";
std::cout.width(9); std::cout << left << "Project5";
std::cout.width(9); std::cout << left << "Project6";
std::cout.width(9); std::cout << left << "Project7";
std::cout.width(9); std::cout << left << "Midterm";
std::cout.width(9); std::cout << left << "Final" << std::endl;
std::cout << "-------------------------------------------------------------------------------" << std::endl;
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
cout.width(10); std::cout << my_matrix[i][j];
}
std::cout << " " << std::endl;
}
I have no errors, it compiles, but further in the program when I would like to display the 2-D matrix, it does not display it. It holds no value in to whole matrix.
Can anyone help me out and tell me what is the problem ? Is it with the way I did the 2 for loops or is it the way I read the text file ? If problem is found, could anyone suggest a solution.
P.S Sorry if I do not have the best professional codes, but I am a beginner in C++ and I did not take any University level programming courses.
You already have a 10x10 matrix and strtok returns a char * to the current token, just pass it to the std::string operator= in the matrix like this:
my_matrix[i][j] = token;
You also need to rethink the logic in your loop. After the strtok call in the inner for, add a check for the return value and break from both loops if it is NULL. Replace the while loop with an if test.
Edit:
I see you changed the while to a if, However, the 2 for loops need a little change too. I suggest something like this:
for (int i = 0; i < 10 && token; i++) {
for (int j = 0; j < 10 && token; j++) {
my_matrix[i][j] = token; // NOTE: not *token here
cout << "token = " << token << endl;
cout << "matrix = " << my_matrix[i][j] << endl;
token = strtok_s(NULL, delims, &context);
}
}
This change also makes the if test before the loops unnecessary.