Output of text file in console application showing junk at end of file

Hi all;

It has been a long time since I have written anything in C++. I am trying to get my app to print the last ten lines of a specified file. I'm still in the starting stages of this, and am having trouble with the very end of the file. I'm reading a text file that is 11 lines long with a forced return at the end of each line. As you can see from below code, I'm reading the file into a buffer that is the same size as the file in characters, I'm using strtok on the buffer to break the file into tokens. The tokens are broken up correctly, except on the output, there are a lot of strange symbols at the end of the last line. See code attached.

I've tried forcing my buffer to be shorter to see if for some reason it was larger than the file, but this only truncated the text in the file and left the junk at the end intact. This happens whether there is a forced return at the end of the last line of the file or not (it just puts the junk on a new line if there is a return).

Any help would be appreciated! As you can guess, this is an assignment, and the assignment was meant to be done in the UNIX environment, but I have no UNIX environment. Please don't rewrite the code; just some pointers on what would be junking up the end of the file would be helpful.

Thanks in advance.

EDIT** to be more specific, the junk is: ²²²²ŒŒ
#pragma warning (push) // store the warning level
#pragma warning (disable:4786) // identifier was truncated to '255' characters in the debug information
 
 
#include <vector>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <iostream.h>
#include <fstream.h>
 
 
int main (int argc, char *argv []) {
	unsigned long fsize;
	size_t res;
	std::vector <char *> LineVector;
 
int length;
char * buffer;
ifstream is;
is.open ("hw2_10.txt", ios::binary);
is.seekg(0, ios::end);
length = is.tellg();
is.seekg(0, ios::beg);
buffer = new char [length];
is.read(buffer, length);
is.close();
 
char * point;
point = strtok (buffer,"\n\0");
while (point != NULL)
{
	printf("%s\n",point);
	point = strtok (NULL, "\n\0");
}
 
	free(buffer);
  return 0;
}

Open in new window

briandeanAsked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
jkrConnect With a Mentor Commented:
The problem is that you are not leaving room for a NULL terminator in your buffer

Make that a text file. Furthermore, *don*t use 'iostream.h', it is not part of the C++ standard, the same applies to 'fstream.h'.

Th ewhole thing should be

#pragma warning (push) // store the warning level
#pragma warning (disable:4786) // identifier was truncated to '255' characters in the debug information
 
 
#include <vector>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
 
using namespace std;
 
 
int main (int argc, char *argv []) {
        unsigned long fsize;
        size_t res;
        std::vector <char *> LineVector;
 
int length;
char * buffer;
ifstream is;
is.open ("hw2_10.txt",ios_base::binary);
is.seekg(0, ios_base::end);
length = is.tellg();
is.seekg(0, ios_base::beg);
buffer = new char [length + 1]; // <--------
memset(buffer,0,length + 1);
is.read(buffer, length);
is.close();
 
char * point;
point = strtok (buffer,"\n\0");
while (point != NULL)
{
        printf("%s\n",point);
        point = strtok (NULL, "\n\0");
}
 
        free(buffer);
  return 0;
}

Open in new window

0
 
Infinity08Commented:
Why not just use getline ?

        http://www.cplusplus.com/reference/string/getline.html

(see the example code at the bottom of the page)
0
 
Kent OlsenData Warehouse Architect / DBACommented:
Hi briandean,

The \0 character in the string being passed to strtok is meaningless.  In fact, if it's not the LAST character, it will affect the search as everything past it will be ignored.

The "garbage" is due to running off the end of the buffer.  Make the buffer one byte longer than the string and set the last character to zero.  That should just about fix this.  Pretty good code.




Good Luck,
Kent
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
jkrCommented:
One other thing,

free(buffer);

is not right, that should be

delete [] buffer;

since you used 'new' to create it:
#pragma warning (push) // store the warning level
#pragma warning (disable:4786) // identifier was truncated to '255' characters in the debug information
 
 
#include <vector>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
 
using namespace std;
 
 
int main (int argc, char *argv []) {
        unsigned long fsize;
        size_t res;
        std::vector <char *> LineVector;
 
int length;
char * buffer;
ifstream is;
is.open ("hw2_10.txt",ios_base::binary);
is.seekg(0, ios_base::end);
length = is.tellg();
is.seekg(0, ios_base::beg);
buffer = new char [length + 1]; // <--------
memset(buffer,0,length + 1);
is.read(buffer, length);
is.close();
 
char * point;
point = strtok (buffer,"\n\0");
while (point != NULL)
{
        printf("%s\n",point);
        point = strtok (NULL, "\n\0");
}
 
        delete [] buffer;
  return 0;
}

Open in new window

0
 
briandeanAuthor Commented:
Thank you! Solution worked and you helped me to understand why.
0
 
Infinity08Commented:
Do consider using getline though ... The code you wrote to read the whole file and then split it up using strtok, is gonna be a lot nicer with getline, as it does all that for you. Plus you can use it with the STL string.
0
All Courses

From novice to tech pro — start learning today.