Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > end-of-line character problem while reading stream characters and wrinting into array

Reply
Thread Tools

end-of-line character problem while reading stream characters and wrinting into array

 
 
dbuser
Guest
Posts: n/a
 
      10-09-2005
Hi,
I need help on a problem, as described below. I am reading a file
"input.txt"which has data like this:
abc def gh izk lmnopq rst uvwxyz

I am using fstream object to read the file and writing into a dynamic
array. My problem is that the array shows extra z and probably because
of this further processing gives run time error in borland compiler.
Can you please tell me, if the problem is related to handling end-of
line , how do i do it.
here is the piece of code I am using:
char ch;
char * input;
input = new char[size]; // size is determined at runtime
memset(input, 0, sizeof(input));
ifstream infile("input.txt", ios::in);
if(!infile) cerr << "Error opening file" << endl;
while(!infile.eof()){
infile.get(ch);
input[i] = ch;
i++;
}
cout << input << endl;
infile.close();


as you can see, the output shows extra 'z'
abc def gh izk lmnopq rst uvwxyzz

Thanks for any help!
regards!
dbuser

 
Reply With Quote
 
 
 
 
John Harrison
Guest
Posts: n/a
 
      10-09-2005
dbuser wrote:
> Hi,
> I need help on a problem, as described below. I am reading a file
> "input.txt"which has data like this:
> abc def gh izk lmnopq rst uvwxyz
>
> I am using fstream object to read the file and writing into a dynamic
> array. My problem is that the array shows extra z and probably because
> of this further processing gives run time error in borland compiler.
> Can you please tell me, if the problem is related to handling end-of
> line , how do i do it.
> here is the piece of code I am using:
> char ch;
> char * input;
> input = new char[size]; // size is determined at runtime
> memset(input, 0, sizeof(input));
> ifstream infile("input.txt", ios::in);
> if(!infile) cerr << "Error opening file" << endl;
> while(!infile.eof()){
> infile.get(ch);
> input[i] = ch;
> i++;
> }
> cout << input << endl;
> infile.close();
>
>
> as you can see, the output shows extra 'z'
> abc def gh izk lmnopq rst uvwxyzz
>
> Thanks for any help!
> regards!
> dbuser
>


The problem is that your end of file handling is wrong.

infile.eof() is true is the *last* operation failed because of end of
file, it is not true because the *next* opeation will fail because of
end of file. So you are going round you loop one to many times.

It is simply unbelievable how many newbies manage to get this wrong. I
don't know where they are getting their information from. Did you read
this in a book, or did you just think it must be right?

Here is how you should write your loop

while(infile.get(ch)){
input[i] = ch;
i++;
}

Now the extra z will disappear.

john
 
Reply With Quote
 
 
 
 
Jacques Labuschagne
Guest
Posts: n/a
 
      10-09-2005
dbuser wrote:

> Hi,
> I need help on a problem, as described below. I am reading a file
> "input.txt"which has data like this:
> abc def gh izk lmnopq rst uvwxyz
>
> I am using fstream object to read the file and writing into a dynamic
> array. My problem is that the array shows extra z and probably because
> of this further processing gives run time error in borland compiler.
> Can you please tell me, if the problem is related to handling end-of
> line , how do i do it.
> here is the piece of code I am using:
> char ch;
> char * input;
> input = new char[size]; // size is determined at runtime
> memset(input, 0, sizeof(input));
> ifstream infile("input.txt", ios::in);
> if(!infile) cerr << "Error opening file" << endl;
> while(!infile.eof()){


This is your problem. The test for eof() is only meaningful after you
try to get() something. This loop should be written as

while (infile.get(ch)){
input[i] = ch;
++i;
}

You may want to consider reading the file in bigger chunks. Reading it
one character at a time is slooow.

Jacques.
 
Reply With Quote
 
Thomas J. Gritzan
Guest
Posts: n/a
 
      10-09-2005
dbuser schrieb:
> char ch;
> char * input;
> input = new char[size]; // size is determined at runtime
> memset(input, 0, sizeof(input));

^^^^^^^^^^^^^

This is a bad idea. The size of the character array input is pointing to
is "size" and not sizeof(input). sizeof(input) is equal to sizeof(char*).

> ifstream infile("input.txt", ios::in);
> if(!infile) cerr << "Error opening file" << endl;
> while(!infile.eof()){
> infile.get(ch);
> input[i] = ch;
> i++;
> }


I would do it here instead:

input[i] = '\0';

> cout << input << endl;
> infile.close();




Thomas
 
Reply With Quote
 
dbuser
Guest
Posts: n/a
 
      10-09-2005
Hi John,
Thanks for such a quick response. the extra z disappeared , but it
added a junk in the array , I am printing (see the last character.
abc def gh izk lmnopq rst uvwxyz☻

somehow, the file pointer is reading endof line and fills garbage. what
am I missing here?
since I am using this array data to manipulate later, this causes run
time error.
Thanks again ,
dbuser

 
Reply With Quote
 
Jacques Labuschagne
Guest
Posts: n/a
 
      10-09-2005
dbuser wrote:

> Hi John,
> Thanks for such a quick response. the extra z disappeared , but it
> added a junk in the array , I am printing (see the last character.
> abc def gh izk lmnopq rst uvwxyz☻
>
> somehow, the file pointer is reading endof line and fills garbage. what
> am I missing here?
> since I am using this array data to manipulate later, this causes run
> time error.
> Thanks again ,
> dbuser
>


Thomas has answered this. You aren't NUL-terminating your string properly.

Jacques.
 
Reply With Quote
 
dbuser
Guest
Posts: n/a
 
      10-09-2005
Hi Thomas,
Thanks ! Null terminating the string resolved this garbage problem.I
have couple of more questions:
1) I need to find the no. of characters in the input file so that I can
determine the size of the dynamic array. right now, I am using C method
_lseek to find beginning and end value and calculating the size.
Can I do this using C++ methods seekg(ios::beg) and seekg(ios::end)
this does not return a long value , whats the efficient way of finding
size in C++?

2) I am calling a scramble function which fills another dynamic array
with scrambled values, at the end, I need to move user input key into
that array. like moving a null terminating string, I am trying to move
the key value but it is not working.. is this doable.
The other bad idea I have is to write entire array into a file and then
move that key value at end of file , but I am getting run time error
when i try to open the filestream object .
Please help !
Thnaks !

 
Reply With Quote
 
dbuser
Guest
Posts: n/a
 
      10-10-2005
Hi Thomas,
Great, the input[i] = '\0' removed the last unwanted character in the
dynamic array. your suggestion greatly appreciated.
can I ask you another question here... after filling this array, I am
calling a swap function and a scramble function to manupulate the
string... I may not be efficient because I am making another dynamic
array and filling scrambled data.
After I am done, I need to insert a user entered key ( a single digit
number) at the end of the array.
c[j] = x; // x is integer
does not work.
I tried to open a file and write this array data into file so that I
can write end character but then ofstream object creation statement
--- ofstream outfile("name.txt", ios::ate);
gives me run time error. here is the code :
void scramble( char *w, int key)
{
int x = key;
int len = strlen(w);
len = (len + len/x);
char s[] = "@#$";
int n = strlen(s);
int i,j,k,m=0;
static char * c;
c = new char[len];
memset(c, 0, sizeof(c));

if (c == NULL) exit(1);
for (i=0,j=0,k=0; i<len; i++){
if(k<x) {
c[j++] = w[i];k++;
}
else {
if(m<n)
c[j++] = s[m++];
else {
c[j++] = s[0]; m = 1;}
c[j++]=w[i]; k=1; }
}
c[j] = x;
cout << "c is " << c << endl;
//write scramble into a file
cout << "I am starting writefile" << endl;
ofstream outfile("name.txt", ios::ate);
cout << "I m after opening writefile" << endl;
if (!outfile) {
cerr << "file could not be opened " << endl;
exit(1);
} else cout << "file created successfully" << endl;
for (int i=0; i< strlen(c); i++) {
outfile<<c[i];
}

outfile.close();


Thanks a lot for help !
dbuser

 
Reply With Quote
 
Thomas J. Gritzan
Guest
Posts: n/a
 
      10-10-2005
dbuser schrieb:
> Hi Thomas,


Hi again,

> After I am done, I need to insert a user entered key ( a single digit
> number) at the end of the array.
> c[j] = x; // x is integer
> does not work.


Of course not. Characters are represented as ASCII code in memory (or
similar on other platforms).
If you want the characters '0', '1', ... write this:

c[j] = '0'+x; // assumes that 0 <= x <= 9

> I tried to open a file and write this array data into file so that I
> can write end character but then ofstream object creation statement
> --- ofstream outfile("name.txt", ios::ate);
> gives me run time error.


Try ios::ate|ios:ut as second parameter. ios::ate does not imply ios:ut.

> here is the code :
> void scramble( char *w, int key)
> {
> int x = key;
> int len = strlen(w);
> len = (len + len/x);
> char s[] = "@#$";
> int n = strlen(s);
> int i,j,k,m=0;
> static char * c;


Why static?

Here are the errors:

> c = new char[len];
> memset(c, 0, sizeof(c));
>
> if (c == NULL) exit(1);


First, don't check c for NULL after using it. That really makes no
sense. Then, you don't have to check c for being null-pointer, since
operator new does not return NULL, it throws an exception instead.

You also need to reserve space for the null-terminator:

c = new char[len+1];

Then again, as I said in the other posting, the array c points to does
not have size sizeof(c). It's size is len.
Write this:

memset(c, 0, len); or better omit it, you don't need it.

Instead, terminate the string with '\0' when done, just as in the other
function.

> for (i=0,j=0,k=0; i<len; i++){
> if(k<x) {
> c[j++] = w[i];k++;
> }
> else {
> if(m<n)
> c[j++] = s[m++];
> else {
> c[j++] = s[0]; m = 1;}
> c[j++]=w[i]; k=1; }
> }


What are you doing here anyway? What do you scramble the string for?

> c[j] = x;


See above.

> cout << "c is " << c << endl;
> //write scramble into a file
> cout << "I am starting writefile" << endl;
> ofstream outfile("name.txt", ios::ate);
> cout << "I m after opening writefile" << endl;
> if (!outfile) {
> cerr << "file could not be opened " << endl;
> exit(1);


Don't forget to free the memory c is pointing to bevor exiting.

> } else cout << "file created successfully" << endl;
> for (int i=0; i< strlen(c); i++) {
> outfile<<c[i];
> }


Why do you write the characters one at a time?

>
> outfile.close();


Again, don't forget to delete c!

Thomas
 
Reply With Quote
 
 
 
Reply

Thread Tools

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 On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
what is the different between byte stream and character stream? dolphin Java 6 03-18-2007 01:58 PM
Insert characters into a text stream. anachronic_individual C Programming 9 09-10-2006 08:57 PM
wrinting an optimised code junky_fellow@yahoo.co.in C Programming 11 05-19-2005 03:00 PM
question: reading character for character from stdin KwikRick Python 1 08-22-2003 05:56 PM
Re: Reading the first three characters from an input stream Andrew Thompson Java 1 08-13-2003 12:36 PM



Advertisments