Let me explain the situation:
I have a class cAnimation with few methods
#include "SDL/SDL.h"
#include <vector>
#include <fstream>
using namespace std;
class cAnimation{
private:
vector<SDL_Rect> frames;
public:
cAnimation();
void setQntFrames(int n){
this->frames.resize(n);
ofstream log("qntframes.txt");
log << "capacity = " << this->frames.capacity();
}
void setFrame(int index,int x, int y, int w, int h){
this->frames[index].x = x;
this->frames[index].y = y;
this->frames[index].w = w;
this->frames[index].h = h;
ofstream log("setrect.txt");
log << "i = " << i
<< "x = " << this->frames.at(i).x
<< "y = " << this->frames.at(i).y
<< "w = " << this->frames.at(i).w
<< "h = " << this->frames.at(i).h;
}
SDL_Rect cAnimation::getFrame(int index){
return this->frames[index];
}
};
I'm doing this at my main.cpp (the includes are all ok)
vector<cAnimation> animation;
animation.resize(1);
animation[0].setQntFrames(10); // it's printing the right value on qntframes.txt
animation[0].setFrame(0,10,10,200,200) // it's printing the right values on setrect.txt
SDL_Rect temp = animation[0].getFrame(0);// here is the problem
ofstream log("square.txt");
log << "x = " << temp.x
<< "y = " << temp.y;
when i look to the square.txt log, some weird chars like squares appears and when i try to use de data of SDL_Rect temp, the application just terminate, what i'm doing wrong here to get the values?
You're probably outputting chars. When you output these to an ostream, you'll get the ASCII character, instead of the numeric value of the ASCII character. Try this:
log << "x = " << (int) temp.x
<< "y = " << (int) temp.y;
A 'char' is frequently used as short hand for a 1-byte integer. They work well for this, except that when you output them to a stream, it attempts to output them as an ASCII character, instead of as a one-byte integer. Casting the character to a true integer usually fixes the problem.
Related
I am a beginner at c++ programming, and this is only my second program. I am getting a consistent error of "expected unqualified-id before..." idk what it means and cannot solve it. This is on lines 21,27,29,33,35,38,40,43,45.48,54,56,59,61,64,66,70.
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <math.h>
using namespace std;
int main ();
int a, b, c, x,y;
int discriminant;
double x1, x2;
int countdataisinvalid=0;
int countdataisvalid=0;
int countnolastterm=0;
int countonexvalue=0;
int countnomiddleterm=0;
int counttwoxterms=0;
while(!cin.eof)
{
a*x*x+b*x+c;
}
if (a==0),
countdataisinvalid++;
{
cout << "A is 0, data invalid." << endl;
}
else if, (discriminant < 0),
countdataisinvalid++;
{
cout << "The square is a negative number, data invalid." << endl;
}
else,
countdataisvalid++;
{
cout << " Data set is valid." << endl;
}
if (c==0),
countnolastterm++;
{
cout << "C is 0, there is no last term." << endl;
}
{
x1 = (-b + sqrt(b*b-4*a*c))/(2*a);
x2 = (-b - sqrt(b*b-4*a*c))/(2*a);
cout.precision(3);
}
if (x1==x2),
countonexvalue++;
{
cout << "Only one x value." << endl;
}
else, if (x1==-x2),
countnomiddleterm++;
{
cout << "There is no middle term." << endl;
}
else
counttwoxterms++;
{
cout << "There are two x values." << endl;
}
{
y = a*x1*x1+b*x1+c
y = a*x2*x2+b*x2+c
cout << "When x is " << x << "y is " << y << endl;
}
Your code contains too many errors. You should learn C++ again with writing simple programs.
At least this code compiles.
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <math.h>
using namespace std;
int main ()
{ // use { to begin definition of function, not ;
// initialize ariables for in case the reading fails
int a = 0, b = 0, c = 0, x = 0, y = 0;
int discriminant = 0;
double x1 = 0, x2 = 0;
int countdataisinvalid=0;
int countdataisvalid=0;
int countnolastterm=0;
int countonexvalue=0;
int countnomiddleterm=0;
int counttwoxterms=0;
// you should read numbers instead of writing possibly infinite loop and meaningless statement
cin >> a >> b >> c >> x >> discriminant >> x1 >> x2;
if (a==0) // remove extra comma
{
countdataisinvalid++; // move this statement to right position
cout << "A is 0, data invalid." << endl;
}
else if (discriminant < 0) // remove extra commas
{
countdataisinvalid++; // move this statement to right position
cout << "The square is a negative number, data invalid." << endl;
}
else // remove extra comma
{
countdataisvalid++; // move this statement to right position
cout << " Data set is valid." << endl;
}
if (c==0) // remove extra comma
{
countnolastterm++; // move this statement to right position
cout << "C is 0, there is no last term." << endl;
}
{
x1 = (-b + sqrt(b*b-4*a*c))/(2*a);
x2 = (-b - sqrt(b*b-4*a*c))/(2*a);
cout.precision(3);
}
if (x1==x2) // remove extra comma
{
countonexvalue++; // move this statement to right position
cout << "Only one x value." << endl;
}
else if (x1==-x2) // remove extra commas
{
countnomiddleterm++; // move this statement to right position
cout << "There is no middle term." << endl;
}
else
{
counttwoxterms++; // move this statement to right position
cout << "There are two x values." << endl;
}
{
y = a*x2*x2+b*x2+c; // add semicolon and remove useless statement
cout << "When x is " << x << "y is " << y << endl;
}
return 0; // add a statement to return some value
} // add this as end of definition of function
I am trying to solve the relatively simple problem of being able to write a double to a file and then to read the file into a double again. Based on this answer I decided to use the human readable format.
I have successfully circumvented the problems some compilers have with nan and [-]infinity according to this question. With finite numbers I use the std::stod function to convert the string representation of a number into the number itself. But from time to time the parsing fails with numbers close to zero, such as in the following example:
#include <cmath>
#include <iostream>
#include <sstream>
#include <limits>
const std::size_t maxPrecision = std::numeric_limits<double>::digits;
const double small = std::exp(-730.0);
int main()
{
std::stringstream stream;
stream.precision(maxPrecision);
stream << small;
std::cout << "serialized: " << stream.str() << std::endl;
double out = std::stod(stream.str());
std::cout << "de-serialized: " << out << std::endl;
return 0;
}
On my machine the result is:
serialized: 9.2263152681638151025201733115952403273156653201666065e-318
terminate called after throwing an instance of 'std::out_of_range'
what(): stod
The program has unexpectedly finished.
That is, the number is too close to zero to be properly parsed. At first I thougth that the problem is that this number is denormal, but this doesn't seem to be the case, since the mantissa starts with a 9 and not a 0.
Qt on the other hand has no problems with this number:
#include <cmath>
#include <limits>
#include <QString>
#include <QTextStream>
const std::size_t maxPrecision = std::numeric_limits<double>::digits;
const double small = std::exp(-730.0);
int main()
{
QString string = QString::number(small, 'g', maxPrecision);
QTextStream stream(stdout);
stream.setRealNumberPrecision(maxPrecision);
stream << "serialized: " << string << '\n';
bool ok;
double out = string.toDouble(&ok);
stream << "de-serialized: " << out << '\n' << (ok?"ok":"not ok") << '\n';
return 0;
}
Outputs:
serialized: 9.2263152681638151025201733115952403273156653201666065e-318
de-serialized: 9.2263152681638151025201733115952403273156653201666065e-318
ok
Summary:
Is this a bug in the gcc implementation of standard library?
Can I circumvent this elegantly?
Should I just use Qt?
Answering question #2:
This is probably my "C-way" kind of thinking, but you could copy the double into a uint64_t (mem-copying, not type-casting), serialize the uint64_t instead, and do the opposite on de-serialization.
Here is an example (without even having to copy from double into uint64_t and vice-versa):
uint64_t* pi = (uint64_t*)&small;
stringstream stream;
stream.precision(maxPrecision);
stream << *pi;
cout << "serialized: " << stream.str() << endl;
uint64_t out = stoull(stream.str());
double* pf = (double*)&out;
cout << "de-serialized: " << *pf << endl;
Please note that in order to avoid breaking strict-aliasing rule, you actually do need to copy it first, because the standard does not impose the allocation of double and uint64_t to the same address-alignment:
uint64_t ismall;
memcpy((void*)&ismall,(void*)&small,sizeof(small));
stringstream stream;
stream.precision(maxPrecision);
stream << ismall;
cout << "serialized: " << stream.str() << endl;
ismall = stoull(stream.str());
double fsmall;
memcpy((void*)&fsmall,(void*)&ismall,sizeof(small));
cout << "de-serialized: " << fsmall << endl;
If you're open to other recording methods you can use frexp:
#include <cmath>
#include <iostream>
#include <sstream>
#include <limits>
const std::size_t maxPrecision = std::numeric_limits<double>::digits;
const double small = std::exp(-730.0);
int main()
{
std::stringstream stream;
stream.precision(maxPrecision);
int exp;
double x = frexp(small, &exp);
//std::cout << x << " * 2 ^ " << exp << std::endl;
stream << x << " * 2 ^ " << exp;
int outexp;
double outx;
stream.seekg(0);
stream >> outx;
stream.ignore(7); // >> " * 2 ^ "
stream >> outexp;
//std::cout << outx << " * 2 ^ " << outexp << std::endl;
std::cout << small << std::endl << outx * pow(2, outexp) << std::endl;
return 0;
}
I'm sure I'm doing something wrong, but I just can't figure it out. I've created an object with integer data members, and I want to have a member function return the quotient of it's members as a floating point value, which it does. It then appends some additional stuff. The output is below the program, which should run as is.
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
class Rational
{
public:
explicit Rational(int = 0, int = 1);
double getRationalAsDouble() const;
private:
int numerator;
int denominator;
};
Rational::Rational(int numerator, int denominator)
{
if (denominator == 0)
this->denominator = 1;
else
this->denominator = denominator;
this->numerator = numerator;
}
// ******* Problem Function *********
double Rational::getRationalAsDouble() const
{
double a = 0.0, b = 0.0;
a = static_cast<double>(numerator);
b = static_cast<double>(denominator);
cout << endl << "a = " << a;
cout << endl << "b = " << b;
cout << endl << "a/b = " << (a/b);
}
// ******** End Problem Function ********
int main()
{
{ //Create a new Scope so that I can view Destructor Message, not used here
Rational c(2, 6);
int data = 10;
cout << c.getRationalAsDouble(); // prints rational object c as double, but not really
cout << "\n\n";
} // End of Scope
return 0;
} // end main
And here's the output:
a = 2
b = 6
a/b = 0.3333332.31196e-317
I've been playing around, and if I change the function to have any regular division in it, it works fine. What's really interesting is if I add any output after the cout << endl << "a/b = " << (a/b); line, that output is handled before (a/b) part of the line. Any help would be greatly appreciated! Thank you in advance for your time.
Solution:
The function wasn't returning anything. When the code was changed to:
double Rational::getRationalAsDouble()
{
return static_cast<double>(numerator)/denominator;
}
It worked as expected. Thank you tc.
Three problems:
You want to print endl at the end of the line, not the "beginning". Your code ends up doing (effectively) cout << endl << "a/b = " << (a/b); ... cout << c.getRationalAsDouble(); cout << "\n\n"; which prints the two doubles 0.333333 and 2.31196e-317 next to each other with no space.
You want (perhaps) cout << "\n" << endl instead of cout << "\n\n". endl causes the stream to be flushed; plain "\n" might not.
Rational::getRationalAsDouble() is not returning a value. Listen to your compiler warnings.
The fix looks something like
double Rational::getRationalAsDouble() const
{
double a = 0.0, b = 0.0;
a = static_cast<double>(numerator);
b = static_cast<double>(denominator);
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "a/b = " << (a/b) << endl;
return a/b;
}
Your implementation of Rational::getRationalAsDouble() can be simplified to:
double Rational::getRationalAsDouble() const
{
return 1.0*numerator/denominator;
}
I think you had everything else there for debugging purposes, and hence are not really needed.
Is there a way to make setw and setfill pad the end of a string instead of the front?
I have a situation where I'm printing something like this.
CONSTANT TEXT variablesizeName1 .....:number1
CONSTANT TEXT varsizeName2 ..........:number2
I want to add a variable amount of '.' to the end of
"CONSTANT TEXT variablesizeName#" so I can make ":number#" line up on the screen.
Note: I have an array of "variablesizeName#" so I know the widest case.
Or
Should I do it manually by setting setw like this
for( int x= 0; x < ARRAYSIZE; x++)
{
string temp = string("CONSTANT TEXT ")+variabletext[x];
cout << temp;
cout << setw(MAXWIDTH - temp.length) << setfill('.') <<":";
cout << Number<<"\n";
}
I guess this would do the job but it feels kind of clunky.
Ideas?
You can use manipulators std::left, std::right, and std::internal to choose where the fill characters go.
For your specific case, something like this could do:
#include <iostream>
#include <iomanip>
#include <string>
const char* C_TEXT = "Constant text ";
const size_t MAXWIDTH = 10;
void print(const std::string& var_text, int num)
{
std::cout << C_TEXT
// align output to left, fill goes to right
<< std::left << std::setw(MAXWIDTH) << std::setfill('.')
<< var_text << ": " << num << '\n';
}
int main()
{
print("1234567890", 42);
print("12345", 101);
}
Output:
Constant text 1234567890: 42
Constant text 12345.....: 101
EDIT:
As mentioned in the link, std::internal works only with integer, floating point and monetary output. For example with negative integers, it'll insert fill characters between negative sign and left-most digit.
This:
int32_t i = -1;
std::cout << std::internal
<< std::setfill('0')
<< std::setw(11) // max 10 digits + negative sign
<< i << '\n';
i = -123;
std::cout << std::internal
<< std::setfill('0')
<< std::setw(11)
<< i;
will output
-0000000001
-0000000123
Something like:
cout << left << setw(MAXWIDTH) << setfill('.') << temp << ':' << Number << endl;
Produces something like:
derp..........................:234
herpderpborp..................:12345678
#include <iostream>
#include <iomanip>
int main()
{
std::cout
<< std::setiosflags(std::ios::left) // left align this section
<< std::setw(30) // within a max of 30 characters
<< std::setfill('.') // fill with .
<< "Hello World!"
<< "\n";
}
//Output:
Hello World!..................
I've been trying to format the output to the console for the longest time and nothing is really happening. I've been trying to use as much of iomanip as I can and the ofstream& out functions.
void list::displayByName(ostream& out) const
{
node *current_node = headByName;
// I have these outside the loop so I don't write it every time.
out << "Name\t\t" << "\tLocation" << "\tRating " << "Acre" << endl;
out << "----\t\t" << "\t--------" << "\t------ " << "----" << endl;
while (current_node)
{
out << current_node->item.getName() // Equivalent tabs don't work?
<< current_node->item.getLocation()
<< current_node->item.getAcres()
<< current_node->item.getRating()
<< endl;
current_node = current_node->nextByName;
}
// The equivalent tabs do not work because I am writing names,
// each of different length to the console. That explains why they
// are not all evenly spaced apart.
}
Is their anything that I can use to get it all properly aligned with each other?
The functions that I'm calling are self-explanatory and all of different lengths, so that don't align very well with each other.
I've tried just about everything in iomanip.
Think of it like using Microsoft Excel :)
You think of your stream as fields. So you set the width of the field first then you insert your text in that field. For example:
#include <iostream>
#include <iomanip>
#include <string>
int main()
{
using namespace std;
string firstName = "firstName",
secondName = "SecondName",
n = "Just stupid Text";
size_t fieldWidth = n.size(); // length of longest text
cout << setw(fieldWidth) << left << firstName << endl // left padding
<< setw(fieldWidth) << left << secondName << endl
<< setw(fieldWidth) << left << n << endl;
cout << setw(fieldWidth) << right << firstName << endl // right padding
<< setw(fieldWidth) << right << secondName << endl
<< setw(fieldWidth) << right << n << endl;
}
......
......
The field width means nothing but the width of the text + spaces. You could fill anything other than spaces:
string name = "My first name";
cout << setfill('_') << setw(name.size() + 10) << left << name;
.....
output::
My first name__________
......
I think the best way is to figure out your format then, write a new formatter that does all what you want:
#include <iostream>
#include <iomanip>
#include <string>
std::ostream& field(std::ostream& o)
{
// usually the console is 80-character wide.
// divide the line into four fields.
return o << std::setw(20) << std::right;
}
int main()
{
using namespace std;
string firstName = "firstName",
secondName = "SecondName",
n = "Just stupid Text";
size_t fieldWidth = n.size();
cout << field << firstName << endl
<< field << secondName << endl
<< field << n << endl;
}
If you started thinking about parametrized manipulators, only that accept one int or long parameter are easy to implement, other types are really obscure if you are not familiar with streams in C++.
Boost has a format library that allows you to easily format the ourput like the old C printf() but with type safety of C++.
Remember that the old C printf() allowed you to specify a field width. This space fills the field if the output is undersized (note it does not cope with over-sized fields).
#include <iostream>
#include <iomanip>
#include <boost/format.hpp>
struct X
{ // this structure reverse engineered from
// example provided by 'Mikael Jansson' in order to make this a running example
char* name;
double mean;
int sample_count;
};
int main()
{
X stats[] = {{"Plop",5.6,2}};
// nonsense output, just to exemplify
// stdio version
fprintf(stderr, "at %p/%s: mean value %.3f of %4d samples\n",
stats, stats->name, stats->mean, stats->sample_count);
// iostream
std::cerr << "at " << (void*)stats << "/" << stats->name
<< ": mean value " << std::fixed << std::setprecision(3) << stats->mean
<< " of " << std::setw(4) << std::setfill(' ') << stats->sample_count
<< " samples\n";
// iostream with boost::format
std::cerr << boost::format("at %p/%s: mean value %.3f of %4d samples\n")
% stats % stats->name % stats->mean % stats->sample_count;
}
Give up on the tabs. You should be able to use io manipulators to set the field width, the fill character, and the format flag (to get left or right justification). Use the same values for the headings as you do for the data, and everything should come out nicely.
Also beware that you've switched Rating and Acres in your example.
You can write a procedure that always print the same number of characters to standard output.
Something like:
string StringPadding(string original, size_t charCount)
{
original.resize(charCount, ' ');
return original;
}
And then use like this in your program:
void list::displayByName(ostream& out) const
{
node *current_node = headByName;
out << StringPadding("Name", 30)
<< StringPadding("Location", 10)
<< StringPadding("Rating", 10)
<< StringPadding("Acre", 10) << endl;
out << StringPadding("----", 30)
<< StringPadding("--------", 10)
<< StringPadding("------", 10)
<< StringPadding("----", 10) << endl;
while ( current_node)
{
out << StringPadding(current_node->item.getName(), 30)
<< StringPadding(current_node->item.getLocation(), 10)
<< StringPadding(current_node->item.getRating(), 10)
<< StringPadding(current_node->item.getAcres(), 10)
<< endl;
current_node = current_node->nextByName;
}
}