Hello I'm having problem with dividing two doubles on C++, on a basic C++ it's working fine, for example
double DfirstNumber = 4.3;
double DsecondNumber = 2.0;
double DthirdNumber = DfirstNumber/DsecondNumber;
std::cout << DthirdNumber;
but not on the code below:
#include <iostream>
#include <fstream>
#include <string>
#include <Windows.h>
#include <regex>
std::string getLastLine(std::ifstream& in)
{
std::string line;
while (in >> std::ws && std::getline(in, line)) // skip empty lines
;
return line;
}
int main()
{
double DfirstNumber;
double DsecondNumber;
while(true){
std::ifstream file("C:\\Users\\Admin\\Documents\\myfile.txt");
if (file)
{
std::string line = getLastLine(file);
Sleep(1000);
try {
std::regex re("\\d*\\.\\d*");
std::sregex_iterator next(line.begin(), line.end(), re);
int i = 0;
std::string firstNumber;
std::string secondNumber;
while (i < 3) {
std::smatch match = *next;
if (i == 1) {
firstNumber = match.str();
DfirstNumber = std::stof(firstNumber);
}
if (i == 2) {
secondNumber = match.str();
DsecondNumber = std::stof(secondNumber);
}
next++;
i++;
}
}
catch (std::regex_error&) {
std::cout << "regex error";
}
double DthirdNumber = DsecondNumber) / DfirstNumber;
std::cout << DthirdNumber << std::endl;
}
else{
std::cout << "Can't Open the file.\n";
}
}
}
I'm getting every second a new line on myfile.txt so I had to check the last line of file, then using regular expression to get the desired datas and store them to C++ variables.
This is how myfile.txt looks
Hello Name Name0.00042Surname NameSurname Name0.00042$100.03
Hello Name Name0.00143Surname NameSurname Name0.00143$100.53
Hello Name Name0.00342Surname NameSurname Name0.00342$100.32
..............................................^1stNr^.^2ndNr^
... and another program just continues to extract lines like these every second!
Could anyone explain to me why is this happening, because if I'm trying to divide for example
DfirstNumber = 407.33
DsecondNumber = 0.015982
I'm not getting 25486.79764735327 but I'm getting 25489.8
Related
Hi I need to find second to last word in a string. Right now below program is printing the last one.
#include <iostream>
#include <string>
using namespace std;
int main() {
string text{"some line with text"};
// find last space, counting from backwards
int i = text.length() - 2; // last character
while (i != 0 && !isspace(text[i]))
{
--i;
}
string lastword = text.substr(i+1); // +1 to skip leading space
cout << lastword << endl;
return 0;
}
Output: (Printing last word)
text
You can split the string into words and hold the previous word before saving the current word.
#include <iostream>
#include <string>
#include <sstream>
int main() {
std::string text{"some line with text"};
std::stringstream ss(text);
std::string previousword, lastword, newword;
while (ss >> newword) {
previousword = lastword;
lastword = newword;
}
std::cout << previousword << std::endl;
return 0;
}
Also note that using using namespace std; is discouraged.
You don't need any loops. Just add error checking:
int main() {
std::string text{ "some line with text" };
std::size_t pos2 = text.rfind(' ');
std::size_t pos1 = text.rfind(' ', pos2-1);
std::cout << text.substr(pos1+1, pos2-pos1-1) << std::endl;
return 0;
}
Just keep counting spaces until you arrive to the word you want or use a stringstream as MikeCAT proposed.
Here there is a function that finds any last word number without having to copy the entire string in a stringstream:
#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::endl;
string getNLastWord(string text, int n)
{
bool insideAWord = false;
int wordNum = 0;
int wordEnd = -1;
for(int i = text.size() - 1; i > 0; i--)
{
if(text[i] != ' ' && !insideAWord)
{
wordNum++;
insideAWord = true;
}
else if(text[i] == ' ')
{
insideAWord = false;
}
if(wordNum == n)
{
wordEnd = i;
break;
}
}
if(wordEnd == -1)
{
cout << "There are no " << n << " words from right." << endl;
}
else
{
int wordStart;
for(wordStart = wordEnd; wordStart > 0; wordStart--)
{
if(text[wordStart] == ' ')
{
wordStart++;
break;
}
}
return text.substr(wordStart,wordEnd+1-wordStart);
}
return "";
}
int main() {
string text = "some text";
cout << getNLastWord(text,2);
return 0;
}
I am trying to write a parser to read large text file in C++. Similar python code using readtable method is approximately 7 to 8 times faster.
I am wonder why it runs so slow in C++. Most of the time is taken in using istringstream to parse lines to separate table numbers. It will be great if someone can point issue with code or alternative to istringstream. The code is as below:
'''
#include <fstream>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
#include <chrono>
using namespace std::chrono;
int main()
{
auto start = high_resolution_clock::now();
std::ifstream inf{ "/Users/***/some.bed" };
std::istringstream iss;
int aprox_nlines = 7000000;
std::vector<int>* ptr_st = new std::vector<int>();
std::vector<int>& start_v = *ptr_st;
start_v.reserve(aprox_nlines);
std::vector<int>* ptr_en = new std::vector<int>();
std::vector<int>& end_v = *ptr_en;
end_v.reserve(aprox_nlines);
// If we couldn't open the output file stream for reading
if (!inf)
{
// Print an error and exit
std::cerr << "Uh oh, File could not be opened for reading!" << std::endl;
return 1;
}
int count=0;
std::string line;
int sstart;
int end_val;
std::string val;
if (inf.is_open())
{
while (getline(inf, line))
{
count += 1;
iss.str(line);
iss >> val;
iss >> sstart;
start_v.push_back(sstart);
iss >> end_val;
end_v.push_back(end_val);
}
std::cout << count<<"\n";
inf.close();
}
auto stop = high_resolution_clock::now();
auto duration = duration_cast<microseconds>(stop - start);
std::cout << "Time taken by function: " << duration.count() << " microseconds" <<"\n";
return 0;
}
'''
It seems using FILE * = fopen() it runs much better. It is around 10 times faster than istringstream. Compared to python inbuilt (readtable) function it is 33% faster.
'''
FILE * ifile = fopen("*/N.bed", "r");
size_t linesz = 60+1;
char * nline = new char[linesz];
char T[50], S[50];
int sn,en;
unsigned int i = 0;
while(getline(&nline, &linesz, ifile) > 0) {
i++;
//std::cout<<nline<<"\n";
sscanf(nline, "%s %d %d", T, &sn, &en);
start_v.push_back(sn);
end_v.push_back(en);
//std::cout<<T<<" "<< S <<"\n";
}
'''
I'm struggling to find a way to decrease the value in a string every time the string is shown.
Using the code below, consider that the 1st line of the text file is some text #N. #N should be replaced by a number decreasing from 18 to 1. When it reaches 0 it should go back to 18.
#include <algorithm>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
void find_and_replace(string & source, string const & find, string const & replace)
{
for (string::size_type i = 0; (i = source.find(find, i)) != string::npos;) {
source.replace(i, find.length(), replace);
i += replace.length();
}
}
int main(int argc, char * argv[])
{
std::ifstream fileIn("Answers.txt", std::ios::in | std::ios::binary);
string question;
string line;
if (!fileIn) {
cout << "Cannot open input file!" << endl;
return 1;
}
while (getline(fileIn, line)) {
if (line == "The answer can be found in a secret place in the woods.") {
fileIn.clear();
fileIn.seekg(0, ios::beg);
}
cout << "Ask a question followed by the Enter key. Or type 'exit' to Exit program.\n";
getline(cin, question);
system("CLS");
find_and_replace(line, "#N", "18");
if (question == "") {
cout << "Your input cannot be blank. Please try again.\n\n";
}
else if (question == "exit")
exit(0);
else {
cout << "Q: " + question
<< "\nA: " + line + "\n\n";
}
}
}
This code only changes #N to 18, nothing more.
Please help guys.
You have hardcoded the value to 18, and you don't have any code which decrements the number.
Try these changes
put this at the start of main
int tempVar=18;
char buffer[100];
and replace
find_and_replace(line, "#N", "18");
with
sprintf(buffer,"%d",tempVar--)
if(tempVar<0)
tempVar=18;
find_and_replace(line, "#N", buffer);
https://www.programiz.com/cpp-programming/library-function/cstdio/sprintf
You can use something like:
#include <sstream>
#include <string>
class Replacer
{
const std::string token_;
const int start_;
int current_;
public:
explicit Replacer(const std::string & token, int start)
: token_(token), start_(start), current_(start)
{
}
std::string replace(const std::string & str)
{
const std::size_t pos = str.find(token_);
if (pos == std::string::npos)
return str;
std::string ret(str);
std::ostringstream oss;
oss << current_;
ret.replace(pos, token_.size(), oss.str());
--current_;
if (current_ == 0)
current_ = start_;
return ret;
}
};
And then you can use it like:
std::string examples[] = {
"",
"nothing",
"some number #N",
"nothing",
"some other #N number",
"nothing",
"#N another test",
"nothing",
};
Replacer replacer("#N", 18);
for (int i = 0; i < 8; ++i)
std::cout << replacer.replace(examples[i]) << '\n';
I have some code that takes in a paragraph and starts a new line after every sentence.
I would like to buffer the output in the terminal with a new line, but adding "std::cout << endl;" outside of the loop does not seem to work. Any help in separating the input from the output if it is typed into a terminal.
I have commented out the code I expected to work, but which does not.
#include <iostream>
#include <string>
using namespace std;
int main() {
// std::cout << std::endl;
for (;;) {
string line;
getline(std::cin, line);
if (!cin) {
break;
}
for (unsigned int i = 0; i < line.length(); ++i) {
const string text = line.substr(i, 1);
if (text == "." || text == "?" || text == "!") {
std::cout << text;
std::cout << std::endl;
}else{
std::cout << text;
}
}
}
// std::cout << std::endl;
return 0;
}
The commented line will never work since it will never be called. You have an endless loop for(;;) before it.
I'm a beginner in c++ and required to write a c++ program to read and print a csv file like this.
DateTime,value1,value2
12/07/16 13:00,3.60,50000
14/07/16 20:00,4.55,3000
May I know how can I proceed with the programming?
I manage to get the date only via a simple multimap code.
I spent some time to make almost (read notice at the end) exact solution for you.
I assume that your program is a console application that receives the original csv-file name as a command line argument.
So see the following code and make required changes if you like:
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <map>
#include <string>
std::vector<std::string> getLineFromCSV(std::istream& str, std::map<int, int>& widthMap)
{
std::vector<std::string> result;
std::string line;
std::getline(str, line);
std::stringstream lineStream(line);
std::string cell;
int cellCnt = 0;
while (std::getline(lineStream, cell, ','))
{
result.push_back(cell);
int width = cell.length();
if (width > widthMap[cellCnt])
widthMap[cellCnt] = width;
cellCnt++;
}
return result;
}
int main(int argc, char * argv[])
{
std::vector<std::vector<std::string>> result; // table with data
std::map<int, int> columnWidths; // map to store maximum length (value) of a string in the column (key)
std::ifstream inpfile;
// check file name in the argv[1]
if (argc > 1)
{
inpfile.open(argv[1]);
if (!inpfile.is_open())
{
std::cout << "File " << argv[1] << " cannot be read!" << std::endl;
return 1;
}
}
else
{
std::cout << "Run progran as: " << argv[0] << " input_file.csv" << std::endl;
return 2;
}
// read from file stream line by line
while (inpfile.good())
{
result.push_back(getLineFromCSV(inpfile, columnWidths));
}
// close the file
inpfile.close();
// output the results
std::cout << "Content of the file:" << std::endl;
for (std::vector<std::vector<std::string>>::iterator i = result.begin(); i != result.end(); i++)
{
int rawLen = i->size();
for (int j = 0; j < rawLen; j++)
{
std::cout.width(columnWidths[j]);
std::cout << (*i)[j] << " | ";
}
std::cout << std::endl;
}
return 0;
}
NOTE: Your task is just to replace a vector of vectors (type std::vector<std::vector<std::string>> that are used for result) to a multimap (I hope you understand what should be a key in your solution)
Of course, there are lots of possible solutions for that task (if you open this question and look through the answers you will understand this).
First of all, I propose to consider the following example and to try make your task in the simplest way:
#include <iostream>
#include <sstream>
#include <vector>
#include <string>
using namespace std;
int main()
{
string str = "12/07/16 13:00,3.60,50000";
stringstream ss(str);
vector<string> singleRow;
char ch;
string s = "";
while (ss >> ch)
{
s += ch;
if (ss.peek() == ',' || ss.peek() == EOF )
{
ss.ignore();
singleRow.push_back(s);
s.clear();
}
}
for (vector<string>::iterator i = singleRow.begin(); i != singleRow.end(); i++)
cout << *i << endl;
return 0;
}
I think it can be useful for you.