How to print precise digits after E in scientific notation in c++ - c++11

the output of the code is 1.068950000E+002 instead the required output is 1.068950000E+02
#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
double c=106.895;
cout<<fixed<<setprecision(9)<<std::scientific<<C<<endl;
return 0;
}

You can't set the number of digits of the outputted exponent in scientific notation using the standard manipulators in C++.
One thing you could do is to remove or add a '0' to the resulting string, if needed.
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include <algorithm>
int main()
{
double c = 106.895;
std::stringstream ss;
ss.setf(std::ios_base::scientific | std::ios_base::uppercase);
ss << std::setprecision(9) << c;
auto number = ss.str();
// you can add the '0' if needed
size_t pos = number.size() - 3;
if ( !std::isdigit(int(number[pos])) )
{
if ( number[pos] == 'E' )
number.insert(pos + 1, "+0");
else
number.insert(pos + 1, 1, '0');
}
std::cout << number << '\n'; // --> 1.068950000E+002
// Or remove it
size_t pos_0 = number.size() - 3;
if ( number[pos_0] == '0' )
number.erase(pos_0, 1);
std::cout << number << '\n'; // --> 1.068950000E+02
}

Related

Using recursion inside a called constructor

Don't know where to begin on how to use recursion within a called constructor.
recursion.cpp
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
#include "MinilabRecursion.h"
MinilabRecursion::puzzleRecurse(int n)
{
int recurse(n) // <--- Don't know what to do here
{ //error: expected ',' or ';' before '{' token
if( n == 0 )
{
return 1;
}
if( n >= 1 )
{
return recurse(n - 1) + 4 * n;
}
}
} //error: expected '}' at end of input
driver.cpp
#include <iostream>
#include <string>
using namespace std;
#include "MinilabRecursion.h"
{
cout << "puzzleRecurse(1) returns: " << MinilabRecursion::puzzleRecurse(1) << endl;
cout << "puzzleRecurse(7) returns: " << MinilabRecursion::puzzleRecurse(7) << endl;
cin.get();
return 0;
}
recursion.h
#ifndef MINILABRECURSION_H
#define MINILABRECURSION_H
#include <iostream>
#include <string>
using namespace std;
class MinilabRecursion
{
public:
static int puzzleFormula(int n);
static int puzzleLoop(int n);
static int puzzleRecurse(int n);
};
#endif
The if statements within recursion.cpp should give me the desired outcome, but I do not know how to use recursion in this context.
I'm not sure I can make sense out of the code you posted. It seems you want to do the following, but are confused about some of the C++ basics:
int MinilabRecursion::puzzleRecurse(int n)
{
if (n == 0) {
return 1;
}
return puzzleRecurse(n - 1) + 4 * n;
}

The problem is i need the input of the string to accept a blank line

The program is supposed to receive a string, that can have blank lines, blank spaces, and break lines. So the problem is i can't use get line, because i don't know how many break lines the user will use.
I tried making a do while but it didn't work, the program stops working.
It was a do while, that would receive an char and using pushback insert in the string while the char was different to EOF. I don't know how else to do it, or why this do while doesn't work.
This code is using get line witch doesn't accept a break line.
'''''
#ifndef INDICE_H
#define INDICE_H
#include <cstddef>
struct Indice{
std::size_t f;
double p;
};
#endif
#include <iostream>
#include <sstream>
#include <string>
#include <iomanip>
#include <map>
#include "Indice.hpp"
int main()
{
std::string str;
std::getline(std::cin, str);
// Count the number of occurrences for each word
std::string word;
std::istringstream iss(str);
std::map<std::string,Indice> occurrences;
while (iss >> word) ++occurrences[word].f;
//Calculate the percentual each word
int total = 0.0;
for (std::map<std::string,Indice>::iterator it = occurrences.begin();
it != occurrences.end(); ++it)
{
total += it->second.f;
}
for (std::map<std::string,Indice>::iterator it = occurrences.begin();
it != occurrences.end(); ++it)
{
it->second.p = (static_cast<double>(it->second.f))/total;
}
// Print the results
for (std::map<std::string,Indice>::iterator it = occurrences.begin();
it != occurrences.end(); ++it)
{
if(it->first.size()>2)
std::cout << it->first << " " << it->second.f << " "<< std::fixed << std::setprecision(2) << it->second.p << std::endl;
}
return 0;
}
''''
Two possible solutions:
#include <iostream>
#include <string>
int main(){
std::string line;
while(std::cin >> line){
//Variable line contains your input.
}
//Rest of your code
return 0;
}
Or:
#include <iostream>
#include <string>
int main(){
std::string line;
while(std::getline(std::cin, line)){
if (line.empty()){
break;
}
//Variable line contains your input.
}
//Rest of your code
return 0;
}

Line-based parser with empty lines and attributes, how to ignore attribute

I'm using boost spirit to parse a line-based format, where empty lines are allowed. For this, i'm using something similar to the following grammar:
struct parser_type : public qi::grammar<std::string::iterator, qi::ascii::blank_type, std::vector<int>()>
{
typedef std::string::iterator Iterator;
parser_type() : parser_type::base_type(main)
{
element = qi::int_;
line %= element | qi::eps;
main %= +(line >> qi::eol);
}
qi::rule<Iterator, int()> element;
qi::rule<Iterator, qi::ascii::blank_type, int()> line;
qi::rule<Iterator, qi::ascii::blank_type, std::vector<int>()> main;
} parser;
This works fine, since the qi::eps together with the qi::eol matches empty lines. Nice (though i am open to other, perhaps better approaches to parse line-based formats with empty lines). However, the attribute of the line parser is an int, which is obviously not present on empty lines. Therefore, for an input of
1
4
the parser creates a vector with the content { 1, 0, 0, 4 }.
I want the line totally ignored, that is, i don't want any dummy object to be constructed to match the attribute of the line. Can this be done? Is there a better way to parse lines?
Here is a complete minimum example (the program needs a input file called "input", you can use my example above):
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
struct parser_type : public qi::grammar<std::string::iterator, qi::ascii::blank_type, std::vector<int>()>
{
typedef std::string::iterator Iterator;
parser_type() : parser_type::base_type(main)
{
element = qi::int_;
line = element | qi::eps;
main %= +(line >> qi::eol);
}
qi::rule<Iterator, int()> element;
qi::rule<Iterator, qi::ascii::blank_type, int()> line;
qi::rule<Iterator, qi::ascii::blank_type, std::vector<int>()> main;
} parser;
int main()
{
std::ifstream file("input");
std::stringstream buffer;
buffer << file.rdbuf();
std::string str = buffer.str();
auto iter = str.begin();
std::vector<int> lines;
bool r = qi::phrase_parse(iter, str.end(), parser, qi::ascii::blank, lines);
if (r && iter == str.end())
{
std::cout << "parse succeeded\n";
for(auto e : lines)
{
std::cout << e << '\n';
}
}
else
{
std::cout << "parse failed. Remaining unparsed: " << std::string(iter, str.end()) << '\n';
}
}
This rule:
line = element | eps;
causes you to loose the information you need. By accepting no-match (eps), you force it to just return the value-initialized attribute you declared (int in the rul signature).
So, drop that, and then I usually write this kind of a repeat using the list-operator (%):
line = element;
main = -line % qi::eol;
This works:
Live On Coliru
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
struct parser_type : public qi::grammar<std::string::iterator, qi::ascii::blank_type, std::vector<int>()>
{
typedef std::string::iterator Iterator;
parser_type() : parser_type::base_type(main)
{
element = qi::int_;
line = element;
main = -line % qi::eol;
}
qi::rule<Iterator, int()> element;
qi::rule<Iterator, qi::ascii::blank_type, int()> line;
qi::rule<Iterator, qi::ascii::blank_type, std::vector<int>()> main;
} parser;
int main()
{
std::ifstream file("input");
std::stringstream buffer;
buffer << file.rdbuf();
std::string str = buffer.str();
auto iter = str.begin();
std::vector<int> lines;
bool r = qi::phrase_parse(iter, str.end(), parser, qi::ascii::blank, lines);
if (r && iter == str.end())
{
std::cout << "parse succeeded\n";
for(auto e : lines)
{
std::cout << e << '\n';
}
}
else
{
std::cout << "parse failed. Remaining unparsed: " << std::string(iter, str.end()) << '\n';
}
}
Prints
parse succeeded
1
4

<random> generates same number in Windows, but not in Linux

I do not why, but in Windows (with MinGW) this code generates for 3/4 time the same pseudo-random number.
I think that is because I set badly the seed, but I can not correct it.
Thank you for your help.
Here there is the code:
#include <iostream>
#include <random>
#include <chrono>
int main()
{
double Nprove = 50.0;
double p = 0.2;
const int Ncampioni = 100; // number of samples
int cappa = 0;
double sample[Ncampioni];
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::mt19937 gen(seed);
std::binomial_distribution<> d(Nprove, 0.9);
for(cappa = 0; cappa < Ncampioni; cappa = cappa +1){
sample[cappa] = d(gen);
std::cout << cappa << "," << sample[cappa] << std::endl;
}
}

Interleave random numbers

I would like to interleave a random number with some alphanumeric characters, for example: HELLO mixed with the random number 25635 → H2E5L6L3O5. I know %1d controls the spacing, although I'm not sure how to interleave text between the random numbers or how accomplish this.
Code:
int main(void) {
int i;
srand(time(NULL));
for (i = 1; i <= 10; i++) {
printf("%1d", 0 + (rand() % 10));
if (i % 5 == 0) {
printf("\n");
}
}
return 0;
}
btw - if my random number generator isn't very good i'm open to suggestions - thanks
If you're okay with using C++11, you could use something like this:
#include <iostream>
#include <random>
#include <string>
int main() {
std::random_device rd;
std::default_random_engine e1(rd());
std::uniform_int_distribution<int> uniform_dist(0, 9);
std::string word = "HELLO";
for (auto ch : word) {
std::cout << ch << uniform_dist(e1);
}
std::cout << '\n';
}
...which produces e.g.:
H3E6L6L1O5
If you're stuck with an older compiler, you could use rand and srand from the standard C library for your random numbers:
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
int main() {
std::srand(std::time(NULL));
std::string word = "HELLO";
for (int i = 0; i < word.size(); ++i) {
std::cout << word[i] << (rand() % 10);
}
std::cout << '\n';
}

Resources