LinuxQuestions.org
View the Most Wanted LQ Wiki articles.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices



Reply
 
Search this Thread
Old 03-19-2014, 06:23 PM   #1
casualfred
Member
 
Registered: Aug 2012
Location: USA
Distribution: Slackware 14.1
Posts: 73

Rep: Reputation: 15
C++ reads in ASCII 255 at the end of files?


I am basically just trying to read in a file and output it to the terminal in C++, but I have noticed a strange character at the end of the output every time. I am using Slackware 14.1, gcc v4.8.2, and this occurs on files with both unix and dos line endings.
Code:
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>

using namespace std;

int main()
{
   ifstream thefile;
   char fileName[50], ch;

   cout << endl << "Enter filename: ";
   cin.getline(fileName, 49);
   thefile.open(fileName);
   if (thefile.fail())
   {
      cout << "file not opened" << endl;
      return 0;
   }

   cout << endl;

   while (! thefile.eof())
   {
      ch = thefile.get();
      cout << ch;
      if (ch == -1) // ASCII 255 or it wraps around to -1
         cout << endl << "EOF";
   }

   return 0;
}
And it outputs:
Code:
Enter filename: expr.d1

45 + 60
45 - 60
(23 + 45)
12
(12)
((12))
((12 + 12 + 12))

EOF
where my file "expr.d1" is:
Code:
45 + 60
45 - 60
(23 + 45)
12
(12)
((12))
((12 + 12 + 12))
So, I'm trying to figure out why it is outputting "", ASCII 255 at the end of the file. I have done some research, but I feel like I just don't know what's going on.

Thanks in advance for your help!
 
Old 03-19-2014, 07:15 PM   #2
gengisdave
Member
 
Registered: Dec 2013
Location: Turin, Italy
Distribution: slackware
Posts: 288

Rep: Reputation: 59
ascii 255 is the non breaking space, the html &nbsp;, does your file have an empty ending line or some other character before eof (first tought is about a copy-paste from a web page)?

Last edited by gengisdave; 03-19-2014 at 07:16 PM. Reason: typo
 
Old 03-19-2014, 07:27 PM   #3
michaelk
Moderator
 
Registered: Aug 2002
Posts: 12,172

Rep: Reputation: 784Reputation: 784Reputation: 784Reputation: 784Reputation: 784Reputation: 784Reputation: 784
Code:
  while (! thefile.eof())
   {
      ch = thefile.get();
      cout << ch;
      if (ch == -1) // ASCII 255 or it wraps around to -1
         cout << endl << "EOF";
   }
Lets look at the loop. If the file pointer is at the last character in the file the while is still true, get() will read the next character which is EOF so cout<<ch will print the character representation which is that strange thing you see. (ch==-1) evaluates true so EOF is printed.
 
1 members found this post helpful.
Old 03-19-2014, 07:29 PM   #4
rknichols
Senior Member
 
Registered: Aug 2009
Distribution: CentOS
Posts: 1,623

Rep: Reputation: 676Reputation: 676Reputation: 676Reputation: 676Reputation: 676Reputation: 676
EOF does not get set when you read the last character in the file. It is the next read that sets EOF, but you are printing the returned value (-1) from that unsuccessful read.

Why does EOF work that way? Because it is entirely possible for the file to grow between the time you read the last character and your next read.

Oops, echo in here.

Last edited by rknichols; 03-19-2014 at 07:31 PM.
 
1 members found this post helpful.
Old 03-19-2014, 07:55 PM   #5
casualfred
Member
 
Registered: Aug 2012
Location: USA
Distribution: Slackware 14.1
Posts: 73

Original Poster
Rep: Reputation: 15
Thanks for the replies! So would a do-while loop work better in my case do you think?

Edit: I went ahead and tried it, but it didn't seem to help. I don't recall ever having this problem before when trying to read in files... I'm not sure what I am doing wrong.

Last edited by casualfred; 03-19-2014 at 08:01 PM. Reason: I tried out what I asked.
 
Old 03-19-2014, 11:35 PM   #6
rknichols
Senior Member
 
Registered: Aug 2009
Distribution: CentOS
Posts: 1,623

Rep: Reputation: 676Reputation: 676Reputation: 676Reputation: 676Reputation: 676Reputation: 676
Anything that prints ch as a character prior to testing for EOF is going to exhibit that problem. Of the myriad ways to code that loop, here is one:
Code:
while (! thefile.eof())
   {
      ch = thefile.get();
      if (ch == -1) // ASCII 255 or it wraps around to -1
         cout << endl << "EOF";
      else
         cout << ch; 
   }
And no, I'm not claiming that is the best way to code that.
 
Old 03-20-2014, 12:25 AM   #7
casualfred
Member
 
Registered: Aug 2012
Location: USA
Distribution: Slackware 14.1
Posts: 73

Original Poster
Rep: Reputation: 15
Alright, thanks rknichols. So, I could just filter the output like that. I think this is an answer to my question, so I'll mark it as solved.

But, let me be sure I understand what is happening here. There is an EOF flag C++ associates with an opened file. C++ sets that flag when it attempts a read, but finds there is nothing else to read. The failed read will always return this strange character.

Thanks for the great information and for taking the time to explain this stuff!
 
Old 03-20-2014, 05:02 AM   #8
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 1,948

Rep: Reputation: 524Reputation: 524Reputation: 524Reputation: 524Reputation: 524Reputation: 524
(It's quite common mistake, almost everyone has it once... getchar/getc/fgetc/... return unsigned char or -1, so the value should be stored in 'int' not 'char')
 
1 members found this post helpful.
Old 03-20-2014, 04:22 PM   #9
sundialsvcs
Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 5,455

Rep: Reputation: 1172Reputation: 1172Reputation: 1172Reputation: 1172Reputation: 1172Reputation: 1172Reputation: 1172Reputation: 1172Reputation: 1172
Do it this way:

Code:
while not ( eof ) {
  get()
  if not ( eof ) {
    ... do something ...
  end-if
end-while
Or this way:

Code:
get()
while not ( eof ) {
  ... do something ...
  get()
end-while
Usually, eof indications are produced by attempts to "get" something. They don't look-ahead to see if eof is about to be reached. (The only language that I recall which attempted to do otherwise was Standard Pascal, and it was ugly.)

Your code is basically producing garbage at the last because it has just read past the end of the file. Although the eof indicator will have been tripped thereby, you're not checking for that after the get which ran-dry.
 
Old 03-20-2014, 07:23 PM   #10
casualfred
Member
 
Registered: Aug 2012
Location: USA
Distribution: Slackware 14.1
Posts: 73

Original Poster
Rep: Reputation: 15
Thanks sundialsvcs - yeah that's pretty much what I came up with in the end:
Code:
char ch;
ch = thefile.get();
while (! thefile.eof())
{
   cout << ch;
   ch = thefile.get;
}
But I've found a situation where your first example would work better also.

I think I understand what's going on now - thanks again everyone for the helpful guidance!
 
Old 03-21-2014, 12:43 AM   #11
sundialsvcs
Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 5,455

Rep: Reputation: 1172Reputation: 1172Reputation: 1172Reputation: 1172Reputation: 1172Reputation: 1172Reputation: 1172Reputation: 1172Reputation: 1172
Heh... I like the second one better, myself, and normally do it that way.
 
Old 03-21-2014, 11:12 AM   #12
rknichols
Senior Member
 
Registered: Aug 2009
Distribution: CentOS
Posts: 1,623

Rep: Reputation: 676Reputation: 676Reputation: 676Reputation: 676Reputation: 676Reputation: 676
My own preference is for
Code:
while (get(), ! eof) {
    ... do something ...
}
 
Old 03-22-2014, 12:09 PM   #13
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,523

Rep: Reputation: 332Reputation: 332Reputation: 332Reputation: 332
You can always evaluate the file stream object after you have performed a call to get(). C++ ios stream objects (including fstream) implement an operator bool() method that returns the state of the stream.

Something like:
Code:
char ch;

while ((ch = file.get()) && file)
{
    std::cout << ch;
}
std::cout << "EOF" << std::endl;
You could also consider reading one line at a time from the data file.
Code:
char line[80];
while (file.getline(line, sizeof(line)) && file)
{
    std::cout << line << std::endl;
}
std::cout << "EOF" << std::endl
Edit... another option:
Code:
std::string line;
while (std::getline(file, line) && file)
{
    std::cout << line << std::endl;
}
std::cout << "EOF" << std::endl;

Last edited by dwhitney67; 03-22-2014 at 12:12 PM.
 
1 members found this post helpful.
Old 03-25-2014, 07:38 PM   #14
casualfred
Member
 
Registered: Aug 2012
Location: USA
Distribution: Slackware 14.1
Posts: 73

Original Poster
Rep: Reputation: 15
Interesting. Thanks dwhitney67!
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
What is this -> SRC=0.0.0.0 DST=255.255.255.255 LEN=328 TOS=0x00 PREC=0x00 TTL=128 ID carves Linux - Networking 5 08-17-2008 10:26 PM
Are Broadcasts to 255.255.255.255 Routed MQMan Linux - Networking 6 11-23-2005 03:16 PM
Logs full of hits to 255.255.255.255; how to stop logging? mac_phil Mandriva 2 02-23-2004 11:25 AM
UDP broadcast 255.255.255.255 java8964 Linux - Networking 0 10-29-2003 03:05 PM
configuring RH 7 for a subnet mask of 255.255.255.224 CDPL Linux - Networking 2 04-20-2002 10:06 AM


All times are GMT -5. The time now is 07:40 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration