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

Discussion in 'C++' started by dbuser, Oct 9, 2005.

  1. dbuser

    dbuser Guest

    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 = 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
     
    dbuser, Oct 9, 2005
    #1
    1. Advertising

  2. Re: end-of-line character problem while reading stream charactersand wrinting into array

    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 = 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 = ch;
    i++;
    }

    Now the extra z will disappear.

    john
     
    John Harrison, Oct 9, 2005
    #2
    1. Advertising

  3. Re: end-of-line character problem while reading stream charactersand wrinting into array

    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 = ch;
    ++i;
    }

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

    Jacques.
     
    Jacques Labuschagne, Oct 9, 2005
    #3
  4. Re: end-of-line character problem while reading stream charactersand wrinting into array

    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 = ch;
    > i++;
    > }


    I would do it here instead:

    input = '\0';

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




    Thomas
     
    Thomas J. Gritzan, Oct 9, 2005
    #4
  5. dbuser

    dbuser Guest

    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
     
    dbuser, Oct 9, 2005
    #5
  6. Re: end-of-line character problem while reading stream charactersand wrinting into array

    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.
     
    Jacques Labuschagne, Oct 10, 2005
    #6
  7. dbuser

    dbuser Guest

    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 !
     
    dbuser, Oct 10, 2005
    #7
  8. dbuser

    dbuser Guest

    Hi Thomas,
    Great, the input = '\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;k++;
    }
    else {
    if(m<n)
    c[j++] = s[m++];
    else {
    c[j++] = s[0]; m = 1;}
    c[j++]=w; 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;
    }

    outfile.close();


    Thanks a lot for help !
    dbuser
     
    dbuser, Oct 10, 2005
    #8
  9. Re: end-of-line character problem while reading stream charactersand wrinting into array

    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::eek:ut as second parameter. ios::ate does not imply ios::eek: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;k++;
    > }
    > else {
    > if(m<n)
    > c[j++] = s[m++];
    > else {
    > c[j++] = s[0]; m = 1;}
    > c[j++]=w; 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;
    > }


    Why do you write the characters one at a time?

    >
    > outfile.close();


    Again, don't forget to delete c!

    Thomas
     
    Thomas J. Gritzan, Oct 10, 2005
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. wrinting an optimised code

    , May 17, 2005, in forum: C Programming
    Replies:
    11
    Views:
    572
    Kevin D. Quitt
    May 19, 2005
  2. Andreas Leitgeb
    Replies:
    0
    Views:
    465
    Andreas Leitgeb
    May 15, 2009
  3. Mark Space
    Replies:
    0
    Views:
    495
    Mark Space
    May 15, 2009
  4. Lew
    Replies:
    0
    Views:
    959
  5. Nikolai Weibull
    Replies:
    7
    Views:
    130
    Daniel Brockman
    Aug 31, 2005
Loading...

Share This Page