writing content of vector to file c++ - c++

I've tried to write my vector content into a file. To do that I've written a piece of code like:
int main()
{
ofstream outputfile("test.txt");
vector<int>temp;
temp.push_back(1);
temp.push_back(2);
temp.push_back(3);
for(int i=0;i<temp.size();i++)
outputfile<<temp[i]<<"\n";
}
When I write this I can easly do what I wanted. the content of file is:
1
2
3
However, when I want to write my vector to file from reverse(like below).I get nothing.Just empty file.Is there anyone to help me ? Thanks in advance.
for(int i=temp.size()-1;i>=0;i--)
outputfile<<temp[i]<<"\n";

You may use
std::copy(temp.rbegin(), temp.rend(),
std::ostream_iterator<int>(outputfile, "\n"));
And this code:
for(int i=temp.size()-1;i>=0;i--)
outputfile<<temp[i]<<"\n";
works fine on my windows with vs12.

You can do it all in 1 line:
std::copy(temp.rbegin(), temp.rend(), std::ostream_iterator<int>(outputFile, "\n"));

use a reverse iterator:
for (std::vector<int>::reverse_iterator it = myvector.rbegin(); it != myvector.rend(); ++it)
or in your code, start the for loop from size() - 1 :
for(int i=temp.size()-1;i>=0;i--)
instead of
for(int i=temp.size();i>=0;i--)

std::copy(head_buff.rbegin(), head_buff.rend(),
std::ostream_iterator<std::string>(data_pack, "\n"));
but use #include<fstram>#include<iterator> #include<osstream>
second method is traverse entire vector and copy the contents to a string
then write the string into ofstream
ie
std::string somthing;
for(std::vector<std::string>::const_iterator i = temp.begin();i!=temp.end(); ++i)
{
something+=*i;
}
then write string (something) to ofstream ie
std::ofstram output;
output.open("test.txt",std::ios_base::trunc)
if(output.fail())
std::cerr<<"unable to open the file"std::endl;
output << something;
//after writing close file
output.close();

Related

Write vector values into multiple files at once in C++

I have the data in my vector. I am trying to write each vector value, say vector_name[0] into "examplezero.h" , vector_name[1] into "exampleone.h" and so on. The below code shows how I have created the files.
int co = 80;
string name ="example";
std::ofstream output_file[80];
for (int i = 0; i < co; i++)
{
output_file[i].open(name + std::to_string(i) + ".h");
output_file[i].close();
}
I am trying to iterate over my vector and trying to write to my files.
std::vector<string> rowname; //This has all the values
for (auto i = rowname.begin(); i != rowname.end(); ++i)
{
std::ostream_iterator<std::string> \
output_iterator(output_file[80], "\n");
std::copy(rowname.begin(), rowname.end(), output_iterator);
}
When I am trying to write to the files it is crashing. Can you let me know what's wrong? I know the basics of C++ and trying to learn the advanced concepts.
Thanks
Your program is likely crashing because you wrote this code:
std::ostream_iterator<std::string> \
output_iterator(output_file[80], "\n");
...and output_file[80] is one element past the end of the array. You declared it as:
std::ofstream output_file[80];
The first element of that array is output_file[0] and the last element of that array is output_file[79].
There are more things wrong
As #walnut pointed out, if your code is really as you posted it, then it appears to close each file immediately after opening it, without writing anything to the file.
for (int i = 0; i < co; i++)
{
output_file[i].open(name + std::to_string(i) + ".h");
output_file[i].close(); // Leaving so soon?
}
Writing to an ofstream that has been closed does not crash the program, but sets an error condition on the ofstream (badbit). So this will appear to be a silent failure to you.
To fix
To fix your problem you'll have to write to your file after you open it, but before you close it.
You'll also have to decide exactly which output_file you actually want to write to and provide the correct array index. It's not obviously clear from your sample code what your intent was. You'll have to decide which file(s) (of the 80 that you opened) you want to write each element of your rowname vector into.
The std::copy as you have written it will write all strings in the rowname vector to the same stream. If your intent was to write each element to its own file, then you'll have to set it up substantially differently.
Something more along the lines of:
#include <fstream>
#include <vector>
#include <string>
int main() {
std::vector<std::string> rowname = { "alpha", "bravo", "charlie" }; // example data
std::string name = "example"; // base filename
for (size_t i = 0; i < rowname.size(); ++i) {
std::ofstream output_file;
std::string filename = name + std::to_string(i) + ".h"; // e.g.: "example0.h"
output_file.open(filename);
output_file << rowname[i]; // write the string to the file
output_file.close(); // if you want
}
}
This writes the text alpha into example0.h, bravo into example1.h, and charlie into example2.h.

C++: How can I output data as CSV to a specific set of cells in an existing file?

So I am looping over data files in order to make a calculation based on each data file (the calculation is done for 20 bins in each file, so 20 results per file). I then want to get each calculation into a csv file so that I am able to average the calculations from each file.
Each time I loop over a file, I am obtaining a csv file with 20 results in cells A1 to A20.
However, what I want is a csv file with 20 results in cells A1 to A20, another 20 results in cells B1 to B20 etc. up to 20 results in cells CV1 to CV20.
My code in each loop looks like this for outputting the data:
ofstream ofs (path2 + "tanShears.csv", ofstream::out);
for (int j = 0; j < r.size(); j++) {
ofs << tShears[j] << endl;
Obviously when I do this I just end up with 20 results in cells A1 to A20 corresponding to the final data set in the loop, since each loop just overwrites the previous one.
Any ideas how I can target specific cells in the csv file, so that I can output the results from each loop to a different part of the same csv file?
A CSV file is structured like this:
[A1];[B1];[C1];...\n
[A2];[B2];...\n
[A3];[B3];...\n
If you don't want to write the whole data at once, you will have to read the whole file, parse it, make changes accordingly and then writing it. Which I would avoid at almost any cost.
Now to some example code: (I am assuming you are printing some int value)
void writeToCSV(std::vector<std::vector<int>> const& tShears)
{
ofstream ofs (path2 + "tanShears.csv", ofstream::out);
for (std::vector<std::vector<int>>::iterator j = tShears.begin();
j != tShears.end(); j++)
{
for(std::vector<int>::iterator i = j->begin(); i < j->end(); j++)
{
ofs << i << ";";
}
ofs << std::endl;
}
ofs.close();
}
In this example the inner vector contains the n-th values of all calculations you made. So it might contain A1, B1, C1...
You could keep the results in a vector (one block of 20 after another, or use different vectors).
Then write all data at once. The first value of each block on the first line in your csv, then the second, and so on.
Did I understand correctly your question?
You have 20 data sources with csv data, 20 results in each one. And you need to operate with these data with later writing each data set to the file?
#include <map>
#include <vector>
#include <string>
struct privateData {
map<string,vector<vector<string>>> allData;
void addDataUnit(const string& block, const vector<string>& unit)
{
// I consider that you already parsed csv data into separated elements
allData[block].push_back(unit);
}
string getDataRow(const string& block, int position) {
string ret;
if (allData[block].size() >= position) return ret;
for (unsigned int i = 0; i < allData[block][position].size(); i++) {
ret+=allData[block][position][i];
ret+="SomeDelim";
}
return ret;
}
vector<string> getDataBlock(const string& block) {
vector<string> ret;
for (unsigned int i = 0; i < allData[block].size(); i++)
ret.push_back(getDataRow(block,i));
return ret;
}
}
I didn't compile - so, probably some syntax errors.
So, each dataBlock will be named array for a cell set.
Then you can iterate the map to get all names and write them to separate files or to separate data set.
Hope it helps
Check this : http://www.cplusplus.com/reference/fstream/ofstream/ofstream/#parameters
You should write sth like this:
ofstream ofs (path2 + "tanShears.csv", ofstream::out|ofstream::app);
You can store your all results in vector, but if calculation is a long process (it takes a hours), there is possibility of loss this data (when sth go wrong), and in this case better is write your results to file after each part of calculation.
However, writing to file full data seems be faster then many writings partial data.

Format vector string on stdout

So for this program I'm writing for class I have to format a vector string into standard output. I get how to do it with just strings with the 'printf' function but I don't understand how to do it with this.
Here's what I got:
void put(vector<string> ngram){
while(!(cin.eof())){ ///experimental. trying to read text in string then output in stdout.
printf(ngram, i);///
Okay, I can't read a lot out of your question but from what I understood, you want to print a vector of strings to the standard output!? This would work like this:
void put(std::vector<std::string> ngram){
for(int i=0; i<ngram.size(); i++)
{
//for each element in ngram do:
//here you have multiple options:
//I prefer std::cout like this:
std::cout<<ngram.at(i)<<std::endl;
//or if you want to use printf:
printf(ngram.at(i).c_str());
}
//done...
return;
}
Is that what you wanted?
If you simply want each item on a single line:
void put(const std::vector<std::string> &ngram) {
// Use an iterator to go over each item in the vector and print it.
for (std::vector<std::string>::iterator it = ngram.begin(), end = ngram.end(); it != end; ++it) {
// It is an iterator that can be used to access each string in the vector.
// The std::string c_str() method is used to get a c-style character array that printf() can use.
printf("%s\n", it->c_str());
}
}

C++ How can i erase a char from a string (input)

I am trying to make a program although i have finished it already i need something more. So, the user asked to give an input IF the string contains * i want to erase the first * and cout the input
getline(cin,str);
int k=str.length();
for(int i=0; i<=k; i++)
if(str[i]=='*')
string::iterator it;
it=str.begin()+i;
str.erase(it);
break;
cout<<str<<endl;
what i am doing wrong ?
Be very careful, you need to use brackets {} to control scope, not tabulation!
Also, using = in a if is an assignation, not a check, you need to use ==
You iterate using i yet you delete using x?
You could simplify this by using std::find to remove the first occurrence of *:
str.erase(std::find(str.begin(), str.end(), '*'));

Very large look up table C++ - can I avoid typing the whole thing out?

I am not a programmer, but am an engineer who needs to use C++ coding on this occasion, so sorry if this question is a little basic.
I need to use a look up table as I have some highly non-linear dynamics going on that I need to model. It consists of literally 1000 paired values, from a pair of (0.022815, 0.7) up to (6.9453, 21.85).
I don't want to have to type all these values out in my C code. The values are currently stored in Matlab. Can I read them from a .dat file or something similar?
I will have calculated a value and simply want the program to kick out the paired value.
Thanks,
Adam
You can't read something stored in Matlab directly, unless you want to
write a parser for whatever format Matlab stores its data in. I'm not
familiar with Matlab, but I would be very surprised if it didn't have a
function to output this data to a file, in some text format, which you
could read and parse.
Assuming this is constant data, if it could output something along the
lines of:
{ 0.022815, 0.7 },
...
{ 6.9453, 21.85 },
you could include it as the initializer of a table in C++. (It may look
strange to have a #include in the middle of a variable definition, but
it's perfectly legal, and in such cases, perfectly justified.) Or just
copy/paste it into your C++ program.
If you can't get exactly this format directly, it should be trivial to
write a small script that would convert whatever format you get into
this format.
this program defines a map, then reading from a.txt file, inserting to a map, iterating on map for any purposes you have, and finally writing the map into a file.
just a simple practice:
#include <fstream>
#include <iostream>
#include <map>
using namespace std;
int main(){
ifstream inFile("a.txt", ios::in);
if (! inFile ){
cout<<"unabl to open";
return 0;
}
//reading a file and inserting in a map
map<double,double> mymap;
double a,b;
while( ! inFile.eof() ){
inFile>>a>>b;
mymap.insert ( a,b );
}
inFile.close(); //be sure to close the file
//iterating on map
map<double,double>::iterator it;
for ( it=mymap.begin() ; it != mymap.end(); it++ ){
// (*it).first
// (*it).second
}
//writing the map into a file
ofstream outFile;
outFile.open ("a.txt", ios::out); // or ios::app if you want to append
for ( it=mymap.begin() ; it != mymap.end(); it++ ){
outFile << (*it).first << " - " << (*it).second << endl; //what ever!
}
outFile.close();
return 0;
}
What I would do for this is as follows as I think this is faster than file open and close. First of all create a header file which contains all the data in an array. You could you a "replace all" available in Notepad or so to replace the () braces to { } braces. Later on you could even write a script that makes the header file from the Matlab file
>> cat import_data.h
#define TBL_SIZE 4 // In your case it is 1000
const double table[TBL_SIZE][2] =
{
{ 0.022815, 0.7 },
{ 6.9453, 21.85 },
{ 4.666, 565.9},
{ 567.9, 34.6}
};
Now in the main program you include this header also for the data
>> cat lookup.c
#include <stdio.h>
#include "import_data.h"
double lookup(double key)
{
int i=0;
for(;i<TBL_SIZE; i++) {
if(table[i][0] == key)
return table[i][1];
}
return -1; //error
}
int main() {
printf("1. Value is %f\n", lookup(6.9453));
printf("2. Value is %f\n", lookup(4.666));
printf("3. Value is %f\n", lookup(4.6));
return 0;
}
Yes, you can read them from the dat file. The question is, what format is the dat file? Once you know that, you want to use:
fopen
fread
fclose
for C and
ifstream
for C++ (or something similar).
The program still has to get those pairs from the file and load them in memory. You can loop through the lines in the file, parse the pairs and shove them in a std::map.
Something like this:
#include<fstream>
#include<map>
...
ifstream infile("yourdatfile.dat");
std::string str;
std::map<double, double> m; //use appropriate type(s)
while(getline(infile, str)){
//split str by comma or some delimiter and get the key, value
//put key, value in m
}
//use m
For the signal processing toolbox you can export data to C header files
directly from Matlab(don't know if it's your particular case):
Matlab export to C header
Or maybe the following article could be of help:
Exporting/Importing Data To/From MATLAB
One of options is to generate the C++ lookup table in matlab. Just write to some text file (lookup.cpp), read table producing C++ source...