Read first 1000 characters of file into a buffer, turn newlines into \0 and store the strings address location to a char*[]

StackOverflow https://stackoverflow.com/questions/23588431

  •  19-07-2023
  •  | 
  •  

Frage

Here is the exact question:

Write a program that reads lines of text and appends them to a char buffer[1000]. Stop after reading 1,000 characters. As you read in the text, replace all newlines characters with null terminators. Establish an array char* lines[100] so that the pointers in that array point to the beginnings of the lines in the text.

Only consider 100 input lines if the input has more lines. Then display the lines in reverse order. Start with the last input line.

Contents of Data.txt:

http://pastebin.com/uKv4nC5s

My Code:

// see updated code

My Problem

The above works perfectly when used with the Data.txt file specified above; however, it FAILS miserably when the file contains > 100 lines of text.

When it reads back the contents in reverse the first line printed is EVERYTHING after the 100th line.

Consider we had the following last four lines

99   ASDF  
100  FFFF  
101  3910  
102  FKDS 

The above would print

FFFF // GOOD 
3910 // NOT GOOD
FKDS // NOT GOOD PART DEUX
ASDF // GOOD

I believe the desired output to be that it ignore everything after the 100th newline and or 1000th character, whichever comes first.

Any pointers or guidance in the right direction would be greatly appreciated. This is homework so no explicit answers if possible.

Updated Code:

void read_and_print()
{
    std::ifstream input("D:\\data.txt");

    if (!input.is_open() || !input.good())
        return;

    char buffer[10001];
    int b = 0;

    char* lines[100];
    int l = 0;
    char** e;
    bool set_start = false;

    lines[l] = buffer + b; // the first line
    e = lines + (l++);

    char t;
    while (input.get(t) && b < 1000)
    {
        if (set_start)
        {
            if (l < 100) {
                lines[l] = buffer + b;
                e = lines + l;
            }
            l++;
            set_start = false;
        }

        if (t == '\n') {
            t = '\0';
            set_start = !set_start;
        }

        buffer[b] = t;
        b++;
    }

    input.close();

    if (b == 1000)
        buffer[1000] = '\0'; // close out the string
    else if (b < 1000)
        buffer[b] = '\0'; // close out the string

    while (lines <= e)
    {
        std::cout << *e << std::endl;
        e--;
    }
}
War es hilfreich?

Lösung

Your loop doesn't stop when you've read in 100 lines; rather, it continues to read but stop replacing \n with \0. The result is that your last "line" contains everything from the 100th line onwards in your input until you hit the 1000 character mark.

You should terminate the loop when you hit the \n for the 100th line.

Side notes:

  • (t = input.get()) != EOF isn't correct when t is a char (EOF is an int value guaranteed to be unequal to any char converted to int; it's not guaranteed to be unequal to a valid character when converted to a char). A simple input.get(t) would do it (it takes its argument by reference and returns a reference to the stream, whose operator bool will return false if an error occurred).

  • If you've read in 1000 characters, and the last character is not \n, the last string never gets closed with \0. You should probably add an extra character to the buffer so that you can close that string up with \0.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top