This code should read a .pnm file. I tried to run it with 2 resolutions:
200x200 px: Here everything works just fine.
500x281 px: Code instantly crashes, raising a SIGSEGV error.
As far as I know, SIGSEGV is related to memory issues. I have 8GB of RAM, a quantity that I judge to be enough to run this. I don't have any idea about why it's happening and how to fix it.
Code
#define IO_ERROR (5)
#define X_DIMENSION (500)
#define Y_DIMENSION (281)
#define C_DIMENSION (3)
#define HEADER_SIZE (3)
#define BODY_SIZE (X_DIMENSION * Y_DIMENSION * C_DIMENSION)
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int readImage(string fileName, string *imgHeader, string *imgBody)
{
ifstream inputFile(fileName);
if (!inputFile.is_open())
return IO_ERROR;
string line;
int count = 0;
while (getline(inputFile, line)) {
if (line.find("#") != string::npos)
continue;
if (count < 3)
imgHeader[count] = line;
else
imgBody[count - HEADER_SIZE] = line;
count++;
}
inputFile.close();
return 0;
}
void numericParser(const string *imgBody, unsigned char *numericBody)
{
int i = 0;
while(i < BODY_SIZE) {
numericBody[i] = (unsigned) atoi(imgBody[i].c_str());
i++;
}
}
void rgbParser(const string *imgBody, unsigned char rgbMatrix[X_DIMENSION][Y_DIMENSION][C_DIMENSION])
{
unsigned char numericBody[BODY_SIZE];
numericParser(imgBody, numericBody);
int k = 0;
for (int i = 0; i < X_DIMENSION; i++) {
for (int j = 0; j < Y_DIMENSION; j++) {
for (int c = 0; c < 3; c++) {
rgbMatrix[i][j][c] = numericBody[k];
k++;
}
}
}
}
void printInfo(const string *header, const string *body)
{
cout << "#-*- Image Header -*-" << endl;
for (int i = 0; i < HEADER_SIZE; i++) {
cout << header[i] << endl;
}
cout << "#-*- Image Body -*-";
for (int i = 0; i < 5 * C_DIMENSION; i++) {
if (i % 3 == 0) cout << endl << "R: " << body[i];
else if (i % 3 == 1) cout << " G: " << body[i];
else cout << " B: " << body[i];
}
cout << endl << ". . ." << endl;
}
int main()
{
string fileName;
cout << "File name: ";
cin >> fileName;
string imgHeader[HEADER_SIZE];
string imgBody[BODY_SIZE];
if(readImage(fileName, imgHeader, imgBody) == IO_ERROR)
return IO_ERROR;
// printInfo(imageData);
unsigned char rgbMatrix[X_DIMENSION][Y_DIMENSION][C_DIMENSION];
rgbParser(imgBody, rgbMatrix);
return 0;
}
Additional Info
I'm on Arch Linux 64-bit, using CLion as IDE.
Related
I am trying to create a program to combine two matrices. The first is to add them, the second is to subtract them, but I am getting an 1120 error. I don't know if that's because my code is bad, or if there's something wrong with my compiler. Here's what I've tried.
#include <iostream>
#include <fstream>
using namespace std;
int main() {
fstream matrix_file("matricies.txt");
fstream result1_file("result1.txt");
fstream result2_file("result2.txt");
matrix_file.open("matricies.txt", ios::in);
if (!matrix_file) {
cout << "File was not opened!" << endl;
}
else {
cout << "File opened successfully!";
}
result1_file.open("result1.txt", ios::app);
if (!result_file) {
cout << "File was not created!" << endl;
}
else {
cout << "File created successfully!";
}
result2_file.open("result1.txt", ios::app);
if (!result_file) {
cout << "File was not created!" << endl;
}
else {
cout << "File created successfully!";
}
int matrix1[9];
int matrix2[9];
int result1Matrix[9];
int result2Matrix[9];
for (int i = 0; i < 9; ++i)
{
matrix_file >> matrix1[i];
}
for (int i = 0; i < 9; ++i) {
matrix_file >> matrix2[i];
}
for (int i = 0; i < 9; ++i) {
result1Matrix[i] = matrix1[i] + matrix2[i]
}
for (int i = 0; i < 9; ++i) {
result2Matrix[i] = matrix1[i] - matrix2[i]
}
for (int i = 0; i < 9; ++i) {
result1_file >> result1Matrix[i] ;
}
for (int i = 0; i < 9; ++i) {
result2_file >> result2Matrix[i];
}
matrix_file.close();
result1_file.close();
result2_file.close();
}
Line 35, 38: expected ';' in end line
Output file (result_file) must use operator '<<' instead of '>>'.
I am getting a OUTOFRANGE error with vector in c++ when using insert method. I don't know why this is happening but I was able to narrow down the problem to one line through debugging. Here is the full code.
//
#include <cstdio>
#include <iostream>
#include <vector>
#include <fstream>
#include <cassert>
#include <string>
using namespace std;
class suffixArray{
public: suffixArray(std:: string concatenated ){
vector<int> attempt1;
const int size = (int)concatenated.length();
int rank[7] = {};
char *suffixPointers[concatenated.length()];
int value[concatenated.length()];
for(int i =0; i <= size-1; i++){
suffixPointers[i] = &concatenated[i];
value[i] = (int)concatenated[i];
}
std::cout << "[";
for(int i = 0; i<= size-1; i++){
std::cout <<value[i] << " ";
}
std::cout << "]"<< std:: endl;
for(int i = 0; i<=size -1; i++){
if(i == 0){
rank[i] = i;
attempt1.push_back(i);
}
else if(value[i] > value[i-1]){
rank[i] = i;
attempt1.push_back(i);
}else{
int current =i;
int savedValue = value[i];
int prevSavedRank;
int indexcounter = i;
while(savedValue <= value[attempt1.at(indexcounter-1)] && indexcounter - 1 >= 0 ){
indexcounter--;
}
cout << indexcounter << endl;
attempt1.insert(attempt1.begin() + indexcounter ,i);
// while(savedValue <= value[rank[current-1]] && current-1 >= 0){
// prevSavedRank= rank[current-1];
// rank[current-1] = i;
// rank[current] = prevSavedRank;
// current--;
// }
}
}
int now;
for(int i = 0; i<= 3; i++){
now = attempt1[i];
std::cout << now << " ";
}
}
};
void read_file(string filename, string& contents, int& num_lines){
ifstream f;
f.open(filename.c_str());
string line;
contents = "";
num_lines = 0;
while(getline(f, line)){
contents.append(line.substr(0, line.length()));
num_lines++;
}
f.close();
}
int main(int argc, const char* argv[]) {
std:: string test = "BANANA$";
suffixArray testString (test);
string fn;
string contents;
int num_lines;
cout << "File 1:" << endl;
cin>> fn;
read_file(fn, contents, num_lines);
cout << "Read: " << fn << "\n";
cout << " * " << num_lines << " lines\n";
cout << " * " << contents.length() << " characters (excluding newlines)\n";
//cout <<" * " << contents << endl;
// char * contents_cstring = (char*)contents.c_str();
//for(int i =0; i< contents.length(); i++){
// assert(contents_cstring[i] == *(contents_cstring + 1));
// assert(contents_cstring[i] == contents.at(i));
//}
//assert(contents_cstring[contents.length()] == '\0');
return 0;
}
I have narrowed down the problem to be the problem to be from this line, but can not figure out why it is occurring, or how to fix it.
attempt1.insert(attempt1.begin() + indexcounter ,i);
Consider the first time the program reaches
int indexcounter = i;
while(savedValue <= value[attempt1.at(indexcounter-1)] && indexcounter - 1 >= 0){
indexcounter--;
}
i will be 1. indexcounter-1 will be 0. If the loop is entered,
int indexcounter = 1;
while(savedValue <= value[attempt1.at(0)] && 0 >= 0 ){
1--;
}
OK, so what happens the next time?
while(savedValue <= value[attempt1.at(-1)] && -1 >= 0 ){
0--;
}
value[attempt1.at(-1)] happens before -1 >= 0, s the trap to prevent -1 fails. Reverse the order of the tests.
while(indexcounter - 1 >= 0 && savedValue <= value[attempt1.at(indexcounter-1)])
Could be more bugs, but after that the program hangs and asks for a file that I don't have.
I am trying to write a function that calculates the gap heursitic. Below is my code:
#include <iostream>
using namespace std;
#include <vector>
#include <map>
#include <string>
using namespace std;
int main(int argc, char const *argv[])
{
string direction = "backward";
string state_string = "012345";
string goal_state_string = "125430";
int n = 3;
string ignored_pancakes;
int gap = 0;
state_string += to_string(state_string.length());
unsigned int goal_state_index;
goal_state_string += to_string(goal_state_string.length());
if (direction == "forward")
{
for (unsigned int i = 0; i < n; i++)
{
ignored_pancakes += goal_state_string[i];
}
}
else
{
for (unsigned int i = 0; i < n; i++)
{
ignored_pancakes += state_string[i];
}
}
for (int i = 0; i < state_string.length(); i++)
{
if ((ignored_pancakes.find(state_string[i + 1]) != string::npos) or (ignored_pancakes.find(state_string.at(i)) != string::npos))
{
continue;
}
if (abs(goal_state_string.find(state_string[i])-goal_state_string.find(state_string[i+1])!=1)){
gap++;
}
cout << state_string.at(i) << "\t" << state_string.at(i + 1) << endl;
}
// cout << state_string << endl;
cout << ignored_pancakes << endl;
cout << gap << endl;
}
The output that I expect is as follows:
3 4
4 5
5 6
012
2
But what is being printed out is:
3 4
4 5
5 6
Strangely when I comment out the line that says :
cout << state_string.at(i) << "\t" << state_string.at(i + 1) << endl;
The output is:
012
2
Why is it printing out something completely different depending on that line which seems irrelevant.
for (int i = 0; i < state_string.length(); i++)
{
// ...
cout << state_string.at(i) << "\t" << state_string.at(i + 1) << endl;
}
With i + 1 you are accessing the string out of bounds. Change your loop to
for (int i = 0; i < state_string.length() - 1; i++)
I was writing some code challenge from reddit about encrypting strings and I came up with something like this:
#include <iostream>
#include <string>
using namespace std;
string encrypt(string sentence);
int main()
{
string sentence;
int i = 0;
cout << "Welcome. Enter a sentence: ";
getline(cin, sentence);
cout << sentence << endl;
encrypt(sentence);
cout << endl << endl;
system("pause");
return 0;
}
string encrypt(string sentence)
{
int i = 0;
int x = (sentence.size());
string *encrypted_sentence = new string[sentence.size()];
int *wsk = new int[sentence.size()];
for (i = 0; i < x; i++)
{
wsk[i] = sentence[i];
}
for (i = 0; i < x; i++)
{
if (wsk[i] == ' ')
continue;
else if (islower(wsk[i]))
{
if (wsk[i] <= 99)
wsk[i] = (wsk[i] + 23);
else
wsk[i] = (wsk[i] - 3);
}
else
{
if (wsk[i] <= 67)
wsk[i] = (wsk[i] + 23);
else
wsk[i] = (wsk[i] - 3);
}
}
for (i = 0; i < x; i++)
{
//cout << static_cast <char> (wsk[i]);
encrypted_sentence[i] = wsk[i];
}
return *encrypted_sentence;
}
My problem is, that there is nothing that gets returned. After I run the program I get nothing in return. Can anybody point me in the right direction with this? What have I missed?
First main() returns an int always. void main() is not standard. Secondly:
string encrypted_sentence = new string[sentence.size()];
Will not even compile. encrypted_sentence is of type std::string but you are trying to assign to it a std::string *. Third you should avoid using using namespace std;
Update:
I believe you are trying to output the encrypted string at:
cout << endl << endl;
But all this is doing is outputting 2 newlines and flushing the output twice. If you want to display the encrypted string then you either need to capture the return of the encrypt() function and display it or encrypt() can take the string in by reference. IF you change encrypt() to take a reference then it would become:
void encrypt(string & sentence)
{
string *encrypted_sentence = new string[sentence.size()]; // get rid of this line as it is not needed.
//...
for (i = 0; i < x; i++)
{
sentence[i] = wsk[i];
}
}
And then you would output the string with:
cout << sentence << endl;
In case anyone would seek an answer to this question, I've come up with this, and I'm pretty sure it finally works how I wanted it to:
#include <iostream>
#include <string>
std::string encrypt(std::string to_encrypt);
int main()
{
std::string sentence;
std::string result;
std::cout << "Welcome. Please enter a sentence: ";
getline(std::cin, sentence);
result = encrypt(sentence);
std::cout << "Result: " << result << std::endl;
system("pause");
return 0;
}
std::string encrypt(std::string to_encrypt)
{
int i = 0;
int x = (to_encrypt.size());
std::cout << std::endl << "x = " << x << std::endl;
int *temp = new int[to_encrypt.size()];
for (i = 0; i < x; i++)
{
temp[i] = to_encrypt[i];
}
for (i=0; i < x; i++)
{
if (temp[i] == ' ')
continue;
else if (islower(temp[i]))
{
if (temp[i] <= 99)
temp[i] = temp[i] + 23;
else
temp[i] = temp[i] - 3;
}
else
{
if (temp[i] <= 67)
temp[i] = temp[i] + 23;
else
temp[i] = temp[i] - 3;
}
}
std::string encrypted;
for (i = 0; i < x; i++)
{
encrypted += (static_cast <char> (temp[i]));
}
return encrypted;
}
The code is obviously wrong. string *encrypted_sentence = new string[sentence.size()]; allocates an ARRAY of strings! Not a single string. Judging from that, you can see how your code is wrong.
Here is the code
#include <iostream>
#include <cstdlib>
#include <fstream>
using namespace std;
class sudoku {
public:
void read(ifstream ifs);
void write(ofstream ofs);
private:
int puzzle[9][9];
};
void sudoku::read(ifstream ifs){
int row;
int col;
int value;
int linenum = 1;
bool error = false;
while(ifs >> row){
ifs >> col;
ifs >> value;
if(row < 0 || row > 8){
cerr << "Incorrect Row Value: " << row << " Line Number: " << linenum;
error = true;
}
if(col < 0 || col > 8){
error = true;
cerr << "Incorrect Col Value: " << col << " Line Number: " << linenum;
}
if(value < 1 || value > 9){
error = true;
cerr << "Invalid Value: " << value << " Line Number: " << linenum;
}
if (! error)
puzzle[row][col] = value;
error = false;
}
}
void sudoku::write(ofstream ofs){
for (int i = 0; i < 9; i++){
for (int j = 0; j < 0; j++){
if(puzzle[i][j] != 0){
ofs << i << ' ' << j << ' ' << puzzle[i][j] << endl;
}
}
}
}
int main(int argc, char* argv[]){
sudoku sudopuzzle;
string filename = argv[1];
int found = filename.find(".txt");
if(found == filename.npos) {
cout << "No .txt extension" << endl;
return 0;
}
ifstream ifs;
ifs.open(filename.c_str());
sudopuzzle.read(ifs);
ifs.close();
filename.resize(filename.size()-4);
filename.append("_checked.txt");
ofstream ofs;
ofs.open(filename.c_str());
sudopuzzle.write(ofs);
ofs.close();
return 0;
}
This program is supposed to read a generated puzzle. make sure its valid and write it to another file. Normally I am good at figuring out errors but this one is a mess. It spits out stuff referring to the inclusion of iostream and cites files that I have nothing to do with. Im guessing its some error that comes with passing fstreams to funcitons or something. any clue?
You should be passing a reference to the stream objects:
class sudoku {
public:
void read(ifstream &ifs);
void write(ofstream &ofs);
private:
int puzzle[9][9];
};
void sudoku::read(ifstream &ifs){
// sudoku::read code here
}
void sudoku::write(ofstream &ofs){
// sudoku::write code here
}
This change is required because both ifstream and ofstream have a =delete copy constructor. (Hat tip: #awesomeyi)