2

I've made a program in c++ that takes in a file and the morph to apply to it through the command line. But, so far. My algorithm is taking in a file like :

.............
.............
..XXX.....X..
..XXX.....X..
..XXX........
..XXX........
..XXXXXXX....
..XXXXXXX....
..XXXXXXX....
.............
.............

and prints out something that looks like this :

.............
..X.X.....X..
.XXXXX...XXX.
..XXX.....X..
.XXXXX.......
..XXX.X.X....
.XXXXXXXXX...
..XXXXXXX....
.XXXXXXXXX...
..X.X.X.X....
.............

When it should be printing out something that looks like this:

.............
..XXX.....X..
.XXXXX...XXX.
.XXXXX...XXX.
.XXXXX....X..
.XXXXXXXX....
.XXXXXXXXX...
.XXXXXXXXX...
.XXXXXXXXX...
..XXXXXXX....
.............

I've made my program to go through each and every index and check to see if its the item they want to dilate, then look above, below, left, and right. To add another copy of its index to its surrounding grid. But why is my program printing out like that?

Here is the code I have so far:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
#include <algorithm>
//look up line by line parsing
using namespace std;
void replacee(vector<vector<char>> &vec, char oldd, char neww)
{
    for (vector<char> &v : vec) // reference to innver vector
    {
        replace(v.begin(), v.end(), oldd, neww); // standard library     algorithm
    }
}
void dialationn(vector<vector<char>> &vec, char suspect, char n)
{
    for (int i = 0; i < vec.size(); i ++) {
            for (int j = 0; j < vec[i].size(); j++) {
                if (vec[i][j] == suspect) {
                    if (i > 0) {
                     vec[i-1][j] = n;
                    }
                    if (j > 0) {
                     vec[i][j-1] = n;
                    }
                    if (i + 1<vec.size()) {
                        vec[i+1][j] = n;
                    }
                    if (j + 1<vec[i].size()) {
                        vec[i][j+1] = n;
                    }
                }
            }
        }
        replacee(vec, n, suspect);
}
void erode(vector<vector<char>> &vec, char suspect, char n)
{
    for (int i = 0; i < vec.size(); i ++) {
            for (int j = 0; j < vec[i].size(); j++) {
                if (vec[i][j] == suspect) {
                    if (i > 0) {
                     vec[i-1][j] = n;
                    }
                    if (j > 0) {
                     vec[i][j-1] = n;
                    }
                    if (i + 1<vec.size()) {
                        vec[i+1][j] = n;
                    }
                    if (j + 1<vec[i].size()) {
                        vec[i][j+1] = n;
                    }
                }
            }
        }
        replacee(vec, n, suspect);
}
int main(int argc, char* argv[]) {

    fstream fin; char ch;
    string name (argv[1]); //File Name.
    vector<vector<char>> data;
    // 2D Vector.
    vector<char> temp;
    // Temporary vector to be pushed 
    // into vec, since its a vector of vectors.
    fin.open(name.c_str(),ios::in);
    // Assume name as an arbitary file.
    string argument2 (argv[2]);
    while(fin)
    {
        ch = fin.get();
        if(ch!='\n') {
            temp.push_back(ch);
        }
        else 
        { 
            data.push_back(temp); 
            temp.clear(); 
        }
    }
    if (argument2 == "replace") {
            string argument4 (argv[4]);
            string argument3 (argv[3]);
        replacee(data, argument3[0], argument4[0]);
        for (int i = 0; i < data.size(); i ++) {
            for (int j = 0; j < data[i].size(); j++) {
                cout << data[i][j];
            }
            cout << endl;
        }
    }
    if (argument2 == "dialate") {
        string argument3 (argv[3]);
        dialationn(data, argument3[0], 'i');
        for (int m = 0; m < data.size(); m ++) {
            for (int n = 0; n < data[m].size(); n++) {
                cout << data[m][n];
            }
            cout << endl;
        }
    }

    fin.close();
} 

The main function takes the first argument as the text file name to parse it. Then, it looks at the second argument to see what the user wants to do, then based on argument 2, it calls the appropriate function replacee or dialate to apply a morph. After the char* containing the file has been modified from one of the functions, it then prints it out.

Note: the dialatee function changes all the characters it sees fit to 'i' then calls the replacee function to turn them back into the original output. This is done to prevent the function from reading already modified characters and applying unintentional morphs.

  • 2
    "`while(fin)`" ... [Why is iostream::eof inside a loop condition considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) – Swordfish Nov 11 '18 at 06:13

2 Answers2

0

You are overwriting your data before you parse it. Before setting an element of vec to n, make sure it is not suspect.

Stepping through your code with a good debugger should let you see this happening.

JaMiT
  • 9,693
  • 2
  • 12
  • 26
  • Ill try to implement this solution, So basically, dont add an i to a given direction of the pointer, while the index in the direction of the pointer = x. –  Nov 11 '18 at 06:21
  • I tried to implement this solution by incorporating lines of `if` statements like this one, `if(vec[i][j-1] != suspect) { vec[i][j-1] = n; }` but it didnt work, instead it made more than 95% of the grid = to suspect. –  Nov 11 '18 at 06:28
  • i may be the biggest idiot ever, you see, my program is supposed to work with multiple files with different arrangements. and i was testing the wrong file the entire time trying to compare it to the one in the post. You're answer is indeed correct. I apologize for being such an idiot. –  Nov 11 '18 at 06:37
0

When you hit the first 'X' you will write 'i' to the spaces above, below, left and right of it, replacing other 'X's you haven't read yet.

After your first pass through, things probably look like: ............. ..i.i.....i.. .iXiXi...iXi. ..iXi.....i.. .iXiXi....... ..XiX........ .iXiXiXiXi... ..XiXiXiX.... .iXiXiXiXi... ..i.i.i.i.... .............

So as you get to a spot that has been switched from 'X' to 'i' it doesn't match, and doesn't get treated the same way.

An easy fix would be to create a new vector, and any time you find an 'X' in the original vector, you place your 'i's up, down, left, right, and directly on (in the new vector) where the 'X' would be in your original vector. Then pass the new one on, since efficiency isn't your highest priority. This will avoid the overwriting, while reading, issues.

DMarczak
  • 454
  • 5
  • 15
  • 2
    Your explanation is on point and i understand why it wont work, but your solution doesn't work. And i agree that there could be a more efficient solution but in the end, efficiency inst high up on the scale for this program. –  Nov 11 '18 at 06:18
  • instead, it brings back the problem that calling the replace function fixes. –  Nov 11 '18 at 06:22
  • 1
    I have amended my answer, as you have rightly pointed out, that my original suggestion was a bit off. Please let me know if this new suggestion isn't going to work for you. – DMarczak Nov 11 '18 at 06:24
  • 2
    Thanks for helping me understand what was going on. Your solution does indeed work with the revision but before you changed it I tested another solution from another user that already worked with minimal code needed. I've tested your solution and indeed it does work. Thank you for the suggestions! –  Nov 11 '18 at 06:39