I am using gnuplot-iostream for c++,my problem is like below:
gp << "set object 1 rect from 3,1 to 3.2,4 fc lt 1 \n";
In the numbers of above, can we use some variables in c++ to replace them? and how to do that? Adding one rectangle is easy, but when I want to add more, that will be very intractable.
I try several ways ,but it does not work.
Thanks ahead!
Never used gnuplot-iostream, but maybe some vanilla C++ will help you, iostream is just a pipe to console, so you cant interrupt the buffer but concatenate information, you could do something like this:
gp << "set object " << 1 << " rect from "
<< 3,1 << " to " << 3.2 << "," << 4 << " fc lt 1 \n";
But i suppose you don't want to do that.
I'd create a struct and overload the << operator to return whatever you need.
struct Rect {
float from[2];
float to[2];
}
std::ostream& operator<<(std::ostream& os, const Rect& obj)
{
std::string formated = "from "
+ std::to_string(obj.from[0]) + ","
+ std::to_string(obj.from[1]) + " to "
+ std::to_string(obj.to[0]) + ","
+ std::to_string(obj.to[1]);
os << formated;
return os;
}
So you can just define rectangles and pass them to the stream
Rect r1 = {{2,41},{63,1.4}};
std::cout << r1; // "from 2,41 to 63,1.4"
I am trying to write to a file and am having trouble with the string not writing.
From what I have been able to figure out, my string will only print if I place a '\n' after it. The problem is I am trying to write it to a file and it has to be all in line with other information.
Sample of what I am trying to make my file look like:
1111 Last, First 10 20 $30.00
What it actually writes:
1111 10 20 $30.00
This is what i have tried and it will only print the last 3 items. If I place a '\n' after getName() then it prints everything fine:
ofstream outputFile("somefile.txt");
outputFile << std::setw(10) << getAccount()
<< std::setw(10) << getName() // returns a string
<< std::setw(10) << getNum1()
<< std::setw(10) << getNum2()
<< std::setw(10) << getTotal() << endl;
I have tried calling flush after getName() but it did not work
outputFile.flush()
I am supposed to store the last and first name separately.
string getName() const
{
string full = last + ", " + first;
return full;
}
I'm assuming you actually specify a name for the output file, e.g.
std::ofstream outputFile("some-file.txt");
Assuming this is sorted, have a look at std::setw(n) from <iomanip> and make sure your outputs are somehow separated. For example, you might want to use
outputFile << std::setw(8) << getAccount() << ' '
<< std::setw(20) << getName() << ' '
<< std::setw(6) << getNum1() << ' '
<< std::setw(6) << getNum2() << ' '
<< getTotal() << '\n';
... and if you really want to make sure the output is immediately written to the file rather than buffered:
outputFile << std::flush;
(which is equivalent to std::outputFile.flush(); but using cuter syntax).
Based on comments mentioned above, I would guess you ended up with names containing a '\r' right at the end: this way, it looks as if there is nothing but actually the characters are just overwritten by characters coming later. You can remove the carriage return characters using
str.erase(std::remove(str.begin(), str.end(), '\r'), str.end());
In C a space can be included in a printf formatting flag which results in positive numbers being prefixed with a space. This is a useful feature for aligning signed values. I can't figure out how to do the same in C++. In C:
double d = 1.2;
printf("%f\n",d);
printf("%+f\n",d);
printf("% f\n",d);
produces:
1.2
+1.2
1.2
Using ostream, I can do the first two, but how do I do the third?
int d = 1.2;
std::cout << d << std::endl;
std::cout << std::showpos << d << std::endl;
// ??????????????
EDIT: There seems to be some confusion about whether or not I just want to prefix all of my values with a space. I only want to prefix positive values with a space, similar to a) like the printf space flag does and b) similar to what showpos does, except a space rather than a '+'. For example:
printf("%f\n", 1.2);
printf("%f\n", -1.2);
printf("% f\n", 1.2);
printf("% f\n", -1.2);
1.2
-1.2
1.2
-1.2
Note that the third value is prefixed with a space while the fourth (negative) value is not.
You can use setfill and setw, like this:
cout << setw(4) << setfill(' ') << 1.2 << endl;
cout << setw(4) << setfill(' ') << -1.2 << endl;
This produces the following output:
1.2
-1.2
Don't forget to include <iomanip> in order for this to compile (link to ideone).
I don't have my standard with me and I'm doing this stuff too rarely to be confident about it: There are two ingredients to achieving this with IOStreams:
Use std:: showpos to have an indicator of positive values be shown. By default this will use +, of course.
I think the + is obtained using std::use_facet<std::ctype<char> >(s.get_loc()).widen('+'). To turn this into a space you could just use a std::locale with a std::ctype<char> facet installed responding with a space to the request to widen +.
That is, something like this:
struct my_ctype: std::ctype<char> {
char do_widen(char c) const {
return c == '+'? ' ': this->std::ctype<char>::do_widen(c);
}
};
int main() {
std::locale loc(std::locale(), new my_ctype);
std::cout.imbue(loc);
std::cout << std::showpos << 12.34 << '\n';
}
(the code isn't tested and probably riddled with errors).
How about
std::cout << (d >= 0 ? " ":"") << d << std::endl;
std::cout << " " << my_value;
If you need space only for positive:
if (my_value >=0 ) cout << " "; cout << my_value;
I generate a set of data files. As the files are supposed to be readable, they text files (opposed to binary files).
To output information to my files, I used very comfortable std::ofstream object.
In the beginning, when the data to be exported was smaller, the time needed to write to the files was not noticeable. However, as the information to be exported has accumulated, it takes now around 5 minutes to generate them.
As I started being bothered by waiting, my question is obvious: Is there any faster alternative to std::ofstream, please? In case there is faster alternative, will it be worth of rewritting my application? In other words, could the time saved be +50%? Thank you.
Update:
I was asked to show you my code that generates the above files, so here you are - the most time consuming loop:
ofstream fout;
fout.open(strngCollectiveSourceFileName,ios::out);
fout << "#include \"StdAfx.h\"" << endl;
fout << "#include \"Debug.h\"" << endl;
fout << "#include \"glm.hpp\"" << endl;
fout << "#include \"" << strngCollectiveHeaderFileName.substr( strngCollectiveHeaderFileName.rfind(TEXT("\\")) + 1) << "\"" << endl << endl;
fout << "using namespace glm;" << endl << endl << endl;
for (unsigned int nSprite = 0; nSprite < vpTilesetSprites.size(); nSprite++ )
{
for(unsigned int nFrameSet = 0; nFrameSet < vpTilesetSprites[nSprite]->vpFrameSets.size(); nFrameSet++)
{
// display index definition
fout << "// Index Definition: " << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->GetLongDescription() << "\n";
string strngIndexSignature = strngIndexDefinitionSignature;
strngIndexSignature.replace(strngIndexSignature.find(TEXT("#aIndexArrayName#")), strlen(TEXT("#aIndexArrayName#")), TEXT("a") + vpTilesetSprites[nSprite]->GetObjectName() + vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->GetFrameSetName() + TEXT("IndexData") );
strngIndexSignature.replace(strngIndexSignature.find(TEXT("#ClassName#")), strlen(TEXT("#ClassName#")), strngCollectiveArrayClassName );
fout << strngIndexSignature << "[4] = {0, 1, 2, 3};\t\t" << "// " << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->GetShortDescription() << ": Index Definition\n\n";
// display vertex definition
fout << "// Vertex Definition: " << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->GetLongDescription() << "\n";
string strngVertexSignature = strngVertexDefinitionSignature;
strngVertexSignature.replace(strngVertexSignature.find(TEXT("#aVertexArrayName#")), strlen(TEXT("#aVertexArrayName#")), TEXT("a") + vpTilesetSprites[nSprite]->GetObjectName() + vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->GetFrameSetName() + TEXT("VertexData") );
strngVertexSignature.replace(strngVertexSignature.find(TEXT("#ClassName#")), strlen(TEXT("#ClassName#")), strngCollectiveArrayClassName );
fout << strngVertexSignature << "[" << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->GetFramesCount() << "] =\n";
fout << "{\n";
for (int nFrameNo = 0; nFrameNo < vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->GetFramesCount(); nFrameNo++)
{
fout << "\t" << "{{ vec4(" << fixed << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->vpFrames[nFrameNo]->aVertices[0].vPosition.fx << "f, " << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->vpFrames[nFrameNo]->aVertices[0].vPosition.fy << "f, " << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->vpFrames[nFrameNo]->aVertices[0].vPosition.fz << "f, " << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->vpFrames[nFrameNo]->aVertices[0].vPosition.fw << "f), vec2(" << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->vpFrames[nFrameNo]->aVertices[0].vTextureUV.fu << "f, " << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->vpFrames[nFrameNo]->aVertices[0].vTextureUV.fv << "f) }, // " << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->GetShortDescription() << " vertex 1: vec4(x, y, z, w), vec2(u, v) \n";
fout << "\t" << " { vec4(" << fixed << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->vpFrames[nFrameNo]->aVertices[1].vPosition.fx << "f, " << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->vpFrames[nFrameNo]->aVertices[1].vPosition.fy << "f, " << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->vpFrames[nFrameNo]->aVertices[1].vPosition.fz << "f, " << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->vpFrames[nFrameNo]->aVertices[1].vPosition.fw << "f), vec2(" << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->vpFrames[nFrameNo]->aVertices[1].vTextureUV.fu << "f, " << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->vpFrames[nFrameNo]->aVertices[1].vTextureUV.fv << "f) }, // " << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->GetShortDescription() << " vertex 2: vec4(x, y, z, w), vec2(u, v) \n";
fout << "\t" << " { vec4(" << fixed << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->vpFrames[nFrameNo]->aVertices[2].vPosition.fx << "f, " << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->vpFrames[nFrameNo]->aVertices[2].vPosition.fy << "f, " << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->vpFrames[nFrameNo]->aVertices[2].vPosition.fz << "f, " << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->vpFrames[nFrameNo]->aVertices[2].vPosition.fw << "f), vec2(" << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->vpFrames[nFrameNo]->aVertices[2].vTextureUV.fu << "f, " << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->vpFrames[nFrameNo]->aVertices[2].vTextureUV.fv << "f) }, // " << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->GetShortDescription() << " vertex 3: vec4(x, y, z, w), vec2(u, v) \n";
fout << "\t" << " { vec4(" << fixed << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->vpFrames[nFrameNo]->aVertices[3].vPosition.fx << "f, " << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->vpFrames[nFrameNo]->aVertices[3].vPosition.fy << "f, " << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->vpFrames[nFrameNo]->aVertices[3].vPosition.fz << "f, " << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->vpFrames[nFrameNo]->aVertices[3].vPosition.fw << "f), vec2(" << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->vpFrames[nFrameNo]->aVertices[3].vTextureUV.fu << "f, " << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->vpFrames[nFrameNo]->aVertices[3].vTextureUV.fv << "f) }}, // " << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->GetShortDescription() << " vertex 4: vec4(x, y, z, w), vec2(u, v) \n\n";
}
fout << "};\n\n\n\n";
}
}
fout.close();
If you don't want to use C file I/O then you can give a try to; FastFormat. Look at the comparison for more info.
How are vpTilesetSprites and vpTilesetSprites[nSprite] stored? Are they implemented with lists or arrays? There is a lot of indexed access to them, and if they are list-like structures, you'll spend a lot of extra time following needless pointers. Ed S.'s comment is right: giving the long indexed temporary variables and linebreaks could make it easier to read, and maybe faster, too:
fout << "// Index Definition: " << vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->GetLongDescription() << "\n";
string strngIndexSignature = strngIndexDefinitionSignature;
strngIndexSignature.replace(strngIndexSignature.find(TEXT("#aIndexArrayName#")), strlen(TEXT("#aIndexArrayName#")), TEXT("a") + vpTilesetSprites[nSprite]->GetObjectName() + vpTilesetSprites[nSprite]->vpFrameSets[nFrameSet]->GetFrameSetName() + TEXT("IndexData") );
strngIndexSignature.replace(strngIndexSignature.find(TEXT("#ClassName#")), strlen(TEXT("#ClassName#")), strngCollectiveArrayClassName );
vs
string idxsig = strngIndexDefinitionSignature;
sprite sp = vpTilesetSprites[nSprite];
frameset fs = sp->vpFrameSets[nFrameSet];
fout << "// Index Definition: " << fs->GetLongDescription() << "\n";
idxsig.replace(idxsig.find(TEXT("#aIndexArrayName#")), strlen(TEXT("#aIndexArrayName#")),
TEXT("a") + sp->GetObjectName() + fs->getFrameSetName() + TEXT("IndexData"));
idxsig.replace(idxsig.find(TEXT("#ClassName#")), strlen(TEXT("#ClassName#")),
strngCollectiveArrayClassName);
But, the much bigger problem is how you're using strings as templates; you're looking for a given text string (and computing the length of your needle string every single time you need it!) over and over again.
Consider this: You're performing the find and replace operations nSprite * nFrameSet times. Each time through, this loop:
makes a copy of strngIndexDefinitionSignature
creates four temporary string objects when concatenating static and dynamic strings
compute strlen(TEXT("#ClassName#"))
compute strlen(TEXT("#aIndexArrayName#"))
find start point of both
replace both texts with new texts
And that's just the first four lines of your loop.
Can you replace your strngIndexDefinitionSignature with a format string? I assume it currently looks like this:
"flubber #aIndexArrayName# { blubber } #ClassName# blorp"
If you re-write it like this:
"flubber a %s%sIndexData { blubber } %s blorp"
Then your two find and replace lines can be replaced with:
sprintf(out, index_def_sig, sp->GetObjectName(), fs->getFrameSetName(),
strngCollectiveArrayClassName);
This would remove two find() operations, two replace() operations, creating and destroying four temporary string objects, a string duplicate that was promptly over-written with two replace() calls, and two strlen() operations that return the same result every time (but aren't actually needed anyway).
You can then output your string with << as usual. Or, you can change sprintf(3) to fprintf(3), and avoid even the temporary C string.
Assuming you do it in large enough chunks, calling write() directly might be faster; that said, it's more likely that your biggest bottleneck doesn't have anything directly to do with std::ofstream. The most obvious thing is to make sure you aren't using std::endl (because flushing the stream frequently will kill performance). Beyond that, I would suggest profiling your app to see where it's actually spending the time.
The performance of ostream is probably not your actual issue; I suggest using a profiler to determine where your real bottlenecks are. If ostream turns out to be your actual problem, you can drop down to <cstdio> and use fprintf(FILE*, const char*, ...) for formatted output to a file handle.
The best answer will depend on what sort of text you are generating, and how you are generating it. C++ streams can be slow, but that mostly is because they can also do a lot more for you, such as locale-dependent formatting, and so on.
You may find speed ups with streams by bypassing some of the formatting (eg. ostream::write), or by writing characters directly to a streambuf instead (streambuf::sputn). Sometimes increasing the buffer size on the relevant streambuf helps (via streambuf::pubsetbuf).
If this isn't good enough, you might want to try C-style stdio files, eg fopen, fprintf, etc. It takes a little while to get used to the way the text is formatted if you're not used to that method but the performance is usually pretty good.
For the absolute top performance you usually have to go to OS-specific routines. Sometimes the direct low-level file routines are significantly better than the C stdio, but sometimes not - for example, I've seen some people say WriteFile on Win32 is the fastest method on Windows, whereas some Google hits report it as being slower than stdio. Another approach might be a memory-mapped file, eg. mmap + msync - this essentially uses your system memory as the disk and writes the actual data to disk in large blocks, which is likely to be near optimal. However you run the risk of losing all the data if you incur a crash half way for some reason, which may or may not be a problem for you.
I am trying to print the value of a const but it is not working. I am making a return to C++ after years so I know casting is a possible solution but I can't get that working either.
The code is as follows:
//the number of blanks surrounding the greeting
const int pad = 0;
//the number of rows and columns to write
const int rows = pad * 2 + 3;
const string::size_type cols = greeting.size() + pad * 2 + 2;
cout << endl << "Rows : " + rows;
I am trying to print the value of 'rows' without success.
You want:
cout << endl << "Rows : " << rows;
Note this has nothing to do with const - C++ does not allow you to concatenate strings and numbers with the + operator. What you were actually doing was that mysterious thing called pointer arithmetic.
You're almost there:
cout << endl << "Rows : " << rows;
The error is because "Rows : " is a string literal, thus is a constant, and generally speaking is not modified as you may think.
Going slightly further, you likely used + (colloquially used as a concatenation operation) assuming you needed to build a string to give to the output stream. Instead operator << returns the output stream when it is done, allowing chaining.
// It is almost as if you did:
(((cout << endl) << "Rows : ") << rows)
I think you want:
std::cout << std::endl << "Rows : " << rows << std::endl;
I make this mistake all the time as I also work with java a lot.
As others have pointed out, you need
std::cout << std::endl << "Rows : " << rows << std::endl;
The reason (or one of the reasons) is that "Rows : " is a char* and the + operator for char*s doesn't concatenate strings, like the one for std::string and strings in languages like Java and Python.