I'm working with an pressure sensitive LED floor, which outputs its sensors in a 2D array. I want to record this data and send it to a CSV file. However with my current code I gather 300.000 KB per second.
void DemoProjectApp::recorddata()
{
std::ofstream myfile;
myfile.open("datafloor.csv");
while(pressed = true)
{
for (int i = 0; i < ProjectSettings::NR_OF_TILES; i++)
{
myfile << "Tile" << i << ",";
myfile << tileIndexToSensorValues[i][0] << ",";
myfile << tileIndexToSensorValues[i][1] << ",";
myfile << tileIndexToSensorValues[i][2] << ",";
myfile << tileIndexToSensorValues[i][3] << "\n";
myfile.flush();
}
}
if(pressed = false)
{
myfile.close();
}
}
Pressed is a boolean changing true or false to start and stop recording.
Does anyone have a solution to decrease the output, but still get the relevant data?
Thanks in advance!
What you're writing there is effectively a series of images. Aka a video file. A video encoded in a very inefficient coding scheme. I guess the pressure field does not have steep changes, so my first approach would be encoding it with a video codec (MPEG4, h264, or such).
Okay, feeling really stupid but the answer was adding == at the pressed booleans.
Totally overlooked it.
Related
I am trying to get words from a text file and play sounds of those words. I am, somehow succesfull coding the first part but not that sucessful when it comes to play *.wav format sounds.
I do get words from text file and add them into a string array. but I could not manage to use PlaySound() function with that array. here is the code
i = 0;
while (i < count) {
cout << "now playing:" << str[i] << endl;
i++;
bool played = PlaySound(TEXT("-.wav"), NULL, SND_SYNC);
cout << "played ?" << played << endl;
}
All i want to do is replace that "-.wav" with my current str[i] index. The indexs are 4 words for now. Can-You-Hear-Me. These words must be in playsound function. I hope my eng is clear enough. Thx
First of I'd like to thank you all in advance for taking your time reading and helping me with my problem. I'm in no way shape or form an expert at c++, I'm not even good. I started programming in c++ 2 months ago and I find it quite harder than python, for a second experience with programming languages.
So I'm making this game for my programming class and I have to have a leaderboard text file with all the winners of a certain level. I set it up so the file always has the same format for time, name like this.
I've been trying to figure out how to sort the leaderboard entries by time and then by name. I thought of reading the file from line 3 and beyond but that doesn't seem to work. I moved on to what seems a better way of doing it which is to read the whole leaderboard discarding the first 2 lines, store it line by line on a vector, sorting the vector then and wiping the file by opening it in trunc mode but for some reason the file doesn't get wiped, it just keeps on adding more and more entries. I wan't it to add the sorted lines (vector) to the leaderboard one by one up until 10 entries are hit. Can someone help me? Here's a code sniped with the function I'm using to update the leaderboard
// Function to check if MAZE_XX_WINNERS.txt exists, if not creates it
void makeLeaderboard(string maze_name, string formated_time){
string winner_name, filename = maze_name.substr(0,7) +"_WINNERS.txt";
while(true){
// If MAZE_XX_WINNERS.txt file exists
if(ifstream(filename)){
// Open MAZE_XX_WINNERS.txt file in append mode
fstream leaderboard(filename, fstream::app);
// Ask for player name
cout << "Type your name (max 15 characters): ";
getline(cin, winner_name);
// If name is valid
if(isValidName(winner_name) && winner_name.length() <= 15){
string line;
vector<string> lb_entries;
int n_line = 0;
// Append to the end of the file
leaderboard << formated_time << " - " << winner_name << endl;
// Store all leaderboard entries in a vector
while(!leaderboard.eof()){
if(n_line >= 2){
getline(leaderboard, line);
lb_entries.push_back(line);
}
n_line++;
}
leaderboard.close();
//Everything works up until here, past here it doesn't do anything I want it to do
// Sort the leaderboard entries first by time, then by name
sort(lb_entries.begin(), lb_entries.end());
// Check if leaderboard has more than 10 entries to delete those past the limit
if(lb_entries.size() > 10){
// Truncates the vector from the 10th position forward
lb_entries.erase(lb_entries.begin()+9, lb_entries.end());
}
// Reopens the file in truncation mode to delete pre-existing leaderboard
leaderboard.open(filename, fstream::trunc);
// Format the file to have a table like shape
leaderboard << "| TIME - NAME |" << endl;
leaderboard << "------------------------------" << endl;
// Updates leaderboard
for(string entry : lb_entries){
leaderboard << entry << endl;
}
leaderboard.close();
break;
}
// If name not valid
else if(isValidName(winner_name) && winner_name.length() > 15){
cerr << endl << "Name has more than 15 characters! Please retry." << endl << endl;
}
else{
cerr << endl << "Not a valid name input!" << endl << endl;
}
}
// If file doesn't exist
else{
// Attempt to create the file
cout << "Creating leaderboard..." << endl;
ofstream leaderboard(filename);
// Check if file was created
if(!leaderboard){
cerr << "File could not be created" << endl;
}
else{
// Format the file to have a table like shape
leaderboard << "| TIME - NAME |" << endl;
leaderboard << "------------------------------" << endl;
leaderboard.close();
}
}
}
}
You need to break your problem down. What I would do is create a class that represents the LeaderBoards. It would actually consist of two classes. You could do one as an inner class of the others, but let's keep them separate:
class Leader {
public:
std::string time;
std::string name;
};
class LeaderBoard {
public:
std::vector<Leader> leaders;
void readFromFile(std::string fName);
void sort();
void writeToFile(std::string fName);
};
At that point, you need to implement three functions. None of them are very long.
void LeaderBoard::readFromFile(std::string fName) {
std::ifstream file(fName);
std::string line;
// skip the header
file.getline(line);
file.getline(line);
// Read the rest of the file.
while (file.getline(line)) {
// You'll need to parse the line into its parts
Leader leader(from the parts);
leaders.push_back(leader);
}
}
Yeah, I left some magic for you.
The write method would be very simple and just use an ofstream instead of an ifstream.
The sort method -- you can do a google for "c++ sort vector of objects" and get LOTS of examples.
In general, ALL programming can be broken down into smaller steps. If you're getting overwhelmed, break it down. This is one of the reasons you use an object-oriented language. If you don't know how to do something, create a class for it, then put methods in it for the smaller steps.
Then just figure out how to do small parts at a time. First: get data. Then print it out so you're sure you've got what you need.
If your code is more than about a screen or so, you're doing too much in one method. That's not an absolute, but at your level of coding, it's definitely true.
Small, tight methods. Small, tight methods are easier to write. Then string them together.
In this case:
Read the data
Sort the data
Write the data.
Each of these is easy to test individually.
I have an application that have to iterate over every character (to check some special cases) and write it to a stream using ostream put method.
When writing the ostream* points to a file stream, it executes magnificently faster than when ostream* points to cout which is redirected to a file.
In this (https://stackoverflow.com/a/1697906/12074577) answer I saw that probable using the fstream will be faster, due to one more layer of buffering compared to cout.
I thought that when I know that the output is going to cout, I can go through a string buffer, and when the buffer is full, append it to cout.
This way I obtain another layer of buffering and performance will improve.
So I have a test here of writing 32 million rows, each row is a string of ten characters.
I write them using cout, fstream, and stringbuffer that is later appended to cout.
void print_to_ostream(ostream *out, string& ones)
{
for (int i = 0; i < 32000000; ++i){
const char* ones_char = ones.c_str();
for (int j = 0; j < ones.size(); ++j ){
out->put(ones_char[j]);
}
}
}
int main(void){
string ones ="1111111111";
ostream *out = &cout;
size_t cout_time = 0;
size_t file_time = 0;
size_t cout_buffered_time = 0;
// print cout using ostream
mono_tick_timer time;
print_to_ostream(out, ones);
cout_time += time.tick();
// write to file using ostream
ofstream file("/tmp/test_file");
out = &file;
time.tick();
print_to_ostream(out, ones);
file_time += time.tick();
// ***optional solution***
// print to cout but passing through a string buffer
stringstream buffer;
out = &buffer;
time.tick();
print_to_ostream(out, ones);
cout_buffered_time += time.tick();
cout << buffer.str();
size_t buf_to_cout = time.tick();
std::cerr << "cout time: " << (double)cout_time / 1e6 << endl;
std::cerr << "file time: " << (double)file_time / 1e6 << endl;
std::cerr << "cout buffered time: " << (double)cout_buffered_time / 1e6 << endl;
std::cerr << "buf_to_cout: " << (double)buf_to_cout / 1e6 << endl;
return 0;
}
The results of running ./a.out > /tmp/test_times
are as follow (milliseconds):
cout time: 4773.62
file time: 2391.52
cout buffered time: 2380.83
buf_to_cout: 131.615
My bottom line question is: is using stringstream as a buffer before appending everything to cout a good solution?
Considering the fact that sometimes cout is redirected with large output to a file, and sometimes it's just being printed to the console?
Are they any negative side effects I didn't think about with this solution?
Or there is a better one I didn't think about?
The global streams (e.g. std::cout) are sync_with_stdio by default, whereas std::ofstream is not:
By default, all eight standard C++ streams are synchronized with their respective C streams.
If the synchronization is turned off, the C++ standard streams are allowed to buffer their I/O independently, which may be considerably faster in some cases.
Try turning it off with std::cout.sync_with_stdio(false);.
I am trying to write some code that is going to output a speed and time values to multiple files, specifically 4 different files which represents 4 different objects moving.
I know that to open and write to 1 file I can do the following:
#include <iostream>
#include <fstream>
std::ofstream outfile ("test.txt");
outfile << "my text here!" << std::endl;
outfile.close();
However I need to adapt this such that it would work in a switch statement as follows:
for (int i = 0; i < numRobots; i++){
switch (i){
case 0:
if (r1_stop == 1) r1Speed = 0;
else //Update speed
r1File << r1Speed << " " << time << endl;
case 1:
if (r2_stop == 1) r2Speed = 0;
else //Update speed
r2File << r2Speed << " " << time << endl;
case 2:
if (r3_stop == 1) r3Speed = 0;
else //Update speed
r3File << r3Speed << " " << time << endl;
case 3:
if (r4_stop == 1) r4Speed = 0;
else //Update speed
r4File << r4Speed << " " << time << endl;
}
}
Where r1File, r2File, r3File, and r4File are the files containing the speed and time for the respective objects. Im not quite sure how to implement this type where I have multiple files open or do i have to keep opening and closing the files? Im worried about overwriting existing data in the file if that is the case unless it knows to not start from the beginning of the file when opening it again.
Any help is appreciated, thanks
By default std::ofstream overwrites instead of appends, so from the moment you open the file it will be streaming bytes in that overwrite whatever was there before it was opened.
*fstream variants keep a file open until the stream object is destroyed. In other words a file being open is tied to the lifetime of the *fstream object representing it. Once destroyed, the file is immediately closed. This concept is known as RAII. In your case the stream objects are global, and thus are destroyed after main() ends, right before the application terminates.
If writing to the files isn't time critical, your implementation is good enough. On the other hand if you need more accurate measurements, consider writing each of your outputs to an intermediate buffer such as std::stringstream, then stream that data to your files after you're done taking measurements.
However, if you don't need the data from previous application runs, don't bother using files and instead just write to memory using a std::stringstream.
I did some searching on this site and on google as well. But i couldnt understand a lot of code i seen and im hoping to find more direct help from here. Im only 2 semesters in for c++ and i have a side project id like to do for my boss.
He generates a csv file for call logs and i want to be able to retrieve certain lines from the log and be able to calculate and display data.
Im not sure of the exact questions i need to ask but heres my code where i tried to start getting data but ran into problems (my programming knowledge is fairly limited due to lack of time and experience :)
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
int main()
{
//opens the csv file.
ifstream gwfile;
gwfile.open("log.csv");
if(!gwfile) { // file couldn't be opened
cout << "FAILED: file could not be opened" << endl << "Press enter to close.";
cin.get();
return 0;
}else
cout << "SUCCESSFULLY opened file!\n";
cout << "-------------------------------------------------------------------------------\n\n\n";
long int SIZE = 0;
char data[SIZE];
cout << "This is data SIZE:" << data[SIZE] << endl;
//in the csv im trying to only read lines that start with the voice as those are only valid data we need.
//also i would like to display the headings in teh very first line
while( !gwfile.eof() ){
//This is where im trying to only accept the lines starting with "Voice"
//if(data[SIZE] == "Voice"){
for( int i=0; i!=","; i++){
cout << "This is i: " << i << endl; //testing purposes.
}
//}
// getline(gwfile, data, '');
// cout << data[0];
}
return 0;
}
Let’s begin with the obvious
long int SIZE = 0;
char data[SIZE];
cout << "This is data SIZE:" << data[SIZE] << endl;
You are creating an array of size 0, then reaching for its first member: data[0]. This cannot work. Give your array a size that is large enough to handle the data you want to treat, or use a dynamicly resizable container (such as std::vector) to deal with it.