-1

I am trying to display text file backwards line by line. I want to do this with char and dynamic allocation. I allocate a 2d dynamic array for this purpose. But the problem is that every line I read in the erase the precedent. This is my code :

int main()
{
    char path[256]; string name;
    cout << "Enter path:" << endl; cin >> path;

    ifstream file(path);
    if (!file) { cout << "ERROR" << endl; return -1; }

    char** sentence = new char* [100];
    for (int i = 0; i < 100; i++)
        *sentence = new char[120];

    char line[120];
    int index = 0;
    while(!file.eof())
    {
        file.getline(line, 120);  
        sentence[index++] = line; //Erase precedent line
    }

    for (int i = 0; i < index; i++)
        cout << sentence[i] << endl;

    
    return 0; 
}
rcoding
  • 9
  • 1
  • Why should it be 2d? – Ted Lyngmo Jan 27 '21 at 20:14
  • Why do you say it's a duplicate, this is not the same question – rcoding Jan 27 '21 at 20:17
  • 1
    @rcoding I'll reopen, but you should fix [that problem](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons) first in any case. Also you should rather use `std::string` as type for line, and `std::vector` for `sentence`. This `sentence[index++] = line;` leaks memory like a sieve. – πάντα ῥεῖ Jan 27 '21 at 20:19
  • I know this is a problem, but because I have to use char and not std::string, I think there isn't a different way. Like I say I have to use regular array and char* – rcoding Jan 27 '21 at 20:22
  • "_I have to use char and not std::string_" - Wait, what?! Why wasn't that information in the question? Is there something else you aren't allowed to use? – Ted Lyngmo Jan 27 '21 at 20:37
  • This doesn't address the question, but `std::cin` and `std::cout` are synchronized. That means that when you write a prompt to `std::cout` and then try to read input, `std::cin`, will get flushed. There's no need for that `std::endl` in the prompt for the file path. – Pete Becker Jan 27 '21 at 21:31

2 Answers2

0

I am not sure whether there is a more efficient way to solve this.

void readFile(char *fileName){
        char c;
        std::ifstream myFile(fileName,std::ios::ate);
        std::streampos size = myFile.tellg();
        for(int i=1;i<=size;i++){
            myFile.seekg(-i,std::ios::end);
            myFile.get(c);
            printf("%c\n",c);
        }
    }
Tivi
  • 456
  • 4
  • 22
  • When open the file, I use ios::ate to set the file position to the end of the file and use seekg method to read back. – Tivi Jan 27 '21 at 20:23
  • If i understand your code, this will reverse every char. I want to reverse all line not every char – rcoding Jan 27 '21 at 20:24
0

This is not doing what you think:

   sentence[index++] = line; //Erase precedent line

This assigns the address of line into sentence[index]. Which is not what you want because at the end of the loop all values in sentence point at line (thus leaking all the dynamically allocated memory).

To make this work you need to copy the string into the destination.

  std::copy(line, strlen(line), sentence[index++]);

However: This is probably not the best solution. You should be using C++ objects rather than low level C-Strings. The C++ objects would have solved this for you without any need for manual copying or dynamic allocation.

A quick hint is that new/delete or probably a bad idea for beginers. If your code contains them you are doing something wrong (or writting C and happen to use the C++ compiler to compile the code).

int main()
{
    /* 
       Replace this with std::vector<std::string>
    char** sentence = new char* [100];
    for (int i = 0; i < 100; i++)
        *sentence = new char[120];
    */
    // Great thing about vectors is that they will resize.
    std::vector<std::string>  sentence;
   
    std::string line;
    // Use the read operation as the condition of the loop
    // If you fail to read then you should not add it to sentence.
    // Note `line` will dynamically re-size for any size of line.
    while(std::getline(file, line))
    {
        sentence.push_back(line);
    }

    // You can finish it.
    // Iterate over the `sentence` backwards and print them out.
}
Martin York
  • 257,169
  • 86
  • 333
  • 562