I can't type in cin.getline() - buffer

I've found an exemplary code where cin.getline() is used:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int a;
char ch[80];
cin >> a;
cin.getline(ch,80);
cout << a << endl;
cout << ch << endl;
return 0;
}
Could anyone explain me why I can't type anything in cin.getline(ch,80) and "a" is printed after typing a value? I know that cin.getline() reads till "\n", but there isn't "\n" anywhere. I'm a bit confused.

Related

Videocapture error: Assertion desc failed at src/libswscale/swscale_internal.h:668 error

Videocapture read give me this error. It started recently when I updated to opencv4. No errors on opencv4 installation. libswscale is up to date, I have libswscale.so.4.8.100.
The code is a simple "open" and "read" video to isolate the problem:
#include<opencv2/core.hpp>
#include<opencv2/videoio.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<string>
#include <iostream>
int main(int argc, char **argv){
cv::VideoCapture video;
std::string filename(argv[1]);
std::cout << "filename " << filename << std::endl;
std::cout << "video.open " << video.open(filename) << std::endl;
union {
char ch[5] = {0};
int i4cc;
} fourcc;
fourcc.i4cc = (int) video.get(cv::CAP_PROP_FOURCC);
std::cout << "Fourcc " << fourcc.ch << std::endl;
cv::Mat frame;
while(true){
std::cout << "video.read " << video.read(frame) << ", Mat.rows " << frame.rows << std::endl;
cv::imshow("imagen", frame);
}
}
The output is this
filename ../Archivos/Vuelta al Lab Uno 720p.MP4
video.open 1
Fourcc avc1
Assertion desc failed at src/libswscale/swscale_internal.h:668
VideoCapture opens the video file, shows fourcc property, and then fails to read first image.
If you ask, video file is fine, I tried with other video files and other video formats, with the same error. These videos play well with ffmpeg.ffplay!
By the way, VideoCapture.read is working fine with webcam. So, it's not clear where the problem is.
Thank you for your time.

How to use Crypto++ to perfom DH key exchange (CryptoPP::DH::Agree returns false)

I'm trying to use Crypto++ to perform Diffie-Hellman key exchange. I have written a simple program to check if this is working. As you can guess, it is not.
This program was written based on wiki article: https://www.cryptopp.com/wiki/Diffie-Hellman It is generating public and private keys and then uses them to cal function CryptoPP::DH::Agree. It was working when I was using the same pair of keys for both sides like it is on the wiki. This does not have much practical sense though. However, when I trying to use different keys, CryptoPP::DH::Agree returns false.
I suspect that I'm doing something incorrectly but I have no idea what.
#include <crypto++/cryptlib.h>
#include <crypto++/dh.h>
#include <cryptopp/dh2.h>
#include <crypto++/osrng.h>
#include <crypto++/integer.h>
#include <crypto++/nbtheory.h>
#include <iostream>
static CryptoPP::AutoSeededRandomPool rnd;
static CryptoPP::DH dhA, dhB;
static CryptoPP::SecByteBlock privKeyA, pubKeyA, privKeyB, pubKeyB;
static void createDomainParameters(CryptoPP::DH &dh)
{
CryptoPP::PrimeAndGenerator pg;
pg.Generate(1, rnd, 512, 511);
const CryptoPP::Integer p = pg.Prime();
const CryptoPP::Integer q = pg.SubPrime();
const CryptoPP::Integer g = pg.Generator();
std::cout << "P: " << p << '\n';
std::cout << "Q: " << q << '\n';
std::cout << "G: " << g << '\n';
dh = CryptoPP::DH(p, q, g);
}
static void createAsymetricKey(const CryptoPP::DH &dh, CryptoPP::SecByteBlock &privKey, CryptoPP::SecByteBlock &pubKey)
{
privKey = CryptoPP::SecByteBlock(dh.PrivateKeyLength());
pubKey = CryptoPP::SecByteBlock(dh.PublicKeyLength());
dh.GenerateKeyPair(rnd, privKey, pubKey);
CryptoPP::Integer a, b;
a.Decode(privKey.BytePtr(), privKey.SizeInBytes());
std::cout << "privKey: " << a << std::endl;
b.Decode(pubKey.BytePtr(), pubKey.SizeInBytes());
std::cout << "pubKey: " << b << std::endl;
}
static void createSymetricKey(const CryptoPP::DH &dh, const CryptoPP::SecByteBlock &privKey, const CryptoPP::SecByteBlock &pubKey)
{
CryptoPP::SecByteBlock shared(dh.AgreedValueLength());
if(!dh.Agree(shared, privKey, pubKey))
throw std::runtime_error("Failed to reach shared secret");
CryptoPP::Integer x;
x.Decode(shared.BytePtr(), shared.SizeInBytes());
std::cout << "shared: " << x << std::endl;
}
int main()
{
std::cout << std::hex;
createDomainParameters(dhA);
std::cout << std::endl;
createDomainParameters(dhB);
std::cout << "\n------------------------------\n" << std::endl;
createAsymetricKey(dhA, privKeyA, pubKeyA);
std::cout << std::endl;
createAsymetricKey(dhB, privKeyB, pubKeyB);
if(dhA.AgreedValueLength() != dhB.AgreedValueLength())
throw std::runtime_error("Shared secret size mismatch");
std::cout << "\n------------------------------\n" << std::endl;
createSymetricKey(dhA, privKeyA, pubKeyB);
std::cout << std::endl;
createSymetricKey(dhB, privKeyB, pubKeyA);
return 0;
}
When you change calls of createSymetricKey so it uses key from the same pair, it works.
createSymetricKey(dhA, privKeyA, pubKeyA);
std::cout << std::endl;
createSymetricKey(dhB, privKeyB, pubKeyB);
AFAIK this has no sense though. What is the correct way to use CryptoPP::DH::Agree?

The result of opencv3.3 dnn module not match the caffe prediction

I used opencv dnn classification, but the result do not match the caffe prediction. What confused me was that some images could get similar result to caffe,a small number of images not.When I changed BGR to RGB, Most of the results ware wrong.
similar result:
different result:
blobFromImage(norm_img, 1.0, cv::Size(64, 64));when used default parameters changed BGR to RGB ,but the result would wrong .so I used like this blobFromImage(norm_img, 1.0, cv::Size(64, 64), cv::Scalar(),false); .most of result would matched caffe prediction,why a small number of images not?
#include <opencv2/dnn.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/core/utils/trace.hpp>
using namespace cv;
using namespace cv::dnn;
#include <fstream>
#include <iostream>
#include <cstdlib>
using namespace std;
/* Find best class for the blob (i. e. class with maximal probability) */
static void getMaxClass(const Mat &probBlob, int *classId, double *classProb)
{
Mat probMat = probBlob.reshape(1, 1); //reshape the blob to 1x1000 matrix
Point classNumber;
minMaxLoc(probMat, NULL, classProb, NULL, &classNumber);
*classId = classNumber.x;
}
static std::vector<String> readClassNames(const char *filename = "./config/type.txt")
{
std::vector<String> classNames;
std::ifstream fp(filename);
if (!fp.is_open())
{
std::cerr << "File with classes labels not found: " << filename << std::endl;
exit(-1);
}
std::string name;
while (!fp.eof())
{
std::getline(fp, name);
if (name.length())
classNames.push_back(name.substr(name.find(' ') + 1));
}
fp.close();
return classNames;
}
int main(int argc, char **argv)
{
CV_TRACE_FUNCTION();
String modelTxt = "./config/HCCR3755_res20_deploy.prototxt";
String modelBin = "./config/HCCR3755-res20_iter_790000.caffemodel";
String imageFile = "./config/b9.jpg";
Net net = dnn::readNetFromCaffe(modelTxt, modelBin);
if (net.empty())
{
std::cerr << "Can't load network by using the following files: " << std::endl;
std::cerr << "prototxt: " << modelTxt << std::endl;
std::cerr << "caffemodel: " << modelBin << std::endl;
exit(-1);
}
Mat img = imread(imageFile);
FileStorage fs("./config/mean.xml", FileStorage::READ);
Mat _mean;
fs["vocabulary"] >> _mean;
if (img.empty())
{
std::cerr << "Can't read image from the file: " << imageFile << std::endl;
exit(-1);
}
cv::Mat img_resize;
resize(img, img_resize, Size(64, 64));
cv::Mat img_float;
img_resize.convertTo(img_float, CV_32FC3);
cv::Mat norm_img;
cv::subtract(img_float, _mean, norm_img);
Mat inputBlob = blobFromImage(norm_img, 1.0, cv::Size(64, 64), cv::Scalar(),false); //Convert Mat to batch of images
Mat prob;
cv::TickMeter t;
for (int i = 0; i < 1; i++)
{
CV_TRACE_REGION("forward");
//! [Set input blob]
net.setInput(inputBlob, "data"); //set the network input
//! [Set input blob]
t.start();
//! [Make forward pass]
prob = net.forward("prob");
//std::cout << prob << std::endl;//compute output
//! [Make forward pass]
t.stop();
}
int classId;
double classProb;
getMaxClass(prob, &classId, &classProb);//find the best class
//! [Gather output]
//! [Print results]
std::vector<String> classNames = readClassNames();
std::cout << "Best class: #" << classId << " '" << classNames.at(classId) << "'" << std::endl;
std::cout << "Probability: " << classProb * 100 << "%" << std::endl;
//! [Print results]
std::cout << "Time: " << (double)t.getTimeMilli() / t.getCounter() << " ms (average from " << t.getCounter() << " iterations)" << std::endl;
getchar();
return 0;
} //main

How to use remove_if with vector<point2f>

I have a vector that has lots of NaN's for x,y positions that I want to remove(doing some opencv work). I cannot figure out how to use remove_if to remove the NaNs(when used in conjunction with erase). I've seen lots of examples if the vector is float or int but not point2f. Any simple examples would be very helpful. Thanks.
You can use a lambda function, or a functor or a function pointer. This is an example with a lambda function:
#include <opencv2/opencv.hpp>
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace cv;
using namespace std;
int main(int argc, char ** argv)
{
vector<Point2f> pts{ Point2f(1.f, 2.f), Point2f(3.f, sqrt(-1.0f)), Point2f(2.f, 3.f) };
cout << "Before" << endl;
for (const auto& p : pts) {
cout << p << " ";
}
cout << endl;
pts.erase(remove_if(pts.begin(), pts.end(), [](const Point2f& p)
{
// Check if a coordinate is NaN
return isnan(p.x) || isnan(p.y);
}), pts.end());
cout << "After" << endl;
for (const auto& p : pts) {
cout << p << " ";
}
cout << endl;
return 0;
}
That will print:
Before
[1, 2] [3, -1.#IND] [2, 3]
After
[1, 2] [2, 3]

Parsing a string into double and string in C++

I have a string like this
string myStr("123ab")
I'd like to parse it into
double d;
string str;
with d=123 and str=ab
I tried using string stream like this
istringstream ss(myStr);
ss >> d >> str;
But it didn't work. What's wrong?
The code in the OP worked as expected for me:
#include <iostream>
#include <sstream>
#include <string>
int main(int argc, char** argv) {
for (int i = 1; i < argc; ++i) {
std::istringstream ss(argv[i]);
double d;
std::string s;
if (ss >> d >> s)
std::cout << "In '" << argv[i]
<< "', double is " << d
<< " and string is '" << s << "'\n";
else
std::cout << "In '" << argv[i]
<< "', conversion failed.\n";
}
return 0;
}
$ ./a.out 123ab
In '123ab', double is 123 and string is 'ab'
(Live on coliru.)
However, it fails on input 123eb because the e is interpreted as an exponent indicator and there is no following exponent. There is no simple way around this issue with std::istringstream, which works somewhat like sscanf; fallback is not possible. However, std::strtod should find the longest valid floating point number, and therefore will be able to deal with 123eb. For example:
#include <iostream>
#include <sstream>
#include <string>
#include <cstring>
int main(int argc, char** argv) {
for (int i = 1; i < argc; ++i) {
char* nptr;
double d = strtod(argv[i], &nptr);
if (nptr != argv[i]) {
std::string s;
if (std::istringstream(nptr) >> s) {
std::cout << "In '" << argv[i]
<< "', double is " << d
<< " and string is '" << s << "'\n";
continue;
}
}
std::cout << "In '" << argv[i]
<< "', conversion failed.\n";
}
return 0;
}
(Live on coliru.)
This looks like a problem for good old strtod.
char* end;
double d = strtod(string.c_str(), &end);
end will then point to the start of the char* array that should form str;
str = end; /*uses string& operator= (const char*)*/
will then copy the relevant contents into str. Since it will take a value copy, there's no concern about c_str() being invalidated.
(Note that if string contains no leading numeric part, then d will be set to zero).
string number;
double an_number;
number="9994324.34324324343242";
an_number=atof(number.c_str());
cout<<"string: "<<number<<endl;
cout<<"double: "<<an_number;
cin.ignore();
ANS:
string: 9994324.34324324343242
double: 9.99432e+006

Resources