1

I'm currently writting a program where I try to filter extra spaces so if there are more than 1 spaces in a row, I discard the rest leaving only one

But this is only the first step because the aim of the program is to parse a txt file with mips assembly instructions.

So far I've opened the file, stored the content in a vector and then stored the vector content in an array. Then I check, if you find a char 2 times in a row shift the array to the left.

The problem is that the code works well for any other letter, except for the space character. (On the code below I test it with the 'D' character and it works)

#include <iostream>
#include <cmath>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <algorithm>

using namespace std;

class myFile {
    vector<string> myVector;
public:
    void FileOpening();
    void file_filter();
};

void myFile::FileOpening() {
    string getcontent;
    ifstream openfile;     //creating an object so we can open files

    char filename[50];
    int i = 0;

    cout << "Enter the name of the file you wish to open: ";
    cin.getline(filename, 50);   //whatever name file the user enters, it's going to be stored in filename
    openfile.open(filename);     //opening the file with the object I created

    if (!openfile.is_open())       //if the file is not opened, exit the program
    {
        cout << "File is not opened! Exiting the program.";
        exit(EXIT_FAILURE);
    };

    while (!openfile.eof())             //as long as it's not the end of the file do..
    {
        getline(openfile, getcontent);     //get the whole text line and store it in the getcontent variable

        myVector.push_back(getcontent);
        i++;
    }
}

void myFile::file_filter() {
    unsigned int i = 0, j = 0, flag = 0, NewLineSize, k, r;
    string Arr[myVector.size()];

    for (i = 0; i < myVector.size(); i++) {
        Arr[i] = myVector[i];

    }

    //removing extra spaces,extra line change
    for (i = 0; i < myVector.size(); i++) {
        cout << "LINE SIZE" << myVector[i].size() << endl;
        for (j = 0; j < myVector[i].size(); j++) {

            //If I try with this character for example,
            //it works (Meaning that it successfully discards extra 'Ds' leaving only one.
            // But if I replace it with ' ', it won't work. It gets out of the loop as soon
            //as it detects 2 consecutive spaces.

            if ((Arr[i][j] == 'D') && (Arr[i][j + 1] == 'D')) {
                for (k = j; k < myVector[i].size(); k++) {
                    Arr[i][k] = Arr[i][k + 1];
                    flag = 0;
                    j--;
                }
            }
        }
    }


    for (i = 0; i < myVector.size(); i++) {
        for (j = 0; j < myVector[i].size(); j++) //edw diapernw tin kathe entoli
        {

            cout << Arr[i][j];
        }
    }
}

int main() {
    myFile myfile;

    myfile.FileOpening();
    myfile.file_filter();
}

My question is, why does it work with all the characters except the space one, and how do I fix this? Thanks in advace.

Fureeish
  • 12,533
  • 4
  • 32
  • 62
John
  • 410
  • 1
  • 9
  • 21
  • So... what is the question? – Fureeish Sep 16 '18 at 17:38
  • My question is, why does it work with all the characters except the space one? – John Sep 16 '18 at 17:41
  • Have you tried either stripping your code to an [MCVE](https://stackoverflow.com/help/mcve) or stepping through your code with a debugger? – Fureeish Sep 16 '18 at 17:43
  • Sorry, I'm quite new to C++ and I don't know how would a debugger help me. I mean, I know when the error happens I just don't know why. – John Sep 16 '18 at 17:57
  • 1
    First of all, don't use `! openfile.eof()`. It's [always wrong](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong). Second of all, consider splitting your code to functions that will perform simpler tasks. That way, your code will be easier to test. Third of all, please improve your code formatting. You have a lot of uselees empty lines and such. – Fureeish Sep 16 '18 at 18:02
  • Thanks for the feedback. Just replaced the !openfile.eof() with the openfile.good(). But do you have any idea why the code won't work specifically for spaces? – John Sep 16 '18 at 18:14
  • `openfile.good()` is not going to change anything. It's just as wring as `eof()`. – n. m. could be an AI Sep 16 '18 at 18:15
  • You should replace it with `getline(openfile, getcontent)`, not with `openfile.good()`. As for the code not working specifically for spaces - how did you test it? Can you unit test the function? – Fureeish Sep 16 '18 at 18:15
  • 1
    `string Arr[myVector.size()];` - makes use of a gnu extension. Technically not portable. You could substitute by just cloning your vector. – selbie Sep 16 '18 at 18:15
  • `string Arr[myVector.size()];` and the following `for` loop are pointless. `auto Arr = myVector;` Also look at `[string::erase](https://en.cppreference.com/w/cpp/string/basic_string/erase)`. – n. m. could be an AI Sep 16 '18 at 18:20
  • I tested the code by creating a txt file in my project file and writting a random sentence (1 line). e.g THISDDDD IS A TEXT. output of this will be THISD IS A TEXT. But it won't work with spaces. – John Sep 16 '18 at 20:14
  • @John take a look at this one liner, for `std::string text = "annyyy texxxtt"`, you can: `text.erase(std::unique(text.begin(), text.end()), text.end());` It does everything you want. Just for the sake of mentioning the correct algorithm :) – Fureeish Sep 16 '18 at 21:36
  • If you are writing code so you can dump the assembly and re-write in Mips, then a C++/STL solution probably isn't what you are looking for. Even with full-optimizations, the generated assembly is likely to be much more complex than an equivalent program written in C. Just something to consider. – David C. Rankin Jun 28 '19 at 04:09

1 Answers1

0

Wow. Many lines of code. I can only recomend to learn more about the STL and algorithms.

You can read the complete file into a vector using the vectors "range"-constructor and std::istream_iterator. Then you can replace one or more spaces in a string by using a std::regex. This is really not complicated.

In the below example, I do all the work, with 2 lines of code in function main. Please have a look:

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <string>
#include <fstream>
#include <regex>

using LineBasedTextFile = std::vector<std::string>;

class CompleteLine {    // Proxy for the input Iterator
public:
    // Overload extractor. Read a complete line
    friend std::istream& operator>>(std::istream& is, CompleteLine& cl) { std::getline(is, cl.completeLine); return is; }
    // Cast the type 'CompleteLine' to std::string
    operator std::string() const { return completeLine; }
protected:
    // Temporary to hold the read string
    std::string completeLine{};
};

int main()
{
    // Open the input file
    std::ifstream inputFile("r:\\input.txt");
    if (inputFile)
    {
        // This vector will hold all lines of the file. Read the complete file into the vector through its range constructor
        LineBasedTextFile text{ std::istream_iterator<CompleteLine>(inputFile), std::istream_iterator<CompleteLine>() };
        // Replace all "more-than-one" spaces by one space
        std::for_each(text.begin(), text.end(), [](std::string& s) { s = std::regex_replace(s, std::regex("[\\ ]+"), " "); });

        // For Debug purposes. Print Result to std::out
        std::copy(text.begin(), text.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
    }
    return 0;
}

I hope, I could give you some idea on how to proceed.

A M
  • 14,694
  • 5
  • 19
  • 44