1

I have made a code which accepts a txt file as input, and parse, and put them in 2d array myarray[][2]. Input file structure looks like this:

aaa/bbb
bbb/ccc
ccc/ddd

And it should be parsed like this:

myarray[0][0] = "aaa"
myarray[0][1] = "bbb"
myarray[1][0] = "bbb"
myarray[1][1] = "ccc"

The code which I made to do this:

void Parse_File(string file){
    ifstream inFile;
    inFile.open(file);
    if (inFile.is_open()){
        inFile.clear();
        int lines = count(istreambuf_iterator<char>(inFile), istreambuf_iterator<char>(), '\n');
        string myarray[lines][2];
        int mycount = 0;
        do{
            getline(inFile, input);
            myarray[mycount][0] = input.substr(0, input.find("/"));
            myarray[mycount][1] = input.substr(input.find("/") +1, input.length());
            mycount++;
        }while (input != "");
    }else{
        Fatal_Err("File Doesn't Exist");
    }
    inFile.close();
}

But myarray doesn't have anything in it after this function. The do-while statement doesn't loop. I can't figure out why. Any help is appreciated. Thanks.

Royna
  • 13
  • 3
  • 2
    After you've read all the data in your `count` call, what's left to read from `inFile`? – Stephen Newell Jan 20 '21 at 04:21
  • Where is `input` declared/defined? – chux - Reinstate Monica Jan 20 '21 at 04:24
  • Sorry about `readline()`. My mistake. – Royna Jan 20 '21 at 04:29
  • Input is declared by `std::string input` – Royna Jan 20 '21 at 04:30
  • Besides, VLA is not standard C++. And what's the point of putting the array inside the block? – user202729 Jan 20 '21 at 04:33
  • After I've read all the data in my `count` call, which I think is getting the text file's lines, there is nothing to read because I am reading the whole file line by line – Royna Jan 20 '21 at 04:34
  • Your call to `count` will consume the entire contents of the file. There's nothing left for `getline` to read. If you copy this pattern from somewhere, that source shouldn't be trusted. – Stephen Newell Jan 20 '21 at 04:37
  • Which editor/compiler are you coding in? It is best if you know how to debug in that said editor so you can see what's happening... – AzuxirenLeadGuy Jan 20 '21 at 04:39
  • Oh, I didn't know that. Is there no way to count the textfile's lines without getting `getline` nothing to read after? Or should I just set the array's size exactly. – Royna Jan 20 '21 at 04:40
  • I'm in linux, using clang – Royna Jan 20 '21 at 04:41
  • The problem is that `count ()` reads the whole file (so there is nothing left to read). A simple solution (not the best): after you have counted the number of lines close the file then reopen it to reset everything back to the start of the file. – Martin York Jan 20 '21 at 05:21
  • There is another bug in counting the lines. It counts the number of `\n` characters. What if the last line does not have a new line character? You need to check if the last character in the file was a new line. If it was not then add one to `lines` – Martin York Jan 20 '21 at 05:23

2 Answers2

1

Move "getline(inFile, input);" to the end of your loop and call it again right before you enter. input is probably "" before you enter the loop, so the loop is never called and input is never updated.

Dark Matter
  • 325
  • 2
  • 8
1

Your file had a few issues, but the major one was: You forgot to bring your file reading pointer back to the beginning of the text document. The count function took the said pointer to the end, so you needed to bring it back.

So you need to use the seekg() function to drag the pointer wherever you wish to.

See if the code below works for you

void Parse_File(string file)
{
    ifstream inFile;
    inFile.open(file);
    if (inFile.is_open())
    {
        inFile.clear();
        int lines = count(istreambuf_iterator<char>(inFile), istreambuf_iterator<char>(), '\n');
        //Pitfall : By counting the lines, you have reached the end of the file.
        inFile.seekg(0);// Pitfall solved: I have now taken the pointer back to the beginning of the file.
        ....
        ....//Rest of your code
    }
}

Also, you need to learn debugging so that you understand your code more easily. I would recommend visual studio code for debugging c++.

AzuxirenLeadGuy
  • 852
  • 1
  • 10
  • 17
  • Don't do this: `string **myarray = new string *[lines];` us a vector. – Martin York Jan 20 '21 at 05:25
  • 1
    Don't do this: `while (!inFile.eof())` its broken. see [this](https://stackoverflow.com/q/5605125/14065) – Martin York Jan 20 '21 at 05:26
  • 1
    This is also wrong most of the time: `++lines`. Only increment if the last character in the file is not a '\n' – Martin York Jan 20 '21 at 05:27
  • One level of indirection to many: `myarray[mycount] = new string[2]`. If you are not going to use a vector then your allocation of the array should not allocate an array of pointers. Just allocate an array of (array[2] of strings). No need to create another level of indirection. – Martin York Jan 20 '21 at 05:29
  • @MartinYork Thank you for pointing out the flaws. While I understood why using `eof()` function and using `++lines` statement without checking if the file ends with '\n' are wrong, can you please elaborate why using a vector as opposed to using an array of string can lead to wrong results. – AzuxirenLeadGuy Jan 20 '21 at 05:38
  • 1
    Manually using new/delete is inherently flawed because you have not considered exceptions and its effect on manual resource management. You should be using RAII to guarantee that you don't leak resources in C++ which leads us to using the correct classes to manage the resources (In this case vectors). Otherwise you may as well be writting in C. – Martin York Jan 20 '21 at 06:15
  • 1
    https://gist.github.com/Loki-Astari/2189f23d331a4237cd80dd4df78e8c69 – Martin York Jan 20 '21 at 06:28