Code that can output changing number to both terminal and file - c++

I have a c++ program which writes changing numbers to screen, something in the vein of the following snippet:
stringstream ss, ssd; ss << 0; int decs=0; ssd << decs;
cout << "Number ";
for(int i=1;i<=1000;i++) {
cout << ss.str() << " Decades: " << decs; cout.flush();
int l=ss.str().length()+12+ssd.str().length();
for(int j=0;j<l;j++) cout << "\b";
this_thread::sleep_for (chrono::milliseconds(100));
ss.str(""); ss << i;
if(i%10==0) {
decs++; ssd.str(""); ssd << decs;
}
}
This works fine, but sometimes (not always) I would like to send the output to a file instead of the terminal, using e.g. ./prog > out.txt. Here the backspace character \b doesn't delete character but outputs some symbol (googling tells me this is not surprising).
One option would be to e.g. only output the data at the end of the calculation when printing to a file. But this would entail different code for terminal/file, switching with an input parameter for example. Is there a way I can do this without having separate code for terminal/file output?
I am using cygwin on Windows 7.

Try to write whole string every time and to write just '\r' without '\n'
stringstream ss, ssd; ss << 0; int decs=0; ssd << decs;
for(int i=1;i<=1000;i++) {
cout << "Number " << ss.str() << " Decades: " << decs; cout.flush();
//int l=ss.str().length()+12+ssd.str().length();
//for(int j=0;j<l;j++) cout << "\b";
cout << '\r';
this_thread::sleep_for (chrono::milliseconds(100));
ss.str(""); ss << i;
if(i%10==0) {
decs++; ssd.str(""); ssd << decs;
}
}
In this case you'll have the full output in the file.

A possible workaround may be to use std::cerr for intermediate result (and so for '\b'),
and std::cout for final result.

Related

C++ Writing a vector of objects to file

I have a vector of objects with quite a few variables (name, type, length etc) which I am trying to write to file.
vector <Boat> berths;
void Boat::write_boats()
{
ofstream file("records_file.txt");
for (Boat b : berths)
{
file << owner_name << "; " << boat_name << "; " << type << "; " << length << "; " << draft << '\n';
}
file.close();
}
void save_records()
{
for (unsigned int i = 1; i < berths.size(); i++)
{
berths[i].write_boats();
}
}
I call the save_records() function with a menu option that ends the application.
The output i get is:
1) If i register a boat object, close the app and go in the text file, I can see the object written twice.
2) If i register 2 objects and I go in the text file, only the last (second) object has been written to file, and it shows 3 times.
Now my questions are:
What causes the double output?
Why is only the last object written to file? I thought the loop would fix that but it didn't
One problem I can spot: "i = 1" in the loop should be "i = 0", because array indexes start from 0. The second: you iterate 'berths' array, so you will get N * N boats saved, if you have N boats in 'berths'.
The simple solution would be
void save_all()
{
ofstream file("records_file.txt");
for (Boat b : berths)
{
file << b.owner_name << "; " << b.boat_name << "; " << b.type << "; " << b.length << "; " << b.draft << '\n';
}
}
If you have to make 'owner_name', 'type' and the rest of the fields as private, then you would have to declare
void Boat::save(std::ofstream& f) const
{
file << owner_name << "; " << boat_name << "; " << type << "; " << length << "; " << draft << '\n';
}
and modify 'save_all' to
void save_all()
{
ofstream file("records_file.txt");
for (const Boat& b: berths)
b.save(f);
}
Every time ofstream file("records_file.txt"); is called, it created a new file and overwrite it, if you want to append in the file you have to open it by this way:
ofstream file("records_file.txt", ios::app);
See: http://www.cplusplus.com/doc/tutorial/files/
I guess you are using something like while(!bla.eof()), if so then it reaches the end of the buffer but it needs to go past it to raise the flag, so you have the same output twice at the end.

Overcoming Issues When Downloading a CSV File for Parsing. Linux vs Windows New Line Charachter

I am attempting to analyze stock data using historical Stock prices. This data can be downloaded from Yahoo Finance(https://finance.yahoo.com/quote/AAPL/history?p=AAPL) as a CSV file. However when I download the file it is organized as one line and not separated by a new line at the end of each row. I have read that this is because different OS uses different characters to denote new lines. Are there ways to overcome this issue when downloading a file or in a text editor, or should I modify my code to accommodate the format the files are downloaded in. I am coding in C++ on Windows 10 and viewing files in NotePad. (Im also new to StackOverFlow so advice on asking questions is appreciated.)
Example:
How the code should be
2017-10-16,157.899994,160.000000,157.649994,159.880005,159.307312,24121500
2017-10-17,159.779999,160.869995,159.229996,160.470001,159.895203,18997300
2017-10-18,160.419998,160.710007,159.600006,159.759995,159.187729,16374200
2017-10-19,156.750000,157.080002,155.020004,155.979996,155.421280,42584200
2017-10-20,156.610001,157.750000,155.960007,156.250000,155.690308,23974100
How it is downloaded
2017-10-16,157.899994,160.000000,157.649994,159.880005,159.307312,241215002017-10-17,159.779999,160.869995,159.229996,160.470001,159.895203,189973002017-10-18,160.419998,160.710007,159.600006,159.759995,159.187729,163742002017-10-19,156.750000,157.080002,155.020004,155.979996,155.421280,425842002017-10-20,156.610001,157.750000,155.960007,156.250000,155.690308,23974100
my code to read in the file
void Stock::readData(filename){
ifstream stream;
stream.open(fileName);
if(stream.fail()){
cout << "The file " << fileName <<" failed to open." << endl;
return;
}
string line ="";
cout << line << endl;
while(!stream.eof()){
// cout << '*' << endl;
getline(stream,line);
//cout << line << endl;
string parsed[7];
int num = Spliter(line, ',', parsed, 7);
string tempDate;
float tempOpen;
float tempHigh;
float tempLow;
float tempClose;
float tempCloseAdj;
float tempVolume;
/*for(int i=0; i<num; i++){
cout << parsed[i] << endl;
}*/
tempDate = parsed[0];
tempOpen = stof(parsed[1]);
tempHigh = stof(parsed[2]);
tempLow = stof(parsed[3]);
tempClose = stof(parsed[4]);
tempCloseAdj = stof(parsed[5]);
tempVolume = stof(parsed[6]);
/*
cout <<(tempDate) << " ";
cout << (tempOpen)<< " ";
cout << (tempHigh)<< " ";
cout << (tempLow)<< " ";
cout << (tempClose)<< " ";
cout << tempCloseAdj<< " ";
cout << (tempVolume) << endl;
*/
vector<float> v;
dates.push_back(tempDate);
data.push_back(v);
data[numberOfDays].push_back(tempOpen);
data[numberOfDays].push_back(tempHigh);
data[numberOfDays].push_back(tempLow);
data[numberOfDays].push_back(tempClose);
data[numberOfDays].push_back(tempCloseAdj);
data[numberOfDays].push_back(tempVolume);
// cout << '#' << endl;
numberOfDays++;
}
stream.close();
}
I figured out the problem. In order to convert the EOL line endings between platforms like Mac, Windoxs or Unix download a text editor such as Notepad++. Open the file in notepadd++ and go to the edit tab. Find the EOL COnversion button and use it to convert the file.

Problems when reading bytes from a midi file

I want to read the single bytes of a midi file, and I wrote a simple program to try to do that:
ifstream file{"D:\Descargas\OutFile.midi" };
if (!file.is_open())
cout << "Not open" << endl; // It passes this test
char c;
for (unsigned i = 0; i < 100; ++i) {
file >> c;
cout << c << endl; // Output is -52, but it must output 4D which is 77 in decimal
}
but as I wrote, the output is not good and I don't know where I'm going wrong.
You need to configure the output to print in hexedecimal and to pad each number with 0 to a width of 2. Also you need to cast the character c to an int so it doesn't get output as a letter:
// configure output
cout << std::hex << std::setfill('0') << std::uppercase;
char c;
// read in the while block so you only use it if the read succeeds
while(file >> c)
{
// set the width and convert to an integer
cout << std::setw(2) << int(c) << endl;
}
It actually was that the \ character must be escaped.

I am trying to write out the results of a process to a text file, the issue I have is with the alignment of the columns

I am sure someone somewhere has had this same issue but I have looked far and wide (including here on the stackoverflow) to find out how to properly align my columns in an output file. The following is the complete code I am using (for an event generator called Pythia 8 of which C++ is the primary language):
using namespace Pythia8;
int main()
{
Pythia pythia;
pythia.readString("Top:gg2ttbar = 1");
pythia.init(2212, 2212, 14000.);
ofstream myfile;
myfile.open("ttbar.txt");
for (int iEvent = 0; iEvent < 1; ++iEvent)
{
if (!pythia.next()) continue;
vector<double> part;
for (int i = 0; i < pythia.event.size(); ++i)
{
if (pythia.event[i].status() == 91) part.push_back(i);
}
myfile << "N = " << part.size() << endl;
for (int j = 0; j < (int(part.size()) - 1); ++j)
{
myfile << left << setw(4) << int(part[j]);
myfile << setw(4) << left << pythia.event[part[j]].name() << " "
<< right << pythia.event[part[j]].id() << " "
<< pythia.event[part[j]].px() << " " << pythia.event[part[j]].py()
<< " " << pythia.event[part[j]].pz() << " "
<< pythia.event[part[j]].m() << " " << pythia.event[part[j]].pT() << endl;
}
}
pythia.stat();
myfile.close();
return 0;
}
The issue occurs near the bottom where the loop that writes out the text file starts, as it is currently written in the above code, the first two columns are mashed together:
N = 665
1777pi- -211 1.19978 0.715507 32.7878 0.13957 1.39694
1779pi+ 211 -8.24173 6.07047 -31.6818 0.13957 10.2361
That is the first couple lines of the output (the program shows the line number where a certain particle is produced and relevant information about it like the name, mass...etc.). I cannot seem to format it so I don't have to use the inserted spaces that I put in by hand.
as it is currently written in the above code, the first two columns are mashed together
well, yes, you explicitly wrote the first two columns with no whitespace between them:
myfile << left << setw(4) << int(part[j]);
myfile << setw(4) << left << pythia.event[part[j]].name() << ...
If you want a general way to format this without worrying adding manual whitespace, split it into two steps:
create a vector<string> containing the columns for each line (you can just use an ostringstream to format each column individually)
write a function to take that vector and write it to an ostream, with spaces between.
std::copy(begin, end, std::ostream_iterator(myfile, " "));
will be sufficient if you just want a fixed number of spaces between each column

C++ cout printing slowly

I noticed if I print out a long string(char*) using cout it seems to print 1 character at a time to the screen in Windows 7, Vista, and Linux(using putty) using Visual C++ 2008 on Windows and G++ on Linux. Printf is so much faster I actually switched from cout to printf for most printing in a project of mine. This is confusing me because this question makes it seem like I'm the only one having this issue.
I even wrote a cout replacement that looks like it beats the pants off of cout on my comp -
class rcout
{
public:
char buff[4096];
unsigned int size;
unsigned int length;
rcout()
{
size = 4096;
length = 0;
buff[0] = '\0';
}
~rcout()
{
printf("%s", buff);
}
rcout &operator<<(char *b)
{
strncpy(buff+length, b, size-length);
unsigned int i = strlen(b);
if(i+length >= size)
{
buff[size-1] = '\0';
printf("%s", buff);
b += (size-length) -1;
length = 0;
return (*this) << b;
}
else
length += i;
return (*this);
}
rcout &operator<<(int i)
{
char b[32];
_itoa_s(i, b, 10);
return (*this)<<b;
}
rcout &operator<<(float f)
{
char b[32];
sprintf_s(b, 32, "%f", f);
return (*this)<<b;
}
};
int main()
{
char buff[65536];
memset(buff, 0, 65536);
for(int i=0;i<3000;i++)
buff[i] = rand()%26 + 'A';
rcout() << buff << buff <<"\n---"<< 121 <<"---" << 1.21f <<"---\n";
Sleep(1000);
cout << "\n\nOk, now cout....\n\n";
cout << buff << buff <<"\n---"<< 121 <<"---" << 1.21f <<"---\n";
Sleep(1000);
cout << "\n\nOk, now me again....\n\n";
rcout() << buff << buff <<"\n---"<< 121 <<"---" << 1.21f <<"---\n";
Sleep(1000);
return 0;
}
Any ideas why cout is printing so slowly for me?
NOTE: This experimental result is valid for MSVC. In some other implementation of library, the result will vary.
printf could be (much) faster than cout. Although printf parses the format string in runtime, it requires much less function calls and actually needs small number of instruction to do a same job, comparing to cout. Here is a summary of my experimentation:
The number of static instruction
In general, cout generates a lot of code than printf. Say that we have the following cout code to print out with some formats.
os << setw(width) << dec << "0x" << hex << addr << ": " << rtnname <<
": " << srccode << "(" << dec << lineno << ")" << endl;
On a VC++ compiler with optimizations, it generates around 188 bytes code. But, when you replace it printf-based code, only 42 bytes are required.
The number of dynamically executed instruction
The number of static instruction just tells the difference of static binary code. What is more important is the actual number of instruction that are dynamically executed in runtime. I also did a simple experimentation:
Test code:
int a = 1999;
char b = 'a';
unsigned int c = 4200000000;
long long int d = 987654321098765;
long long unsigned int e = 1234567890123456789;
float f = 3123.4578f;
double g = 3.141592654;
void Test1()
{
cout
<< "a:" << a << “\n”
<< "a:" << setfill('0') << setw(8) << a << “\n”
<< "b:" << b << “\n”
<< "c:" << c << “\n”
<< "d:" << d << “\n”
<< "e:" << e << “\n”
<< "f:" << setprecision(6) << f << “\n”
<< "g:" << setprecision(10) << g << endl;
}
void Test2()
{
fprintf(stdout,
"a:%d\n"
"a:%08d\n"
"b:%c\n"
"c:%u\n"
"d:%I64d\n"
"e:%I64u\n"
"f:%.2f\n"
"g:%.9lf\n",
a, a, b, c, d, e, f, g);
fflush(stdout);
}
int main()
{
DWORD A, B;
DWORD start = GetTickCount();
for (int i = 0; i < 10000; ++i)
Test1();
A = GetTickCount() - start;
start = GetTickCount();
for (int i = 0; i < 10000; ++i)
Test2();
B = GetTickCount() - start;
cerr << A << endl;
cerr << B << endl;
return 0;
}
Here is the result of Test1 (cout):
# of executed instruction: 423,234,439
# of memory loads/stores: approx. 320,000 and 980,000
Elapsed time: 52 seconds
Then, what about printf? This is the result of Test2:
# of executed instruction: 164,800,800
# of memory loads/stores: approx. 70,000 and 180,000
Elapsed time: 13 seconds
In this machine and compiler, printf was much faster cout. In both number of executed instructions, and # of load/store (indicates # of cache misses) have 3~4 times differences.
I know this is an extreme case. Also, I should note that cout is much easier when you're handling 32/64-bit data and require 32/64-platform independence. There is always trade-off. I'm using cout when checking type is very tricky.
Okay, cout in MSVS just sucks :)
I would suggest you try this same test on a different computer. I don't have a good answer for why this might be happening; all I can say is I have never noticed a speed difference between cout and printf. I also tested your code using gcc 4.3.2 on Linux and there was no difference whatsoever.
That being said, you can't easily replace cout with your own implementation. The fact is, cout is an instance of std::ostream which has a lot of functionality built into it which is necessary for interoperability with other classes that overload the iostream operators.
Edit:
Anyone that says printf is always faster than std::cout is simply wrong. I just ran the test code posted by minjang, with gcc 4.3.2 and the -O2 flag on a 64-bit AMD Athlon X2, and cout was actually faster.
I got the following results:
printf: 00:00:12.024
cout: 00:00:04.144
Is cout always faster than printf? Probably not. Especially not with older implementations. But on newer implementations iostreams are likely to be faster than stdio because instead of parsing a format string at runtime, the compiler knows at compile time what functions it needs to call in order to convert integers/floats/objects to strings.
But more importantly, the speed of printf versus cout depends on the implementation, and so the problem described by the OP is not easily explicable.
Try call ios::sync_with_stdio(false); before using std::cout/cin, unless of course, you mix stdio and iostream in your program, which is a bad thing to do.
Based on my experience in programming competitions, printf IS faster than cout.
I remember many times when my solution didn't make it before the Time limit just because of cin/cout, while printf/scanf did work.
Besides that, it seems normal (at least for me) that cout is slower than printf, because it does more operations.
Try using some endls or flushes as they will flush cout's buffer, in case the OS is caching your program's output for whatever reason. But, as Charles says, there's no good explanation for this behavior, so if that doesn't help then it's likely a problem specific to your machine.
You should try to write all your data to an ostringstream first, and then use cout on the ostringstream's str(). I am on 64-bit Windows 7 and Test1 was already significantly faster than Test2 (your mileage may vary). Using an ostringstream to build a single string first and then using cout on that further decreased Test1's execution time by a factor of about 3 to 4. Be sure to #include <sstream>.
I.e., replace
void Test1()
{
cout
<< "a:" << a << "\n"
<< "a:" << setfill('0') << setw(8) << a << "\n"
<< "b:" << b << "\n"
<< "c:" << c << "\n"
<< "d:" << d << "\n"
<< "e:" << e << "\n"
<< "f:" << setprecision(6) << f << "\n"
<< "g:" << setprecision(10) << g << endl;
}
with:
void Test1()
{
ostringstream oss;
oss
<< "a:" << a << "\n"
<< "a:" << setfill('0') << setw(8) << a << "\n"
<< "b:" << b << "\n"
<< "c:" << c << "\n"
<< "d:" << d << "\n"
<< "e:" << e << "\n"
<< "f:" << setprecision(6) << f << "\n"
<< "g:" << setprecision(10) << g << endl;
cout << oss.str();
}
I suspect ostringstream makes this so much faster as a result of not trying to write to the screen each time you call operator<< on cout. I've also noticed through experience that reducing the number of times you write to the screen (by writing more at once) increases performance (again, your mileage may vary).
E.g.,
void Foo1()
{
for(int i = 0; i < 10000; ++i) {
cout << "Foo1\n";
}
}
void Foo2()
{
std::string s;
for(int i = 0; i < 10000; ++i) {
s += "Foo2\n";
}
cout << s;
}
void Foo3()
{
std::ostringstream oss;
for(int i = 0; i < 10000; ++i) {
oss << "Foo3\n";
}
cout << oss.str();
}
In my case, Foo1 took 1,092ms, Foo2 took 234ms, and Foo3 took 218ms. ostingstreams are your friend. Obviously Foo2 and Foo3 require (trivially) more memory. To compare this against a C-style function, try sprintf into a buffer and then write that buffer using fprintf and you should see still more efficiency over Test2 (though for me this only improved performance of Test2 by about 10% or so; cout and printf are indeed different beasts under the hood).
Compiler: MinGW64 (TDM and its bundled libraries).
Try using ios::sync_with_stdio(false);. Mention it before using std::cin/cout. It doesn't mix stdio or iostream but it synchronizes iostream standard streams with their corresponding standard c streams.
for example - std::cin/wcin of iostream is synchronized with stdin of c stream
Here is hax that should make c++ streams as fast as c printf. I never tested it but I believe it works.
ios_base::sync_with_stdio(0);