getline and EOF question

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Amadeus W. M.

    getline and EOF question

    I'm trying to read a whole file as a single string, using the getline()
    function, as in the example below. I can't tell what I'm doing wrong.
    Tried g++ 3.2, 3.4 and 4.0. Thanks!


    #include <iostream>
    #include <fstream>
    #include <cstdlib>
    #include <string>

    using namespace std;

    int main(int argc, char * argv[])
    {
    const int MAX_SIZE=100000 ;
    string s;
    char chars[MAX_SIZE];

    fstream IN("junk", ios::in);

    // These 2 are ok.
    IN.getline(char s, MAX_SIZE, EOF); // works, so EOF ok
    getline(IN, s, 'x'); // works with string, no EOF

    // g++ doesn't like this one.
    getline(IN, s, EOF); // what's wrong??

    return 0;
    }

  • Steven T. Hatton

    #2
    Re: getline and EOF question

    Amadeus W. M. wrote:
    [color=blue]
    > I'm trying to read a whole file as a single string, using the getline()
    > function, as in the example below. I can't tell what I'm doing wrong.
    > Tried g++ 3.2, 3.4 and 4.0. Thanks!
    >
    >
    > #include <iostream>
    > #include <fstream>
    > #include <cstdlib>
    > #include <string>
    >
    > using namespace std;
    >
    > int main(int argc, char * argv[])
    > {
    > const int MAX_SIZE=100000 ;
    > string s;
    > char chars[MAX_SIZE];
    >
    > fstream IN("junk", ios::in);
    >
    > // These 2 are ok.
    > IN.getline(char s, MAX_SIZE, EOF); // works, so EOF ok
    > getline(IN, s, 'x'); // works with string, no EOF
    >
    > // g++ doesn't like this one.
    > getline(IN, s, EOF); // what's wrong??
    >
    > return 0;
    > }[/color]

    Unfortunately, there is a std::getline() declared as follows:

    template<class charT, class traits, class Allocator>
    basic_istream<c harT,traits>& getline(basic_i stream<charT,tr aits>& is,
    basic_string<ch arT,traits,Allo cator>& str, charT delim);

    It wants a charT which is not of the same type as EOF. Try calling the
    getline on IN. I have not tried that myself, so I don't know if it will
    help.
    --
    If our hypothesis is about anything and not about some one or more
    particular things, then our deductions constitute mathematics. Thus
    mathematics may be defined as the subject in which we never know what we
    are talking about, nor whether what we are saying is true.-Bertrand Russell

    Comment

    • Amadeus W. M.

      #3
      Re: getline and EOF question

      On Fri, 01 Jul 2005 05:33:08 -0400, Steven T. Hatton wrote:
      [color=blue]
      > Amadeus W. M. wrote:
      >[color=green]
      >> I'm trying to read a whole file as a single string, using the getline()
      >> function, as in the example below. I can't tell what I'm doing wrong.
      >> Tried g++ 3.2, 3.4 and 4.0. Thanks!
      >>
      >>
      >> #include <iostream>
      >> #include <fstream>
      >> #include <cstdlib>
      >> #include <string>
      >>
      >> using namespace std;
      >>
      >> int main(int argc, char * argv[])
      >> {
      >> const int MAX_SIZE=100000 ;
      >> string s;
      >> char chars[MAX_SIZE];
      >>
      >> fstream IN("junk", ios::in);
      >>
      >> // These 2 are ok.
      >> IN.getline(char s, MAX_SIZE, EOF); // works, so EOF ok
      >> getline(IN, s, 'x'); // works with string, no EOF
      >>
      >> // g++ doesn't like this one.
      >> getline(IN, s, EOF); // what's wrong??
      >>
      >> return 0;
      >> }[/color]
      >
      > Unfortunately, there is a std::getline() declared as follows:
      >
      > template<class charT, class traits, class Allocator>
      > basic_istream<c harT,traits>& getline(basic_i stream<charT,tr aits>& is,
      > basic_string<ch arT,traits,Allo cator>& str, charT delim);
      >
      > It wants a charT which is not of the same type as EOF. Try calling the
      > getline on IN. I have not tried that myself, so I don't know if it will
      > help.[/color]

      I did, in the very program I posted, and it worked. I was curious why the
      one on string wouldn't work.

      There is also a getline() in bits/basic_string.h

      template<typena me _CharT, typename _Traits, typename _Alloc>
      basic_istream<_ CharT,_Traits>&
      getline(basic_i stream<_CharT, _Traits>& __is,
      basic_string<_C harT, _Traits, _Alloc>& __str, _CharT __delim);

      So in this version, the type of the delimiter must be the same _CharT
      as in basic_istream and basic_string. The same is true for the istream
      version of getline. So I don't understand why one works and the other
      doesn't. What's the type of EOF? Whatever the type, it should both work,
      or both not work.


      Comment

      • Kyle Kolander

        #4
        Re: getline and EOF question


        "Amadeus W. M." <amadeus84@cabl espeed.com> wrote in message
        news:pan.2005.0 7.01.06.14.50.9 09272@cablespee d.com...[color=blue]
        > I'm trying to read a whole file as a single string, using the getline()
        > function, as in the example below. I can't tell what I'm doing wrong.
        > Tried g++ 3.2, 3.4 and 4.0. Thanks!
        >
        >
        > #include <iostream>
        > #include <fstream>
        > #include <cstdlib>
        > #include <string>
        >
        > using namespace std;
        >
        > int main(int argc, char * argv[])
        > {
        > const int MAX_SIZE=100000 ;
        > string s;
        > char chars[MAX_SIZE];
        >
        > fstream IN("junk", ios::in);
        >
        > // These 2 are ok.
        > IN.getline(char s, MAX_SIZE, EOF); // works, so EOF ok
        > getline(IN, s, 'x'); // works with string, no EOF
        >
        > // g++ doesn't like this one.
        > getline(IN, s, EOF); // what's wrong??
        >
        > return 0;
        > }
        >[/color]

        Here is a small example of one way to read the entire file. The key to
        answering your question is checking the state of the stream. Once you have
        read the last line of the file, it is the next call to getline() that will
        set the eof flag of ifl.

        #include <fstream>
        #include <iostream>
        #include <string>
        using namespace std;
        int main(int argc, char* argv[])
        {
        ifstream ifl("junk");
        string s, temp;
        while ( 1 )
        {
        getline(ifl, temp);
        if (ifl.eof()) break;
        s += temp + "\n"; // if you want to maintain line breaks
        }
        cout << "// starts on next line\n";
        cout << s;
        cout << "// ended on last line\n";
        return 0;
        }

        On an aside, if you just want to read the entire contents of the file,
        perhaps consider using read() on a binary file stream. You can open it at
        the end of the file to deduce the size in bytes of the file. Then seek back
        to the beginning and call read().

        Thanks,
        Kyle


        Comment

        • Peter Gordon

          #5
          Re: getline and EOF question

          "Amadeus W. M." <amadeus84@cabl espeed.com> wrote in
          news:pan.2005.0 7.01.06.14.50.9 09272@cablespee d.com:
          [color=blue]
          > I'm trying to read a whole file as a single string, using the getline[/color]
          ()[color=blue]
          > function, as in the example below. I can't tell what I'm doing wrong.
          > Tried g++ 3.2, 3.4 and 4.0. Thanks!
          >[/color]
          If the objective is to read a file into a string, the
          code below is handy and instructive. It does not use
          getline.

          /*
          From: Robert W Hand <rwhand@NOSPAMo peramail.com>
          Newsgroups: alt.comp.lang.l earn.c-c++
          Subject: Re: Reading a file into a string?
          Date: Wed, 30 Mar 2005 21:18:08 -0500

          */
          #include <iostream>
          #include <fstream>
          #include <istream>
          // #include <sstream>
          #include <string>
          #include <iterator>

          int main(int argc, char *argv[]) {
          if(argc != 3) {
          std::cerr << "Usage: " << argv[0] << " InputFile OutputFile" <<
          std::endl;
          return 1;
          }
          std::ifstream fin(argv[1], std::ios::in);
          if(fin.bad() ) {
          std::cerr << "Could not open" << argv[1] << "for reading." <<
          std::endl;
          return 1;
          }
          std::ofstream fout(argv[2], std::ios::out | std::ios::binar y);
          if(fout.bad() ) {
          std::cerr << "Could not open" << argv[2] << "for writing." <<
          std::endl;
          return 1;
          }

          fin.unsetf(std: :ios_base::skip ws);
          std::istream_it erator<char> in(fin);
          std::istream_it erator<char> out;
          std::string buf(in, out); // Problem Line for bcc
          fout << buf;
          fin.close();
          fout.close();

          return 0;
          }

          Comment

          • Amadeus W. M.

            #6
            Re: problem solved. Kinda of.

            On Fri, 01 Jul 2005 02:14:51 -0400, Amadeus W. M. wrote:
            [color=blue]
            > I'm trying to read a whole file as a single string, using the getline()
            > function, as in the example below. I can't tell what I'm doing wrong.
            > Tried g++ 3.2, 3.4 and 4.0. Thanks!
            >
            >
            > #include <iostream>
            > #include <fstream>
            > #include <cstdlib>
            > #include <string>
            >
            > using namespace std;
            >
            > int main(int argc, char * argv[])
            > {
            > const int MAX_SIZE=100000 ;
            > string s;
            > char chars[MAX_SIZE];
            >
            > fstream IN("junk", ios::in);
            >
            > // These 2 are ok.
            > IN.getline(char s, MAX_SIZE, EOF); // works, so EOF ok
            > getline(IN, s, 'x'); // works with string, no EOF
            >
            > // g++ doesn't like this one.
            > getline(IN, s, EOF); // what's wrong??
            >
            > return 0;
            > }[/color]


            std::getline(IN , s, (char) EOF); // works.

            The std is necessary, because there's a C version in stdlib.h:

            ssize_t getline(char **lineptr, size_t *n, FILE *stream);

            and the compiler thinks I'm trying to call that one. Also, without the
            cast to char, EOF is being treated as int. Don't know though why I don't
            have to cast it in the stream version of getline.

            So there, reading a file into a string can be done in one instruction.



            Comment

            • Larry I Smith

              #7
              Re: problem solved. Kinda of.

              Amadeus W. M. wrote:[color=blue]
              > On Fri, 01 Jul 2005 02:14:51 -0400, Amadeus W. M. wrote:
              >[color=green]
              >>I'm trying to read a whole file as a single string, using the getline()
              >>function, as in the example below. I can't tell what I'm doing wrong.
              >>Tried g++ 3.2, 3.4 and 4.0. Thanks!
              >>
              >>
              >>#include <iostream>
              >>#include <fstream>
              >>#include <cstdlib>
              >>#include <string>
              >>
              >>using namespace std;
              >>
              >>int main(int argc, char * argv[])
              >>{
              >> const int MAX_SIZE=100000 ;
              >> string s;
              >> char chars[MAX_SIZE];
              >>
              >> fstream IN("junk", ios::in);
              >>
              >> // These 2 are ok.
              >> IN.getline(char s, MAX_SIZE, EOF); // works, so EOF ok
              >> getline(IN, s, 'x'); // works with string, no EOF
              >>
              >> // g++ doesn't like this one.
              >> getline(IN, s, EOF); // what's wrong??
              >>
              >> return 0;
              >>}[/color]
              >
              >
              > std::getline(IN , s, (char) EOF); // works.
              >
              > The std is necessary, because there's a C version in stdlib.h:
              >
              > ssize_t getline(char **lineptr, size_t *n, FILE *stream);
              >
              > and the compiler thinks I'm trying to call that one. Also, without the
              > cast to char, EOF is being treated as int. Don't know though why I don't
              > have to cast it in the stream version of getline.
              >
              > So there, reading a file into a string can be done in one instruction.
              >
              >
              >[/color]

              Just be aware that this may work for text files, but probably
              won't work for binary files - where "(char) EOF" (0xff) may
              appear within the binary file.

              Larry

              Comment

              • Steven T. Hatton

                #8
                Re: getline and EOF question

                Amadeus W. M. wrote:
                [color=blue]
                > On Fri, 01 Jul 2005 05:33:08 -0400, Steven T. Hatton wrote:
                >[color=green]
                >> Amadeus W. M. wrote:
                >>[color=darkred]
                >>> I'm trying to read a whole file as a single string, using the getline()
                >>> function, as in the example below. I can't tell what I'm doing wrong.
                >>> Tried g++ 3.2, 3.4 and 4.0. Thanks!
                >>>
                >>>
                >>> #include <iostream>
                >>> #include <fstream>
                >>> #include <cstdlib>
                >>> #include <string>
                >>>
                >>> using namespace std;
                >>>
                >>> int main(int argc, char * argv[])
                >>> {
                >>> const int MAX_SIZE=100000 ;
                >>> string s;
                >>> char chars[MAX_SIZE];
                >>>
                >>> fstream IN("junk", ios::in);
                >>>
                >>> // These 2 are ok.
                >>> IN.getline(char s, MAX_SIZE, EOF); // works, so EOF ok
                >>> getline(IN, s, 'x'); // works with string, no EOF
                >>>
                >>> // g++ doesn't like this one.
                >>> getline(IN, s, EOF); // what's wrong??
                >>>
                >>> return 0;
                >>> }[/color]
                >>
                >> Unfortunately, there is a std::getline() declared as follows:
                >>
                >> template<class charT, class traits, class Allocator>
                >> basic_istream<c harT,traits>& getline(basic_i stream<charT,tr aits>& is,
                >> basic_string<ch arT,traits,Allo cator>& str, charT delim);
                >>
                >> It wants a charT which is not of the same type as EOF. Try calling the
                >> getline on IN. I have not tried that myself, so I don't know if it will
                >> help.[/color]
                >
                > I did, in the very program I posted, and it worked.[/color]

                What you posted was using an array of char with the member function. I
                tried passing a string to the member function, and it didn't work. I
                believe it could be made to work if the size of the file were passed to
                getline, but I'm not sure how to get the size of the file, and haven't
                found time to look into it.
                [color=blue]
                > I was curious why the one on string wouldn't work.[/color]

                In terms of the Standard, I believe my reply explained that. Don't you
                agree?
                [color=blue]
                > There is also a getline() in bits/basic_string.h
                >
                > template<typena me _CharT, typename _Traits, typename _Alloc>
                > basic_istream<_ CharT,_Traits>&
                > getline(basic_i stream<_CharT, _Traits>& __is,
                > basic_string<_C harT, _Traits, _Alloc>& __str, _CharT __delim);[/color]

                I don't recommend looking in bits for definitive answers to the C++ Standard
                Library API, but it can be instructive in both gaining a better
                understanding of the API, and seeing how it is implemented.
                [color=blue]
                > So in this version, the type of the delimiter must be the same _CharT
                > as in basic_istream and basic_string. The same is true for the istream
                > version of getline. So I don't understand why one works and the other
                > doesn't. What's the type of EOF? Whatever the type, it should both work,
                > or both not work.[/color]

                The errors I'm getting are suggesting that EOF is type int. You could try
                casting to char or something, but that doesn't seem like a portable
                solution, even if it does work. As to why it works in one case and not the
                other, I would really have to examine all the signatures. I've extracted
                most of the Standard Headers from the Standard, and created source code
                files. Unfortunately there are a few remaining to be done. Among them are
                some of the IO headers.

                Just as a guess, the could be a case where a template is being used in one
                circumstance, and not the other. Templates do not support type conversion
                in the same was as do comperable built in types.

                As for whether it /should/ work for both or neither, I agree that is
                desirable, but I don't believe the Standard dictates that, and it may be an
                unreasonable expectation of the implementers. I haven't seen a function
                signature in the Standard that would necessarily work for any form using
                EOF. If it does work in one circumstance, that's just luck of the draw.
                --
                If our hypothesis is about anything and not about some one or more
                particular things, then our deductions constitute mathematics. Thus
                mathematics may be defined as the subject in which we never know what we
                are talking about, nor whether what we are saying is true.-Bertrand Russell

                Comment

                • Steven T. Hatton

                  #9
                  Re: getline and EOF question

                  Amadeus W. M. wrote:
                  [color=blue]
                  > On Fri, 01 Jul 2005 05:33:08 -0400, Steven T. Hatton wrote:[color=green]
                  >> Unfortunately, there is a std::getline() declared as follows:
                  >>
                  >> template<class charT, class traits, class Allocator>
                  >> basic_istream<c harT,traits>& getline(basic_i stream<charT,tr aits>& is,
                  >> basic_string<ch arT,traits,Allo cator>& str, charT delim);
                  >>
                  >> It wants a charT which is not of the same type as EOF. Try calling the
                  >> getline on IN. I have not tried that myself, so I don't know if it will
                  >> help.[/color]
                  >
                  > I did, in the very program I posted, and it worked. I was curious why the
                  > one on string wouldn't work.[/color]

                  One thing I neglected to mention in previous replies - but which I suspect
                  we both agree upon - is that getline() is really not intended to be used in
                  this way, and there are better means of reading in a whole file. This
                  discussion is merely "academic". Do you agree?

                  --
                  If our hypothesis is about anything and not about some one or more
                  particular things, then our deductions constitute mathematics. Thus
                  mathematics may be defined as the subject in which we never know what we
                  are talking about, nor whether what we are saying is true.-Bertrand Russell

                  Comment

                  • Larry I Smith

                    #10
                    Re: getline and EOF question

                    Steven T. Hatton wrote:[color=blue]
                    > Amadeus W. M. wrote:
                    >[color=green]
                    >>On Fri, 01 Jul 2005 05:33:08 -0400, Steven T. Hatton wrote:[color=darkred]
                    >>>Unfortunatel y, there is a std::getline() declared as follows:
                    >>>
                    >>>template<cla ss charT, class traits, class Allocator>
                    >>> basic_istream<c harT,traits>& getline(basic_i stream<charT,tr aits>& is,
                    >>>basic_string <charT,traits,A llocator>& str, charT delim);
                    >>>
                    >>>It wants a charT which is not of the same type as EOF. Try calling the
                    >>>getline on IN. I have not tried that myself, so I don't know if it will
                    >>>help.[/color]
                    >>I did, in the very program I posted, and it worked. I was curious why the
                    >>one on string wouldn't work.[/color]
                    >
                    > One thing I neglected to mention in previous replies - but which I suspect
                    > we both agree upon - is that getline() is really not intended to be used in
                    > this way, and there are better means of reading in a whole file. This
                    > discussion is merely "academic". Do you agree?
                    >[/color]

                    The istream methods read() and readsome() would seem to be better
                    choices for the task.

                    Larry

                    Comment

                    • Amadeus W. M.

                      #11
                      Re: getline and EOF question

                      [color=blue]
                      > What you posted was using an array of char with the member function. I
                      > tried passing a string to the member function, and it didn't work.[/color]

                      Why would you expect it to work, if the prototype of the
                      istream::getlin e() is

                      istream& getline( char* buffer, streamsize num );
                      istream& getline( char* buffer, streamsize num, char delim );

                      string is not char*.
                      [color=blue]
                      > I believe it could be made to work if the size of the file were passed
                      > to getline, but I'm not sure how to get the size of the file, and
                      > haven't found time to look into it.[/color]

                      #include <iostream>
                      #include <fstream>
                      #include <cstdlib>
                      #include <inttypes.h>
                      #include <sys/stat.h>
                      #include <unistd.h>

                      using namespace std;

                      int main(int argc, char * argv[])
                      {

                      // Use the stat system call.
                      struct stat status;
                      stat(argv[1], &status);
                      std::cout << status.st_size << std::endl;

                      // Alternatively, use seekg+tellg
                      size_t pos;
                      fstream IN;

                      IN.open(argv[1], ios::in | ios::binary);
                      IN.seekg(0, ios::end);
                      pos = IN.tellg();
                      IN.seekg(0, ios::beg); // or IN.close();
                      cout << pos << endl;

                      return 0;
                      }

                      [color=blue][color=green]
                      >> I was curious why the one on string wouldn't work.[/color]
                      >
                      > In terms of the Standard, I believe my reply explained that. Don't you
                      > agree?[/color]

                      What's the standard got to do with it? I'm not saying the standard if
                      violated. In

                      istream::getlin e(char*, streamsize, char delim);

                      EOF is treated as char, whereas in

                      std::getline(is tream&, string &, char delimiter='\n') ;

                      EOF is treated as int (as you noticed). Notice that I used
                      IN.getline(...) , with fstream IN. Now fstream is an instantiation of
                      basic_fstream to char:

                      pwd
                      /usr/include/c++/3.4.0
                      grep fstream * | grep typedef | grep -v wchar
                      iosfwd: * typedef basic_ifstream< char> ifstream;
                      iosfwd: typedef basic_ifstream< char> ifstream; ///< @isiosfwd
                      iosfwd: typedef basic_ofstream< char> ofstream; ///< @isiosfwd
                      iosfwd: typedef basic_fstream<c har> fstream; ///< @isiosfwd

                      So then istream::getlin e() is not templated, and int to char is implicit.
                      On the other hand, std::getline is templated, and the conversion is not
                      implicit. Your intuition was right.
                      [color=blue]
                      > Just as a guess, the could be a case where a template is being used in one
                      > circumstance, and not the other. Templates do not support type conversion
                      > in the same was as do comperable built in types.
                      >[/color]


                      Comment

                      • Amadeus W. M.

                        #12
                        Re: getline and EOF question

                        > One thing I neglected to mention in previous replies - but which I suspect[color=blue]
                        > we both agree upon - is that getline() is really not intended to be used in
                        > this way, and there are better means of reading in a whole file. This
                        > discussion is merely "academic". Do you agree?[/color]

                        To paraphrase a famous president: it depends what the meaning of the word
                        "better" is. If by better you mean faster/more efficient, then of course,
                        I agree.

                        But e.g. for ASCII files of size=O(10k) on which you want to do
                        some find-and-replace, putting the entire file in a string in single
                        instruction is a pretty darn good way of doing it.

                        I don't suppose anyone in their right mind would try to read a 1G vob file
                        in a string, would they?


                        Comment

                        • Steven T. Hatton

                          #13
                          Re: getline and EOF question

                          Amadeus W. M. wrote:
                          [color=blue]
                          >[color=green]
                          >> What you posted was using an array of char with the member function. I
                          >> tried passing a string to the member function, and it didn't work.[/color]
                          >
                          > Why would you expect it to work, if the prototype of the
                          > istream::getlin e() is
                          >
                          > istream& getline( char* buffer, streamsize num );
                          > istream& getline( char* buffer, streamsize num, char delim );
                          >
                          > string is not char*.
                          >[color=green]
                          >> I believe it could be made to work if the size of the file were passed
                          >> to getline, but I'm not sure how to get the size of the file, and
                          >> haven't found time to look into it.[/color]
                          >
                          > #include <iostream>
                          > #include <fstream>
                          > #include <cstdlib>
                          > #include <inttypes.h>
                          > #include <sys/stat.h>
                          > #include <unistd.h>
                          >
                          > using namespace std;
                          >
                          > int main(int argc, char * argv[])
                          > {
                          >
                          > // Use the stat system call.
                          > struct stat status;
                          > stat(argv[1], &status);
                          > std::cout << status.st_size << std::endl;
                          >
                          > // Alternatively, use seekg+tellg
                          > size_t pos;
                          > fstream IN;
                          >
                          > IN.open(argv[1], ios::in | ios::binary);
                          > IN.seekg(0, ios::end);
                          > pos = IN.tellg();
                          > IN.seekg(0, ios::beg); // or IN.close();
                          > cout << pos << endl;
                          >
                          > return 0;
                          > }
                          >
                          >[color=green][color=darkred]
                          >>> I was curious why the one on string wouldn't work.[/color]
                          >>
                          >> In terms of the Standard, I believe my reply explained that. Don't you
                          >> agree?[/color]
                          >
                          > What's the standard got to do with it? I'm not saying the standard if
                          > violated. In
                          >
                          > istream::getlin e(char*, streamsize, char delim);
                          >
                          > EOF is treated as char, whereas in
                          >
                          > std::getline(is tream&, string &, char delimiter='\n') ;
                          >
                          > EOF is treated as int (as you noticed). Notice that I used
                          > IN.getline(...) , with fstream IN. Now fstream is an instantiation of
                          > basic_fstream to char:
                          >
                          > pwd
                          > /usr/include/c++/3.4.0
                          > grep fstream * | grep typedef | grep -v wchar
                          > iosfwd: * typedef basic_ifstream< char> ifstream;
                          > iosfwd: typedef basic_ifstream< char> ifstream; ///<
                          > @isiosfwd
                          > iosfwd: typedef basic_ofstream< char> ofstream; ///<
                          > @isiosfwd
                          > iosfwd: typedef basic_fstream<c har> fstream; ///<
                          > @isiosfwd
                          >
                          > So then istream::getlin e() is not templated, and int to char is implicit.
                          > On the other hand, std::getline is templated, and the conversion is not
                          > implicit. Your intuition was right.
                          >[color=green]
                          >> Just as a guess, the could be a case where a template is being used in
                          >> one
                          >> circumstance, and not the other. Templates do not support type
                          >> conversion in the same was as do comperable built in types.
                          >>[/color][/color]

                          Strange. In both cases the type of the delimiter is actually specified as a
                          template parameter. In the case of std::basic_istr eam<> it's a template
                          parameter of the class. In the std::getline() it's a template parameter of
                          the function. I'm not sure why one works and not the other.

                          In /usr/include/c++/3.3.5/string, bits/basic_string.h is the file being
                          #included. That means the std::getline in question is declared as follows:

                          template<typena me _CharT, typename _Traits, typename _Alloc>
                          basic_istream<_ CharT,_Traits>&
                          getline(basic_i stream<_CharT, _Traits>& __is,
                          basic_string<_C harT, _Traits, _Alloc>& __str, _CharT __delim);

                          Now /usr/include/c++/3.3.5/istream defines basic_istream like this:

                          template<typena me _CharT, typename _Traits>
                          class basic_istream : virtual public basic_ios<_Char T, _Traits>
                          {
                          public:
                          // Types (inherited from basic_ios (27.4.4)):
                          typedef _CharT char_type;

                          //...

                          __istream_type&
                          getline(char_ty pe* __s, streamsize __n, char_type __delim);
                          //...
                          };


                          The error message I get is this:

                          test.cpp: In function `int main(int, char**)':
                          test.cpp:21: error: invalid conversion from `void*' to `char**'
                          test.cpp:21: error: cannot convert `std::string' to `size_t*' for argument
                          `2'
                          to `__ssize_t getline(char**, size_t*, FILE*)'//wth is this?

                          That makes me believe its trying to use std::istream::g etline(). When I
                          explicitly wrote std::getline(IN , s, EOF);

                          I got:
                          test.cpp: In function `int main(int, char**)':
                          test.cpp:21: error: no matching function for call to `getline(std::f stream&,
                          std::string&, int)'


                          --
                          If our hypothesis is about anything and not about some one or more
                          particular things, then our deductions constitute mathematics. Thus
                          mathematics may be defined as the subject in which we never know what we
                          are talking about, nor whether what we are saying is true.-Bertrand Russell

                          Comment

                          • Steven T. Hatton

                            #14
                            Re: getline and EOF question

                            Larry I Smith wrote:
                            [color=blue]
                            > Steven T. Hatton wrote:[color=green]
                            >> Amadeus W. M. wrote:
                            >>[color=darkred]
                            >>>On Fri, 01 Jul 2005 05:33:08 -0400, Steven T. Hatton wrote:
                            >>>>Unfortunate ly, there is a std::getline() declared as follows:
                            >>>>
                            >>>>template<cl ass charT, class traits, class Allocator>
                            >>>> basic_istream<c harT,traits>& getline(basic_i stream<charT,tr aits>& is,
                            >>>>basic_strin g<charT,traits, Allocator>& str, charT delim);
                            >>>>
                            >>>>It wants a charT which is not of the same type as EOF. Try calling the
                            >>>>getline on IN. I have not tried that myself, so I don't know if it will
                            >>>>help.
                            >>>I did, in the very program I posted, and it worked. I was curious why the
                            >>>one on string wouldn't work.[/color]
                            >>
                            >> One thing I neglected to mention in previous replies - but which I
                            >> suspect we both agree upon - is that getline() is really not intended to
                            >> be used in
                            >> this way, and there are better means of reading in a whole file. This
                            >> discussion is merely "academic". Do you agree?
                            >>[/color]
                            >
                            > The istream methods read() and readsome() would seem to be better
                            > choices for the task.
                            >
                            > Larry[/color]
                            This is my choice:

                            ifstream in("filename") ;
                            stringstream ss;
                            ss << in.rdbuf();
                            --
                            If our hypothesis is about anything and not about some one or more
                            particular things, then our deductions constitute mathematics. Thus
                            mathematics may be defined as the subject in which we never know what we
                            are talking about, nor whether what we are saying is true.-Bertrand Russell

                            Comment

                            • Amadeus W. M.

                              #15
                              Re: getline and EOF question

                              > Strange. In both cases the type of the delimiter is actually specified as a[color=blue]
                              > template parameter. In the case of std::basic_istr eam<> it's a template
                              > parameter of the class. In the std::getline() it's a template parameter of
                              > the function. I'm not sure why one works and not the other.[/color]

                              Now you understand my confusion. Read my previous post more carefully.
                              fstream is in fact an instantiation of basic_fstream to char, so
                              istream::getlin e() is just a regular function now, and so the implicit
                              conversion from int to char of EOF. However, std::getline remains
                              templated, and the type of EOF must match that of string, and they don't.

                              [color=blue]
                              > The error message I get is this:
                              >
                              > test.cpp: In function `int main(int, char**)': test.cpp:21: error:
                              > invalid conversion from `void*' to `char**' test.cpp:21: error: cannot
                              > convert `std::string' to `size_t*' for argument `2'
                              > to `__ssize_t getline(char**, size_t*, FILE*)'//wth is this?[/color]

                              I explained this before: it's the C-version of getline. The compiler
                              finds this one first and complains. It will work if you use std::getline.

                              Comment

                              Working...