I'm trying to read a binary file that contains a 1501-by-1501 matrix of double, and plug it in an Eigen matrix. Here is my code:
#include <fstream>
#include <iostream>
#include <Eigen/Dense>
#include <string>
using namespace std;
using namespace Eigen;
int main()
{
MatrixXd B(1501, 1501);
ifstream inputFile;
double toread;
inputFile.open("/path/to/bathymetry_S1000s2500s_E65d1000s65d2500s.bin",
ios::out | ios::in | ios::binary);
if (!inputFile) {
cout << "The file can't be opened.\n";
exit(10);
} else {
for (int i2 = 0; i2 < 1501; i2++) {
for (int i1 = 0; i1 < 1501; i1++) {
inputFile.read( reinterpret_cast<char*>( &toread ),
sizeof(toread) );
inputFile >> toread;
B(i1, i2) = toread;
}
}
inputFile.close();
}
cout << "Max value:" << B.maxCoeff() << endl; // Just to check the result
cout << "Mean Value:" << B.mean() << endl; // The same
}
My problem is that, when I run the code, my matrix B is actually filled only with the very first value of the inputFile, which is -4502, which will then be given by the two cout. (All the elements of the matrix are -4502). How can I make the compiler understand that I want it to continue reading the inputFile after the previous value, instead of starting from the beginning at each loop-step?
Related
The file does open and I get the message "File opened successfully". However I can't input data from the array in file "random.csv" into my inputFile object.
The data in random.csv is:
Boston,94,-15,65
Chicago,92,-21,72
Atlanta,101,10,80
Austin,107,19,81
Phoenix,112,23,88
Washington,88,-10,68
Here is my code:
#include "main.h"
int main() {
string item; //To hold file input
int i = 0;
char array[6];
ifstream inputFile;
inputFile.open ("random.csv",ios::in);
//Check for error
if (inputFile.fail()) {
cout << "There was an error opening your file" << endl;
exit(1);
} else {
cout << "File opened successfully!" << endl;
}
while (i < 6) {
inputFile >> array[i];
i++;
}
for (int y = 0; y < 6; y++) {
cout << array[y] << endl;
}
inputFile.close();
return 0;
}
Hello and welcome to Stack Overflow (SO). You can use std::getline() to read each line from the file, and then use boost::split() to split each line into words. Once you have an array of strings for each line, you can use a container of your liking to store the data.
In the example below I've used an std::map that stores strings and a vector of ints. Using a map will also sort the entrances using the key values, which means that the final container would be in alphabetical order. The implementation is very basic.
#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <fstream>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/split.hpp>
#include <ctype.h>
typedef std::map<std::string,std::vector<int>> ContainerType;
void extract(ContainerType &map_, const std::string &line_)
{
std::vector<std::string> data;
boost::split(data, line_, boost::is_any_of(","));
// This is not the best way - but it works for this demo.
map_[data[0]] = {std::stoi(data[1]),std::stoi(data[2]),std::stoi(data[3])};
}
int main()
{
ContainerType map;
std::ifstream inputFile;
inputFile.open("random.csv");
if(inputFile.is_open())
{
std::string line;
while( std::getline(inputFile,line))
{
if (line.empty())
continue;
else
extract(map,line);
}
inputFile.close();
}
for (auto &&i : map)
{
std::cout<< i.first << " : ";
for (auto &&j : i.second)
std::cout<< j << " ";
std::cout<<std::endl;
}
}
Hope this helps.
I have a list of data (in 4 columns) that I would like to sort by a certain column. It was read in from a file to a 2D vector. I the used the std::sort method and wrote my comparator functor. The program compiles and runs, but when I print the first 10 elements it is not sorted, but is certainly different from the order it was added to the 2D vector.
Here is the code:
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <string>
#include <vector>
#include <algorithm>
#include <iomanip>
using namespace std;
typedef vector<double> Row;
typedef vector<Row> Matrix;
bool sortByFourthColumn(const Row& row1, const Row& row2){
return (double) row1[3] < (double) row2[3];
}
int main(){
std::ifstream infile;
infile.open("Test8_Output.txt");
double x,y,z,E;
char line[200];
int line_count=0;
ofstream outfile;
outfile.open("WO_crp.txt");
if (infile.is_open()){
while (!infile.eof()){
infile.getline(line,170);
if (line[0] != '%'){
outfile<<line<<"\n";
line_count++;
}
else{
}
}
Matrix data(line_count,Row(4));
outfile.close();
std::ifstream myfile;
myfile.open("WO_crp.txt");
int i = 0;
while(myfile >> x >> y >> z >> E){
data[0][i] = x;
data[1][i] = y;
data[2][i] = z;
data[3][i] = E;
i++;
}
myfile.close();
std::sort(data.begin(), data.end(), sortByFourthColumn);
for (int u = 0; u <20; u++){
cout << setprecision(5) << data[0][u] << "\t" << setprecision(5)<< data[1][u] << "\t" << setprecision(5)<< data[2][u] << "\t" << setprecision(5)<< data[3][u] << endl;
}
}
else{
cout << "Error: File is invalid.\n";
}
return(0);
}
EDIT - Sample of what the input file looks like:
EDIT 2 - swapped 4 and line_count in Matrix data(4,Row(line_count));
% Model: CDS_Test8.mph
% Version: COMSOL 5.2.0.220
% Date: Jul 13 2016, 14:33
% Dimension: 3
% Nodes: 86183
% Expressions: 1
% Description: Electric field norm
% Length unit: m
% x y z es.normE (V/m)
0.13774675805195374 0.05012986567931247 0.20735 67.35120820901535
0.13870000000000005 0.04957489750396299 0.20735000000000003 102.8772500513651
0.13870000000000002 0.050800000000000005 0.20735 87.56008679032011
0.13792733849817027 0.050131465727838186 0.20801419247484804 73.55192534768238
0.13674627634411463 0.04992349737428063 0.20735 63.23018910026428
0.13750191177019236 0.0508 0.20735000000000003 67.26176884022838
0.13827743496772454 0.05193409099097887 0.20734999999999998 73.35474409597487
0.13803618792088135 0.05134931748395268 0.20841988134890965 75.3712126982815
0.13905949760011943 0.05141879754884912 0.20734999999999998 83.70739713476813
0.13896970815034013 0.05092428105421264 0.208142746399683 84.73571510992372
0.1390220807917094 0.0501245422629353 0.20817502757007986 85.57119242707628
0.13944867847480893 0.05161480113017738 0.2081969878426443 89.65643851109644
And so on it goes for another 87k lines or so.
I have a list of data (in 4 columns) that I would like to sort by a
certain column.
The problem is that the dimensions of the vector of vectors used to store the data in OP program is not consistent between declaration and use.
A minor problem is the use of while(!infile.eof()){... which should be avoided.
A fixed version is like this:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <array>
#include <algorithm>
#include <iomanip>
using Row = std::array<double,4>; // instead of typedefs
using Matrix = std::vector<Row>;
using std::cout;
bool sortByFourthColumn(const Row& row1, const Row& row2){
return row1[3] < row2[3];
// ^ The cast is unnecessary
}
int main(){
std::string file_name{"Test8_Output.txt"};
std::ifstream infile{file_name, std::ios_base::in};
if ( !infile ) {
cout << "Error: unable to open file " << file_name << '\n';
return EXIT_FAILURE;
}
Matrix data;
data.reserve(90000); // if you are afraid of the reallocations
int count = 0;
std::string line;
// instead of two loops you can use one loop and read the file once
// I'll use std::getline to extract a row in a std::string
while ( std::getline(infile, line) ) {
// skip comments and empty lines
if ( line.empty() || line[0] == '%' )
continue;
++count;
// extract data from the string using a stringstream
std::stringstream ss{line};
Row r;
ss >> r[0] >> r[1] >> r[2] >> r[3];
if ( !ss ) {
cout << "Format error in line " << count << " of file.\n";
break;
}
data.push_back(std::move(r));
}
std::sort(data.begin(), data.end(), sortByFourthColumn);
cout << std::setprecision(5) << std::fixed;
for ( const auto & r : data ) {
for ( auto const &x : r ) {
cout << std::setw(10) << x;
}
cout << '\n';
}
return EXIT_SUCCESS;
}
The output, given the example data is:
0.13675 0.04992 0.20735 63.23019
0.13750 0.05080 0.20735 67.26177
0.13775 0.05013 0.20735 67.35121
0.13828 0.05193 0.20735 73.35474
0.13793 0.05013 0.20801 73.55193
0.13804 0.05135 0.20842 75.37121
0.13906 0.05142 0.20735 83.70740
0.13897 0.05092 0.20814 84.73572
0.13902 0.05012 0.20818 85.57119
0.13870 0.05080 0.20735 87.56009
0.13945 0.05161 0.20820 89.65644
0.13870 0.04957 0.20735 102.87725
Its not appending to the end of the already created text file (which has contents in it) that i specify with cin , even when i have out2.open(tablename2, std::ofstream::out | std::ofstream::app); and out2 << v2[i]; in there.
Full code:
#include "stdafx.h"
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <iomanip>
#include <stdio.h>
using namespace std;
using std::vector;
using std::string;
void insertit(std::vector<std::string>& v, std::vector<std::string>& v2, std::string insertedstr)
{
std::string tablename2;
cout << "Enter file name with the extension " << endl;
std::getline(std::cin, tablename2);
for (int w = 0; w < v.size(); w++) {
cout << v[w] << ": ";
cin.ignore();
std::getline(std::cin, insertedstr);
v2.push_back(insertedstr + " ");
insertedstr.clear();
}
//below, why is it not writing to the file you specified from cin >>tablename2?
std::ofstream out2(tablename2);
out2.open(tablename2, std::ofstream::out | std::ofstream::app);
for (int i = 0; i < v2.size(); i++) {
out2 << v2[i];
}
out2.close();
v2.clear();
cout << "The record has been inserted into " << tablename2 << endl;
}
int main()
{
std::vector<std::string> v = {"author", "title"};
std::vector<std::string> v2;
std::string insertedstr;
insertit(v, v2, insertedstr);
return 0;
}
Any ideas why?
The constructor already opens the file, although not in appending mode. It's not clear to me what this does (I looked at http://en.cppreference.com/w/cpp/io/basic_filebuf/open , which didn't help too much, and I'm not a standards wizard). If your constructor looks like
std::ofstream out2(tablename2, std::ofstream::out | std::ofstream::app);
and you remove the out.open(....) call, your code works (tested with gcc 4.8.4 - I removed the #include "stdafx.h").
I tried to create a program that uses an input file 'cardList.txt' that contains:
Schmidt, Helga
Alvarez, Ruben
Zowkowski, Aaron
Huang, Sun Lee
Einstein, Beverly
and I wanted to sort this alphabetically by last name.
main:
#include <iostream>
#include <fstream>
#include <string>
#include "insertsortFunct.h"
using namespace std;
int main(void){
ifstream inData;
ofstream outData;
const int listSize = 5;
char cardList[listSize][25];
instruct();
openFile(inData, outData);
buildList(cardList, inData);
inData.close();
sortList(cardList, listSize);
cout << endl << "Your list is sorted" << endl;
writeFile(cardList, outData);
outData.close();
return 0;
}
I defined these functions in a separate file:
#include "insertsortFunct.h"
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;
void instruct(void){
cout << "The program insertSort.cpp reads the file, cardList.txt " <<
"into an array and" << endl;
cout << "sorts the array using the selection sort algorithm." << endl;
cout << "The sorted array is written to a file named cardList.srt." <<
endl;
}
void openFile(ifstream& inputFile, ofstream& outputFile){
inputFile.open("cardsList.txt");
if(!inputFile.is_open())
exit(1);
outputFile.open("cardsList.srt");
if(!outputFile.is_open())
exit(1);
}
void buildList(char (*array)[25], ifstream& inputFile){
for (int i = 0; i < 5; i++)
inputFile >> array[i];
}
void sortList(char (*list)[25], int length){
int firstOutOfOrder, location;
char temp[25];
for (firstOutOfOrder = 1; firstOutOfOrder < length; firstOutOfOrder++){
location = firstOutOfOrder;
while ( location > 0 && list[location - 1] > list[location]){
temp[25] = list[location][25];
list[location][25] = list[location - 1][25];
list[location - 1][25] = temp[25];
location--;
}
}
}
void writeFile(char (*array)[25], ofstream& outputFile){
for (int i = 0; i < 5; i++)
outputFile << array[i];
}
However my program only prints the instruct(); statements and nothing else appears to happen. This program is supposed to a create a file cardList.srt with the sorted list and that does not appear in my directory after compiling.
Either inputFile.is_open() or outputFile.is_open() return false and hence exit() is called.
I'm writing a vector array to an ofstream file, however certain values aren't getting written, I.E.:
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;
int main (){
char * hold = new char [100];
vector<double> fx(2049);
ifstream inputFile;
ofstream myFile;
inputFile.open("data.txt");
myFile.open("test.txt");
for (int c=0; c<2049; c++){
inputFile.getline(hold, 100);
fx[c] = atof(hold);
}
for (int c=0; c<2049; c++){
myFile << fx[c] << "\n";
}
}
Within fx, the second half is all equal to 0. (fx[1024] through fx[2048]==0). Within test.txt however, none of these 0 values are present, on the carriage return is applied. Any thoughts?
Thanks! (New to the formatting of these questions... any tips to make this more understandable would be appreciated.)
Note: I realize this program is rather redundant. The actual program has a great deal more functionality to it, this is just an area that is working incorrectly.
Try this
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <cstdlib>
#define MAX_FILE_LINES 2048
using namespace std;
//genarate random double number
double fRand()
{
double fMin = 100, fMax = 200;
double f = (double)rand();
return fMin + (f / (fMax - fMin));
}
//init file (if you need to create sample file with list of double numbers, you can use this function)
void fileInit(){
ofstream sourceFile;
sourceFile.open("D:\\source.txt");
if (sourceFile.is_open())
{
for (int i=0; i<MAX_FILE_LINES; i++){
sourceFile << fRand() << endl;
}
}
}
int main (){
string buffer;
vector<double> fx(MAX_FILE_LINES);
ifstream sourceFile;
ofstream destinationFile;
sourceFile.open("D:\\source.txt");
destinationFile.open("D:\\destination.txt");
//reading file lines to vector
int lineCount =0;
if (sourceFile.is_open())
{
while ( sourceFile.good() )
{
getline (sourceFile,buffer);
fx[lineCount] = atof(buffer.c_str());
lineCount++;
if (lineCount == (MAX_FILE_LINES-1)){
break;
}
}
sourceFile.close();
}
//write lines to new file
if (destinationFile.is_open())
{
for (int i=0; i<MAX_FILE_LINES; i++){
destinationFile << fx[i] << endl;
}
}
}
Why screw with handroll buffers for one-offs? You can't save a millionth of what it costs to think about cycles here, there's not enough waste to recoup.
Think about eliminating needless statements and unchecked failures first.
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
int main()
{
vector<float> data;
{
ifstream ids("source.txt",ios_base::in);
int linenr = 0;
for ( string line ; getline(ids,line) ; ) {
++linenr;
decltype(data)::value_type x;
istringstream s(line);
if ( s >> x )
data.push_back(x);
else
cerr << "crap line "<<linenr<<" ignored: " << line << '\n';
}
}
ofstream ods("object.txt");
for ( auto x : data )
ods << x << '\n';
}