How to Save and Read Binary Data? - c++

I need your help again for the save and read data in binary. I have, a vector<<complex> > xy(256) which is read from the hardware in 10 times:
vector<<complex> > xy(256);
ofstream outfile2 (outfilename2.c_str() , ofstream::binary);
....
....
for(unsigned t = 0; t < 10; t++)
{
....
....
for(unsigned i = 0; i < 256; i++)
{
xy[i] = f[i] * conj(g[i]);
}
for(unsigned i = 0; i < 256; i++)
{
outfile2 << boost::format("%20.8e") % xy[i]<< endl; // write in text
}
} // the text data will be 2560 lines of complex data, for example:
// (6.69635350e+06,7.34146150e+06)
Now, I am trying to save into binary file, using this command:
for(unsigned i = 0; i < 256; i++)
{
outfile2.write((const char*)& xy[i], 1 * sizeof(complex<short>));
outfile2.flush();
}
Although, it still give me a data, but when i compare to the original text data, they were different. I do not understand why?
I would like to read complex 16 with floating point data.
I hope you guys can help.
Thank you very much.

I have written a demo, which works on my computer.
#include <cassert>
#include <complex>
#include <fstream>
#include <iostream>
#include <type_traits>
#include <vector>
int main() {
assert( std::is_trivially_copy_assignable<std::complex<short> >::value );
std::vector<std::complex<short> > vtr(256);
for (int i=0; i<256; ++i)
vtr[i] = std::complex<short>(i*2,i*2+1);
{
std::ofstream output("data.bin", std::ofstream::binary);
for (int i=0; i<256; ++i)
output.write((char *)&vtr[i],sizeof(vtr[i]));
}
vtr.clear();
std::cout << vtr.size() << std::endl;
vtr.resize(256);
{
std::ifstream input("data.bin", std::ifstream::binary);
for (int i=0; i<256; ++i)
input.read((char *)&vtr[i],sizeof(vtr[i]));
}
for (size_t i=0; i<vtr.size(); ++i)
std::cout << vtr[i] << " ";
std::cout << std::endl;
return 0;
}
You could run this demo on your computer. If this demo works, it's likely that you made some mistakes in your code. Please provide a complete, and verifiable example.

Related

How to make my program faster with Open MPI? My Open MPI program is currently slower than the original, what am I not understanding?

I have written a program for an assignment that cracks passwords using a dictionary attack and am trying to speed it up using Open MPI but my Open MPI version is slower and I am not sure why or what I am not understanding. The encrypted passwords are generated using a salt and a string passed into the unix function 'crypt.'
From what I have learned from looking at my class lecture notes, this is what I have come up with.
main.cc:
//****************************************************
// File: main.cc
// Author: Jordan Ward
// Purpose: Crack passwords in the form word+number
// or number+word where number can be at most
// three digits long using
// Open MPI to make it more efficient.
//*****************************************************
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <unistd.h>
#include <mpi.h>
using namespace std;
// Builds the list of encrypted passwords,
// list of dictionary words, and list of salts.
void file_IO(int argc, char *argv[], vector<string> &encPass, vector<string> &words,
vector<string> &salts);
// Builds the list of possible guesses.
void build_guesses(vector<string> &guesses, vector<string> &words);
// Tries each of the salts with each of
// the strings in the list of guesses to see
// if they match the ecrypted passwords.
void crack(string pass, vector<string> &salts, vector<string> &guesses);
// Broadcasts the vectors to all other processes.
void broadcast_receive(vector<string> &encPass, vector<string> &words,
vector<string> &salts, vector<string> &guesses);
// Converts a vector of strings to a vector of chars
vector<char> convert(vector<string> &strings);
int main(int argc, char *argv[]) {
vector<string> encPass;
vector<string> words;
vector<string> salts;
vector<string> guesses;
int numProcesses;
int procNum;
MPI_Init(NULL, NULL);
MPI_Comm_size(MPI_COMM_WORLD, &numProcesses); // Get the number of processes
MPI_Comm_rank(MPI_COMM_WORLD, &procNum); // Get the process number
if(procNum == 0) {
file_IO(argc, argv, encPass, words, salts);
build_guesses(guesses, words);
}
broadcast_receive(encPass, words, salts, guesses, numProcesses, procNum);
if(procNum != 0) {
for(size_t i = 0; i < encPass.size(); i++) {
if(i % procNum == 0) {
size_t del = encPass[i].rfind("$"); // Finds the last "$" in the string
string pass = encPass[i].substr(del); // Pass is a substring starting at the last "$"
crack(pass, salts, guesses);
}
}
}
MPI_Finalize();
return 0;
}
void file_IO(int argc, char *argv[], vector<string> &encPass, vector<string> &words,
vector<string> &salts) {
if(argc < 3) {
cout << "One or more files were not specified." << endl;
cout << "Correct format is 'mpiexec a.out file1 file2'" << endl;
exit(1);
}
ifstream secretPass(argv[1]);
string singlePass;
while(getline(secretPass, singlePass)) {
encPass.push_back(singlePass);
}
secretPass.close();
ifstream dictionary(argv[2]);
string word;
while(getline(dictionary, word)) {
words.push_back(word);
}
dictionary.close();
ifstream salt("salts");
string s;
while(getline(salt, s)) {
salts.push_back(s);
}
salt.close();
}
void build_guesses(vector<string> &guesses, vector<string> &words) {
//one word and one number
for(size_t i = 0; i < words.size(); i++) {
for(size_t j = 0; j < 10; j++) {
guesses.push_back(words[i] + to_string(j));
}
}
//one number and one word
for(size_t i = 0; i < 10; i++) {
for(size_t j = 0; j < words.size(); j++) {
guesses.push_back(to_string(i) + words[j]);
}
}
//one word and two numbers
for(size_t i = 0; i < words.size(); i++) {
for(size_t j = 0; j < 10; j++) {
for(size_t x = 0; x < 10; x++) {
guesses.push_back(words[i] + to_string(j) + to_string(x));
}
}
}
//two numbers and one word
for(size_t i = 0; i < 10; i++) {
for(size_t j = 0; j < 10; j++) {
for(size_t x = 0; x < words.size(); x++) {
guesses.push_back(to_string(i) + to_string(j) + words[x]);
}
}
}
//one word and three numbers
for(size_t i = 0; i < words.size(); i++) {
for(size_t j = 0; j < 10; j++) {
for(size_t x = 0; x < 10; x++) {
for(size_t y = 0; y < 10; y++) {
guesses.push_back(words[i] + to_string(j) + to_string(x) + to_string(y));
}
}
}
}
//three numbers and one word
for(size_t i = 0; i < 10; i++) {
for(size_t j = 0; j < 10; j++) {
for(size_t x = 0; x < 10; x++) {
for(size_t y = 0; y < words.size(); y++) {
guesses.push_back(to_string(i) + to_string(j) + to_string(x) + words[y]);
}
}
}
}
}
void crack(string pass, vector<string> &salts, vector<string> &guesses) {
for(size_t i = 0; i < salts.size(); i++) {
for(size_t j = 0; j < guesses.size(); j++) {
string ep = crypt(guesses[j].c_str(), salts[i].c_str());
if(ep.compare(salts[i] + pass) == 0) {
cout << "Password: " + guesses[j] << endl;
}
}
}
cout << "Password not found" << endl;
}
void broadcast_receive(vector<string> &encPass, vector<string> &words,
vector<string> &salts, vector<string> &guesses) {
int buffer[5];
buffer[0] = encPass.size();
buffer[1] = words.size();
buffer[2] = salts.size();
buffer[3] = guesses.size();
MPI_Bcast(buffer, 4, MPI_INT, 0, MPI_COMM_WORLD);
encPass.resize(buffer[0]);
words.resize(buffer[1]);
salts.resize(buffer[2]);
guesses.resize(buffer[3]);
vector<char> ep = convert(encPass);
vector<char> w = convert(words);
vector<char> s = convert(salts);
vector<char> g = convert(guesses);
MPI_Bcast(ep.data(), ep.size(), MPI_CHAR, 0, MPI_COMM_WORLD);
MPI_Bcast(w.data(), w.size(), MPI_CHAR, 0, MPI_COMM_WORLD);
MPI_Bcast(s.data(), s.size(), MPI_CHAR, 0, MPI_COMM_WORLD);
MPI_Bcast(g.data(), g.size(), MPI_CHAR, 0, MPI_COMM_WORLD);
}
vector<char> convert(vector<string> &strings) {
vector<char> cstrings;
cstrings.reserve(strings.size());
for(string s : strings) {
for(size_t i = 0; i < strlen(s.c_str()); i++) {
cstrings.push_back(s.c_str()[i]);
}
}
return cstrings;
}
My thought process is:
If process number is 0, read in the files and build the vectors with strings from the files and then build the list of guesses.
Else, receive all the lists and go through each encrypted password and see if any of the salts combined with any of the guesses matches the encrypted password.
What am I not doing correctly or not understanding that is making this slower than the original without the Open MPI code? Original code would just be the same file without the broadcast_receive and convert functions and obviously without the MPI calls in the main function.
I am compiling with mpic++ -std=c++11 -Wall main.cc -lcrypt and then running with mpiexec a.out enc_passwords words where enc_passwords is a small file with some encrypted passwords generated from the crypt function and words is a small list of words to build the guesses with.
Regarding your first question (why isn't MPI "faster"?), you need to ask two questions:
Q: Is the work actually being partitioned to multiple processors, in parallel?
Q: Does the overhead of message passing exceed the actual work you're trying to parallelize?
This should help with both questions:
OpenMPI FAQ: Performance Tools
Regarding your follow-on comment, "...but for some reason it is throwing a ton of errors.": please provide an MCVE. Or simply revert back to the "working" code.

In the given code can someone please explain me this code snippet for (int i=0; i<len; i++) count[str[i]]++;

#include<bits/stdc++.h>
#define ASCII_SIZE 256
using namespace std;
char getMaxOccuringChar(char* str)
{
int count[ASCII_SIZE] = {0};
// Construct character count array from the input
// string.
int len = strlen(str);
for (int i=0; i<len; i++)
count[str[i]]++;
// can someone please explain me this for loop
int max = -1; // Initialize max count
char result; // Initialize result
// Traversing through the string and maintaining
// the count of each character
for (int i = 0; i < len; i++) {
if (max < count[str[i]]) {
max = count[str[i]];
result = str[i];
}
}
return result;
}
// can someone please explain me this for loop
Simplify the code a bit and add a line of code to produce some useful output.
for (int i=0; i<len; i++)
{
// Simplify this line
// count[str[i]]++;
int index = str[i];
count[index]++;
// Add helpful output to understand the code.
std::cout << "Changed the value of count[" << index << "] to " << count[index] << std::endl;
}
The output should throw some light on what's happening there.

operations with matrix from two differents txt files

Good day :) I want to make a program (in Visual C ++) that does several differents operations with two matrix from two different files. So far i was done this.
typedef unsigned int uint;
class matrix {
private:
uint nrows, ncol;
float **elements;
public:
matrix(const char*);
void printmatrix(const char*);
};
#include "matrix.h"
#include <iostream>
#include <fstream>
#include <iomanip>
matrix::matrix(const char*file) {
ifstream fcin(file, ios::in);
if (!fcin) {
cerr << "\nError: the file doesnt exist\n";
exit(EXIT_FAILURE);
}
fcin >> nrows;
fcin >> ncol;
elements = new float*[nrows];
for (uint i = 0; i < nrows; i++) {
elements[i] = new float[ncol];
for (uint j = 0; j < ncol; j++)
fcin >> elements[i][j];
}
fcin.close();
}
void matrix::printmatrix(const char*file) {
ofstream fcout(file, ios::out);
if (!fcout) {
cerr << "\nError: file doesnt exist\n";
exit(EXIT_FAILURE);
}
fcout << nrows;
fcout << "\n";
fcout << ncol;
fcout << "\n";
for (uint i = 0; i < nrows; i++) {
for (uint j = 0; j < ncol; j++)
fcout << setw(6) << elements[i][j];
fcout << "\n";
}
fcout.close();
};
#include "matrix.h"
#include <cstdlib>
int main()
{
matrix A("matrix1.txt");
A.imprimir("matrix2.txt");
system("PAUSE");
return 0;
}
I begun to do the program with randomly generated matrixs, and to do operations (addition, subtraction, multiplication) with overloaded operators; And also do the operations "inverse matrix" and "multiplication by a scalar". However, when working with matrixs from two different text files, I complicate: \ and I have many doubts, starting with, what is the prototype for the operator overload for matrixs from two differents text files?
When I did the sum for randomly generated matrixs, I had done this:
matrix* operator+ (const matrix&matrix2){
matrix*sum=new matriz(nrow, ncol);
for (uint i=0; i<nrows; i++){
for (uint j=0; j<ncol; j++){
sum->elements[i][j]=elements[i][j]+matrix2.elements[i][j];
}
}
return sum;
}
And similarly I had performed the operations mentioned above and they worked well. but, I have no idea how to do operations (with overhead) with matrixs obtained from two different text files. Can you help me, please? :) Sorry if my question is not clear at all, im from latinoamerica and my english is bad

Can't read integer from file to matrix

I have to read from a file an array of numbers with an unknown size and save it as a matrix. The code must be as compact as possible, which is why I don't want to read file as string and then convert it to an int.
int main()
{
ifstream infile("array.txt");
int n, counter = 0, **p;
while (!infile.eof()) {
counter++;
}
counter = sqrt(counter);
cout << "counter is " << counter << endl;
p = new int*[counter];
for (int i = 0; i < counter; i++)
p[i] = new int[counter];
while (!infile.eof()) {
for (int i = 0; i < counter; i++) {
for (int j = 0; j < counter; j++)
p[i][j] = n;
}
}
for (int i = 0; i < counter; i++) {
for (int j = 0; j < counter; j++) {
cout << p[i][j] << " ";
}
cout << endl;
}
_getch();
return 0;
}
Here is my code, it was made for a square matrix. The problem is, I can't read the file at second time to save the numbers to the matrix.
You have a lot of problems in your code. A big one is that you have several infinite loops and aren't even reading from a file. An even bigger problem is that you're not using C++ constructs. I've written a small program that does what you're trying to do using more C++ concepts. In this case, you should use a std::vector - they will handle all the dynamic sizing for you.
test.cc
#include <iostream>
#include <vector>
#include <sstream>
#include <fstream>
#include <string>
// Nobody wants to write `std::vector<std::vector<int>>` more than once
using int_matrix = std::vector<std::vector<int>>;
void populate_matrix(int_matrix& mat, const std::string& line) {
int num;
std::stringstream ss(line);
std::vector<int> row;
// Push ints parsed from `line` while they still exist
while(ss >> num) {
row.push_back(num);
}
// Push the row into the matrix
mat.push_back(row);
}
// This is self-explanatory, I hope
void print_matrix(const int_matrix& mat) {
size_t n = mat.at(0).size();
for(size_t i = 0; i < n; ++i) {
for(size_t j = 0; j < n; ++j) {
std::cout << mat.at(i).at(j) << " ";
}
std::cout << std::endl;
}
}
int main(int argc, char** argv) {
int_matrix mat;
// Pass the file as a command-line arg. Then you don't need to worry about the path as much.
if(argc != 2) {
std::cout << "Number of arguments is wrong\n";
return EXIT_FAILURE;
}
// Open file with RAII
std::ifstream fin(argv[1]);
std::string line;
// Handle each line while we can still read them
while(std::getline(fin, line)) {
populate_matrix(mat, line);
}
print_matrix(mat);
return EXIT_SUCCESS;
}
This code assumes the text file looks something like this:
numbers.txt
1 2 3
4 5 6
7 8 9
i.e., n lines with n numbers per line separated by whitespace.
To compile and run this code, you can follow these steps:
13:37 $ g++ test.cc -std=c++14
13:37 $ ./a.out /path/to/numbers.txt
As far as I can see the program runs once through the file and later you run another while loop to read from the file. When you read from a file, then its like your "cursor" moves forward. So basicly, if you hit the end, you have to reset the cursor back to the start of the file.
You can set your cursor back with seekg(0).(http://www.cplusplus.com/reference/istream/istream/seekg/)

write to txt file in c++

I want to write random sorted data to a file. I'm using g++, but after running the program there was no data saved to the file.
This is the code:
#include <string>
// basic file operations
#include <stdlib.h>
#include <iostream>
#include <fstream>
using namespace std;
int main() {
int ra;
int pp = 0;
ofstream myfile("fi21.txt");
myfile.open("fi21.txt");
for(int j = 0; j < 10; j++)
{
for(int i = 0; i < 10; i++)
{
ra = (rand()) + pp;
pp = ra;
std::string vv;
vv = "1,";
vv += i;
vv += ",";
vv += ra;
vv += "\n";
// myfile << vv;
myfile.write(vv.c_str(), sizeof(vv));
}
}
// myfile.close();
return 0;
}
Your code should/could look like this:
#include <string>
#include <stdlib.h>
#include <iostream>
#include <fstream>
using namespace std;
int main() {
int ra;
int pp = 0;
ofstream myfile("fi21.txt"); // This already opens the file, no need to call open
for(int j = 0; j < 10; j++)
{
for(int i = 0; i < 10; i++)
{
ra = rand() + pp;
pp = ra;
// This will concatenate the strings and integers.
// std::string::operator+= on the other hand, will convert
// integers to chars. Is that what you want?
myfile << "1," << i << "," << ra << "\n";
}
}
return 0;
}
That superfluous call was the major problem, but also note that your attempt:
myfile.write(vv.c_str(), sizeof(vv));
has a mistake - sizeof(vv) is the number of bytes std::string takes on the stack, not how long it is. std::string::length or std::string::size is for that. Why to use the above at all, when you can myfile << vv;? I actually didn't even use std::string in the above code.