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?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jkrCommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
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
The Ultimate Tool Kit for Technolgy Solution Provi

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy for valuable how-to assets including sample agreements, checklists, flowcharts, and more!

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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.