I would like to know how to output an array of doubles to the hard drive.
edit:
for further clarification. I would like to output it to a file on the hard drive (I/O functions). Preferably in a file format that can be quickly translated back into an array of doubles in another program. It would also be nice if it was stored in a standard 4 byte configuration so that i can look at it through a hex viewer and see the actual values.
Hey... so you want to do it in a single write/read, well its not too hard, the following code should work fine, maybe need some extra error checking but the trial case was successful:
#include <string>
#include <fstream>
#include <iostream>
bool saveArray( const double* pdata, size_t length, const std::string& file_path )
{
std::ofstream os(file_path.c_str(), std::ios::binary | std::ios::out);
if ( !os.is_open() )
return false;
os.write(reinterpret_cast<const char*>(pdata), std::streamsize(length*sizeof(double)));
os.close();
return true;
}
bool loadArray( double* pdata, size_t length, const std::string& file_path)
{
std::ifstream is(file_path.c_str(), std::ios::binary | std::ios::in);
if ( !is.is_open() )
return false;
is.read(reinterpret_cast<char*>(pdata), std::streamsize(length*sizeof(double)));
is.close();
return true;
}
int main()
{
double* pDbl = new double[1000];
int i;
for (i=0 ; i<1000 ; i++)
pDbl[i] = double(rand());
saveArray(pDbl,1000,"test.txt");
double* pDblFromFile = new double[1000];
loadArray(pDblFromFile, 1000, "test.txt");
for (i=0 ; i<1000 ; i++)
{
if ( pDbl[i] != pDblFromFile[i] )
{
std::cout << "error, loaded data not the same!\n";
break;
}
}
if ( i==1000 )
std::cout << "success!\n";
delete [] pDbl;
delete [] pDblFromFile;
return 0;
}
Just make sure you allocate appropriate buffers! But thats a whole nother topic.
Use std::copy() with the stream iterators. This way if you change 'data' into another type the alterations to code would be trivial.
#include <algorithm>
#include <iterator>
#include <fstream>
int main()
{
double data[1000] = {/*Init Array */};
{
// Write data too a file.
std::ofstream outfile("data");
std::copy(data,
data+1000,
std::ostream_iterator<double>(outfile," ")
);
}
{
// Read data from a file
std::ifstream infile("data");
std::copy(std::istream_iterator<double>(infile),
std::istream_iterator<double>(),
data // Assuming data is large enough.
);
}
}
You can use iostream .read() and .write().
It works (very roughly!) like this:
double d[2048];
fill(d, d+2048, 0);
ofstream outfile ("save.bin", ios::binary);
outfile.write(reinterpret_cast<char*>(&d), sizeof(d));
ifstream infile ("save.bin", ios::binary);
infile.read(reinterpret_cast<char*>(&d), sizeof(d));
Note that this is not portable between CPU architectures. Some may have different sizes of double. Some may store the bytes in a different order. It shouldn't be used for data files that move between machines or data that is sent over the network.
#include <fstream.h>
void saveArray(double* array, int length);
int main()
{
double array[] = { 15.25, 15.2516, 84.168, 84356};
saveArray(array, 4);
return 0;
}
void saveArray(double* array, int length)
{
ofstream output("output.txt");
for(int i=0;i<length;i++)
{
output<<array[i]<<endl;
}
}
here is a way to output an array of doubles to text file one per line. hope this helps
EDIT
Change top one line to this two, and it will compile in VS. You can use multithreading to not blocking system wile saving data
#include <fstream>
using namespace std;
Now I feel old. I asked this question a long time ago (except about ints).
comp.lang.c++ link
#include <iostream>
#include <fstream>
using namespace std;
int main () {
double [] theArray=...;
int arrayLength=...;
ofstream myfile;
myfile.open ("example.txt");
for(int i=0; i<arrayLength; i++) {
myfile << theArray[i]<<"\n";
}
myfile.close();
return 0;
}
adapted from http://www.cplusplus.com/doc/tutorial/files/
Just set theArray and arrayLength to whatever your code requires.
Related
I want to make copies of the exe file itself multiple times.
I tried the following code:
#include <fstream>
#include <string>
int main() {
std::ifstream from("main.exe", std::ios::binary);
auto buf { from.rdbuf() };
for(int x { 0 }; x <= 10; ++x) {
std::string name { "main" + std::to_string(x) + ".exe" };
std::ofstream out(name, std::ios::binary);
out << buf;
out.close();
}
from.close();
return 0;
}
But it doesn't work as I expected (It does not copy the executable repeatedly. See the size column in the following screenshot):
How do I solve this problem?
Reading from the input file stream buffer consumes the data. You need to reset the stream to the start after copying the file:
...
for (int x{ 0 }; x <= 10; ++x) {
std::string name{ "main" + std::to_string(x) + ".exe" };
std::ofstream out(name, std::ios::binary);
out << buf;
out.close();
from.seekg(0, std::ios::beg); // need to go back to the start here
}
...
You could simply use the std::filesystem standard library functionality for this though:
int main() {
std::filesystem::path input("main.exe");
for (int x{ 0 }; x <= 10; ++x) {
std::filesystem::path outfile("main" + std::to_string(x) + ".exe");
std::filesystem::copy_file(input, outfile, std::filesystem::copy_options::overwrite_existing);
}
return 0;
}
After you read all of the contents from the input buffer during your first iteration, your input buffer is empty. Thus, your subsequent iterations will also render empty copies. I suggest moving the from buffer initialization inside the loop like so:
#include <fstream>
#include <string>
int main() {
for (int x{ 0 }; x <= 10; ++x) {
std::ifstream from("main.exe", std::ios::binary);
auto buf{ from.rdbuf() };
std::string name{ "main" + std::to_string(x) + ".exe" };
std::ofstream out(name, std::ios::binary);
out << buf;
out.close();
from.close();
}
return 0;
}
Here's what you should get:
In the other answers the data will be read from the file multiple times (once per save).
This will happen if you create a new std::ifstream object inside the loop, and also happen if you use seekg to go to the beginning of the stream.
Since disk access is relatively slow (when compared to memory access), it will more efficient to read it once into memory, then save as many times as needed from memory.
The code below reads the file binary content into a std::vector. Then write the content of the vector multiple times to create the new files:
#include <string>
#include <vector>
#include <fstream>
int main() {
// Read the entire main.exe file into memory:
const std::string inFilename{ "main.exe" };
std::ifstream inFile{ inFilename, std::ios_base::binary };
std::vector<char> inFileData{ std::istreambuf_iterator<char>(inFile), std::istreambuf_iterator<char>() };
inFile.close();
// Save it as many times as needed:
for (int x{ 0 }; x <= 10; ++x)
{
std::string name{ "main" + std::to_string(x) + ".exe" };
std::ofstream outFile{ name, std::ios::binary };
outFile.write(inFileData.data(), inFileData.size());
outFile.close();
}
}
The first copy is done perfectly. My best guess is that the input buffer is empty afterwards, so all consecutive copies are empty.
I know this is a dumb question!
But I just CAN NOT get my head around how to read my file into an array one word at a time using c++
Here is the code for what I was trying to do - with some attempted output.
void readFile()
{
int const maxNumWords = 256;
int const maxNumLetters = 32 + 1;
int countWords = 0;
ifstream fin;
fin.open ("madLib.txt");
if (!fin.is_open()) return;
string word;
while (fin >> word)
{
countWords++;
assert (countWords <= maxNumWords);
}
char listOfWords[countWords][maxNumLetters];
for (int i = 0; i <= countWords; i++)
{
while (fin >> listOfWords[i]) //<<< THIS is what I think I need to change
//buggered If I can figure out from the book what to
{
// THIS is where I want to perform some manipulations -
// BUT running the code never enters here (and I thought it would)
cout << listOfWords[i];
}
}
}
I am trying to get each word (defined by a space between words) from the madLib.txt file into the listOfWords array so that I can then perform some character by character string manipulation.
Clearly I can read from a file and get that into a string variable - BUT that's not the assignment (Yes this is for a coding class at college)
I have read from a file to get integers into an array - but I can't quite see how to apply that here...
The simplest solution I can imagine to do this is:
void readFile()
{
ifstream fin;
fin.open ("madLib.txt");
if (!fin.is_open()) return;
vector<string> listOfWords;
std::copy(std::istream_iterator<string>(fin), std::istream_iterator<string>()
, std::back_inserter(listOfWords));
}
Anyways, you stated in your question you want to read one word at a time and apply manipulations. Thus you can do the following:
void readFile()
{
ifstream fin;
fin.open ("madLib.txt");
if (!fin.is_open()) return;
vector<string> listOfWords;
string word;
while(fin >> word) {
// THIS is where I want to perform some manipulations
// ...
listOfWords.push_back(word);
}
}
On the suggestion of πάντα ῥεῖ
I've tried this:
void readFile()
{
int const maxNumWords = 256;
int const maxNumLetters = 32 + 1;
int countWords = 0;
ifstream fin;
fin.open ("madLib.txt");
if (!fin.is_open()) return;
string word;
while (fin >> word)
{
countWords++;
assert (countWords <= maxNumWords);
}
fin.clear();
fin.seekg(0);
char listOfWords[countWords][maxNumLetters];
for (int i = 0; i <= countWords; i++)
{
while (fin >> listOfWords[i]) //<<< THIS did NOT need changing
{
// THIS is where I want to perform some manipulations -
cout << listOfWords[i];
}
}
and it has worked for me. I do think using vectors is more elegant, and so have accepted that answer.
The suggestion was also made to post this as a self answer rather than as an edit - which I kind of agree is sensible so I've gone ahead and done so.
The most simple way to do that is using the STL algorithm... Here is an example:
#include <iostream>
#include <iomanip>
#include <iterator>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector<string> words;
auto beginStream = istream_iterator<string>{cin};
auto eos = istream_iterator<string>{};
copy(beginStream, eos, back_inserter(words));
// print the content of words to standard output
copy(begin(words), end(words), ostream_iterator<string>{cout, "\n"});
}
Instead of cin of course, you can use any istream object (like file)
Please examine following code :
#include <iostream>
#include <string>
#include <fstream>
int main()
{
char mybuffer[512];
std::filebuf* optr = new std::filebuf();
optr->pubsetbuf(mybuffer, 512);
const char sentence[] = "Sample sentence";
auto ptr = optr->open("bd.bin", std::ios::binary | std::ios::trunc | std::ios::out);
if (ptr) {
float fx = 13;
auto n = optr->sputn(sentence, sizeof(sentence) - 1);
n += optr->sputn(reinterpret_cast<const char*>(&fx), sizeof(fx));
optr->pubsync();
}
optr->close();
if(optr) { delete optr; }
return 0;
}
After run this program no data has been written in to the file whilesputn -> n is returning valid amount of writtne characters(verified through debugging).
You code runs fine on my system, producing a bd.bin with 19 characters.
Are you sure this is exactly what you built and ran? Perhaps you're using a problematic compiler, or you're out of disk space or something.
Use the right tool for the job. filebuf is just the buffer that is streamed into. The actual thing that does the writing in the iostreams API is std::ostream:
std::filebuf file;
if (file.open(...)) {
std::ostream os(&file);
os << sentence;
os.write(reinterpret_cast<const char*>(&fx), sizeof(fx));
}
It's also easier to remember to use << and write() rather than deal with the maze of cryptically named functinos that is the streambuf API.
Hi I'm trying to read string from txt file and transform it into binary file which is bitset<12> string form.
int main()
{
using namespace std;
std::ifstream f("fruit.txt");
std::ofstream out("result.txt");
std::hash<std::string>hash_fn;
int words_in_file = 0;
std::string str;
while (f >> str){
++words_in_file;
std::bitset<12>* bin_str = new std::bitset<12>[3000];
int temp_hash[sizeof(f)];
std::size_t str_hash = hash_fn(str);
temp_hash[words_in_file] = (unsigned int)str_hash;
bin_str[words_in_file] = std::bitset<12>((unsigned int)temp_hash[words_in_file]);
out << bin_str[words_in_file] << endl;
delete[] bin_str;
}
out.close();
}
but there is error. How can I change it?
Here is some code that I wrote that turns the input file "file.txt" into binary. It does this by taking the ascii value of each character and representing that number as a binary value, although I'm not sure how to write bin_str to a file here.
#include <string>
#include <fstream>
#include <streambuf>
#include <bitset>
#include <iostream>
int main(){
std::ifstream f("file.txt");
std::string str((std::istreambuf_iterator<char>(f)),
std::istreambuf_iterator<char>()); // Load the file into the string
std::bitset<12> bin_str[str.size()]; // Create an array of std::bitset that is the size of the string
for (int i = 0; i < str.size(); i++) {
bin_str[i] = std::bitset<12>((int) str[i]); // load the array
std::cout << bin_str[i] << std::endl; // print for checking
}
}
SIDE NOTE:
std::bitset<12> may not be what you want, if you look at ascii characters the highest number you can have is 127 and in binary that's only 7 digits so I'd assume you'd want something more like std::bitset<7> or std::bitset<8>
EDIT:
If you want to write it to a file you'll need to open a file with std::ios::binary and then loop through the array of bitsets and write their unsigned long representative, given from to_ulong(), as a const char pointer ((const char*)&ulong_bin). Now when you open the file with a binary editor you will see the difference between the binary write and the regular write, but you'll notice that programs like cat can still decipher the binary you've written as simple ascii letters.
std::ofstream out("file.bin", std::ios::binary);
for (int i = 0; i < str.size(); i++) {
unsigned long ulong_bin = bin_str[i].to_ulong();
out.write((const char*)&ulong_bin, sizeof(ulong_bin));
}
EDIT: Credit to #PeterT
It has come to my attention that VLAs, variable length arrays, are not supported in C++11 and up so the line std::bitset<12> bin_str[str.size()]; should be changed to one of the following:
std::bitset<12> *bin_str = new std::bitset<12>[str.size()]; // make sure you delete it later
// OR
std::vector<std::bitset<12>> bin_str(str.size());
// OR
std::unique_ptr<std::bitset<12>[]> str_ptr (new std::bitset<12>[str.size()]);
I am reading numbers from a file, say:
1 2 3 4 5
I want to read this data from a file into a string into an array for further processing. Here's what I've done:
float *ar = nullptr;
while (getline(inFile, line))
{
ar = new float[line.length()];
for (unsigned int i = 0; i < line.length(); i++)
{
stringstream ss(line);
ss >> ar[i];
}
}
unsigned int arsize = sizeof(ar) / sizeof(ar[0]);
delete ar;
Suffice it to say that it works insofar it only gets the first value from the file. How do I get the array to be input ALL the values? I debugged the program and I can confirm that line has all the necessary values; but the float array doesn't. Please help, thanks!
line.length() is the number of characters in the line, not the number of words/numbers/whatevers.
Use a vector, which can be easily resized, rather than trying to juggle pointers.
std::vector<float> ar;
std::stringstream ss(line);
float value;
while (ss >> value) { // or (inFile >> value) if you don't care about lines
ar.push_back(value);
}
The size is now available as ar.size(); your use of sizeof wouldn't work since ar is a pointer, not an array.
The easiest option is to use the standard library and its streams.
$ cat test.data
1.2 2.4 3 4 5
Given the file you can use the stream library like this:
#include <fstream>
#include <vector>
#include <iostream>
int main(int argc, char *argv[]) {
std::ifstream file("./test.data", std::ios::in);
std::vector<float> res(std::istream_iterator<float>(file),
(std::istream_iterator<float>()));
// and print it to the standard out
std::copy(std::begin(res), std::end(res),
std::ostream_iterator<float>(std::cout, "\n"));
return 0;
}
I ran into this problem earlier when I wanted to extract data line by line from a file to fill my sql database that I wanted to use.
There are many solutions to this specific problem such as:
The solution is using stringstream with a while statement to put data from file into the array with a while statement
//EDIT
While statement with getline
//This solution isn't very complex and is pretty easy to use.
New Improved simple solution:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
int main()
{
ifstream line;
line.open("__FILENAME__");
string s;
vector<string> lines;
while(getline(line, s))
{
lines.push_back(s);
}
for(int i = 0;i < lines.size();i++)
{
cout << lines[i] << " ";
}
return 0;
}
compiled code to check - http://ideone.com/kBX45a
What about atof?
std::string value = "1.5";
auto converted = atof ( value.c_str() );
Rather complete:
while ( std::getline ( string ) )
{
std::vector < std::string > splitted;
boost::split ( splitted, line, boost::is_any_of ( " " ) );
std::vector < double > values;
for ( auto const& str: splitted ) {
auto value = atof ( str.c_str() );
values.push_back ( value );
}
}