I am trying to define a class CDTable, which has a variable double table[4][4000] (4 by 4000 array of doubles) and some functions that carry out calculations based on the table.
My CDTable.h looks something like:
#define CDTABLE_H
class CDTable {
public:
double table[4][4000];
CDTable(string fileName);
double dLookUp(double z);
};
and a part of my CDTable.cpp looks like:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <ctime>
#include <stdlib.h>
#include "CDTable.h"
using namespace std;
CDTable::CDTable(string fileName) {
fstream file;
file.open(fileName.c_str(), ios::in);
string line;
int col = 0;
int row = 0;
getline(file, line); //skip the title line
while (getline(file, line, '\t')) { //for each line
istringstream ss(line);
double val;
while (ss >> val) { //read the value
table[row][col] = val; //assign the value
++col; //next column in the table
}
++row; //next line in the table
col = 0; //reset column
}
file.close();
}
int main() {
CDTable cd = CDTable("CDLookUp.dat");
return 0;
}
So, I mean to construct a CDTable object by giving it a string fileName which is a .dat file of two dimensional array (the first line of .dat file is not real data but a title line). I have other relevant methods implemented in CDTable.cpp as well, but I have not included them since they do not seem to be the problem.
CDTable.cpp compiles without any errors, but when I run it, I get Segmentation fault (core dumped).
Can somebody tell me what's wrong here? Is there a better way to convert a .dat or .txt two dimensional data to a two dimensional array of doubles in C++?
Related
I'm building a class named Board, that will get it's details from a txt file.
#define ROW 25;
#define COL 80;
class Board
{
char _board[ROW][COL] = {0};
public:
Board(string name); // our new constructor - reads map from file.
};
It receives string name, and tries to open a file with the specific name.
In case we are indeed in the right file, I want to read the chars from it, and copy them into a board.
I've been trying several things, that are summed up in this code:
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
Board::Board(string name)
{
string line;
ifstream file(name);
int i = 0;
if (file.is_open())
{
while (!file.eof())
{
(1) getline(file, line);
(2) const char* test = line.c_str();
(3) strcpy_s(_board[i], test);
(4) _board[i] = line;
i++;
}
// MORE FUNCTIONS NOT RELEVANT TO THIS QUESTION
}
}
I get the following errors:
For (3): The program crashes.
For (4): expression must be a modifiable lvalue.
For (1), (2): test and line are worked well.
Is there any other simplier way to copy string to char* without using ugly loops, and copy every single char?
Why is (3) crashing my program?
Thanks in advance!
Unrelated, but void main() had been deprecated for ages and is incorrect in current versions of the standard: it shall be int main()...
Next while (!file.eof()) is a common but terrible thing: eof becomes true only after a reading operation returned nothing. That means that you will process the last line twice...
For your errors:
(4) _board[i] is an array, and an array cannot be on the left size of an assignment (idiomatically: it is not a lvalue)
(3): strcpy_s is not a drop-in replacement for strcpy and your compiler should have emit warnings (any correct compiler would have...). It should be:
strcpy_s(_board[i], COL, test);
#include <iostream>
#include <fstream>
#include <string>
#define ROW 25;
#define COL 80;
int i=0;
class Board
{
char _board[ROW][COL] = {0};
public:
Board(string name); // our new constructor - reads map from file.
};
Board::Board(string name)
{
fstream newfile;
newfile.open(name,ios::in);
if (newfile.is_open()){
string tp;
while(getline(newfile, tp)){
strcpy(_board[i], tp);
i++;
}
newfile.close();
}
}
I am solving a twoSum problem.
Steps:
Read an input file with a following template:
7
1 7 3 4 7 9
First line is the target number, second line is a number sequence.
Numbers can be in range 0 < N < 999999999
If the sum of two numbers from the number sequence equals the target number, I write "1" to the output file.
If there are no numbers the sum of which equals the target number then I write "0" to the output file.
I need to optimize memory usage in my code. How can I do that?
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <unordered_map>
#include <string>
#include <algorithm>
using namespace std;
int main() {
ifstream f1;
vector<int> nums;
string line;
string source;
//Open input file and read it to a string
f1.open("input.txt");
while (getline(f1, line, '\n')) {
source+=line + " ";
} f1.close();
//Parse the string into an int vector
stringstream parser(source);
int num;
while (parser >> num) { nums.push_back(num); }
//Clear used strings
line = "";
source = "";
//Get target number
int target = nums.at(0);
//Get number sequence
nums.erase(nums.begin());
bool flag = false;
//Check number sequence for two numbers sum of which equals the target number
unordered_map<int, int> mp;
for(int i=0;i<nums.size();i++){
if(mp.count(nums[i])==1){
flag = true;
break;}
mp[target-nums[i]]=i;
}
//Write the result into the output file
ofstream f2;
f2.open("output.txt");
f2 << flag;
f2.close();
}
There are a couple of things you can do to minimise memory usage here. First up, you don't need to read entire contents of the file into std::string. You can read directly into std::vector, or better still read the file contents into a single int variable and process the numbers as you go. Another thing: you do not need to use a std::unordered_map, because presence of the key is the only thing you are really interested in, so std::unordered_set is sufficient. Below a simple solution making use of that suggestions:
#include <fstream>
#include <unordered_set>
int main() {
std::ifstream input {"input.txt"};
int target;
input >> target;
int current_number;
bool found = false;
std::unordered_set<int> observed_numbers;
while (input >> current_number) {
if (observed_numbers.count(target - current_number) > 0) {
found = true;
break;
}
observed_numbers.insert(current_number);
}
std::ofstream output {"output.txt"};
output << found;
}
I have a problem trying to read coordinates from a .csv file to a 2d array , to use it as input to a linear regression model .I know how to read from a file to an array but i needed the informations of the file to be double and not string so I thought i should see what the output whould be. I can't get it right.The problem is that the file's lines are being read 30 times each one of them and i can't figure it out.
The code is here:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <cmath>
#include <limits>
#include <iomanip>
#include <vector>
using namespace std;
int main()
{
cout<<setprecision(10);
//vector<vector<double> > observ_matr;
ifstream myfile("Salary_Data.csv");
vector<vector<double> > vec;
string line;
while(getline(myfile,line))
{
stringstream lineStream(line);
string cell;
vector<double> temp_vec;
while(getline(lineStream, cell, ','))
{
temp_vec.push_back(atof(cell.c_str()));
}
vec.push_back(temp_vec);
}
for(int i=0;i<vec.size();i++)
{
for(int j=0;j<vec.size();j++)
{
cout<<vec[i][j]<<"\t\t";
}
cout<<endl;
}
//cout<<vec[1].size();
return 0;
}
"myfile" is this , this .csv file
The output i am getting after running the code is this:
The problem is here...
for (int j = 0; j < vec[i].size(); j++) // vec[i].size() instead of vec.size()
I'm making a function importcsv() which takes in a filename and outputs a 2D array. For some reason, whenever I use the following version of importcsv(), the compiler runs smoothly, but the executable always returns a "segmentation fault: 11" error.
typedef vector<vector<double> > matrix;
matrix importcsv(string filename)
{
ifstream myfile (filename); //Constructs a stream, and then asssociates the stream with the file "filename"
matrix contents; // Vector which will store the contents of the stream.
int i, j;
while(!myfile.eof())
{
if(myfile.get()==','){++j;}
else if(myfile.get()=='\n'){++i; j=0;}
else{
contents[i][j]=2;}
}
return contents;
}
Can anyone find the source of the error? btw I have the following header:
#include <fstream>
#include <iostream>
#include <array>
#include <vector>
using namespace std;
You are getting "segmentation fault: 11" since you have not allocated memory for contents.
contents[i][j] will work only if contents has something in it.
You can divide reading of the file and constructing the matrix into various parts:
Reading all the numbers in a line and treating it as a row of contents.
Reading a number from the line and treating it as a column of a row.
This way, the program can be simplified. This also helps you easily isolate problems when there are any and fix them.
typedef vector<vector<double> > matrix;
double readNextNumber(std::istream& str)
{
double n = 0.0;
str >> n;
// Skip until we get ',' or '\n'
while (str)
{
int c = str.getc();
if ( c == ',' || c == '\n' || c == EOF )
break;
}
return n;
}
std::vector<double> importRow(std::ifstram& myfile)
{
std::string line;
std::vector<double> row;
// Read a line as a string.
// Then parse the string using std::istringstream.
// When you have finished parsing the line, you know
// you have finished constructing a row of the matrix.
std::getline(myfile, line);
if ( myfile )
{
std::istringstream str(line);
while (str)
{
double n = readNextNumber(str);
if (str)
{
row.push_back(n);
}
}
}
return row;
}
matrix importcsv(string filename)
{
ifstream myfile (filename); //Constructs a stream, and then asssociates the stream with the file "filename"
matrix contents; // Vector which will store the contents of the stream.
while(!myfile.eof())
{
std::vector<double> row = importRow(myfile);
if (myfile)
{
contents.push_back(row);
}
}
return contents;
}
You haven't defined the size of contents. So by default, it will be a vector of 0 element. Therefore the calls to the operator[] will lead to a segmentatin fault.
Implementing the advice of the others here, the quick fix is to use resize() before reading each value into the array:
//WARNING: THIS PROGRAM UTILIZES C++11
#include <fstream>
#include <iostream>
#include <array>
#include <vector>
#include <cctype>
#include <thread>
using namespace std;
typedef vector<vector<double> > matrix;
matrix importcsv(string filename)
{
ifstream myfile ("wavelengthtorgb.csv"); //Constructs a stream, and then asssociates the stream with the file "filename".
matrix contents {{0.0}};
char nextchar; double data; int i,j;
while(!myfile.eof())
{
myfile.get(nextchar);
if(nextchar==',')
{
++j;
contents[i].resize(j+1);
cout<<"encountered a comma."<<" contents is now " <<i+1<<" x "<<j+1<<'\n';
}
else if(isspace(nextchar))
{
myfile.get(); //You might not need this line - first run with this line, and if there is an error, delete it, and try again.
++i;
contents.resize(i+1);
j=0;
contents[i].resize(j+1);
cout<<"encountered a carriage return."<<" contents is now " <<i+1<<" x "<<j+1<<'\n';
}
else
{
myfile.unget();
myfile >> data;
contents[i][j]=data;
cout<< "encountered a double."<<" contents("<<i<<','<<j<<")="<<data<<'\n';
}
}
return contents;
}
I am attempting read in a file and create a 2D vector to store the game board for a word search game but I can't seem to get it to read more than the first line. I'm sure it is something small but I put in a test display for the 'board' vector and all that shows up is the first line of the text file.
Here is some of my code:
'Board.cpp'
#include "stdafx.h"
#include "Board.h"
#include <fstream>
#include <iostream>
using namespace std;
Board::Board(void)
: rows(0)
{
}
Board::~Board(void)
{
}
void Board::readInFile(void)
{
ifstream indata;
indata.open("Puzzle.txt");
indata >> rows;
for(int i = 0; i < rows; i++){
char tmpChar;
for(int j = 0; j < rows; j++){
indata >> tmpChar;
row.push_back(tmpChar);
}
board.push_back(row);
}
indata.close();
}
'Board.h'
#pragma once
#include <vector>
using namespace std;
class Board
{
public:
Board(void);
~Board(void);
void readInFile(void);
protected:
vector<vector<char>> board;
vector<char>row;
protected:
int rows;
};
Here is how the text file is set up:
16
BDXWASEESPHWEBGB
SIGJVAWDFLCTZIAM
ENKVESMARNAEBRRI
IKOEOPZLUKMVJDDL
KLIRELOBSNPOFWEC
SBOHKLLRHSIFPANA
RSKWMEEEPEITPTPE
EZPIELLLYMOOQCDH
TAWDLGGLZBUNDHOJ
ASIOJNFOPKAJAPBP
WLRCIILROZXLSCID
SKATEBOARDGCLCIA
LLABESABIVOTNVVE
VOFRISBEETMIEVZG
BWADEVAUCYCSWING
XNJFJPZHBTBFTSAW
There are much better ways to handle input files. Firstly, rather than using a vector<char>, just use a std::string, and rather than using a vector<vector<char> >, just use a vector<string>. I'm not sure I understand why row is a member of the class if it is only being used to fill the board. Anytime you need the last item in board you can just do board.back() or *board.rbegin().
void Board::readInFile(void)
{
ifstream indata("Puzzle.txt", ios::in);
if(!ifstream.is_open())
return;
indata >> rows; //you don't really need to do this if you take
//the row count out of the file, but if you can't
//change the file, leave it in so as not to corrupt
//the loop that follows
string line;
while(getline(indata, line)){
board.push_back(line);
}
indata.close();
}
Really, you don't need to have the file store the rows variable.
Your function would also be more reusable if readInFile took the filename as a parameter so it could open anything instead of only one specific filename.