std::istream& operator >> (std::istream& is, String& s)

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • randysimes
    New Member
    • Oct 2009
    • 54

    std::istream& operator >> (std::istream& is, String& s)

    I have to overload this operator to cin a character array to eventually put the strings in lexicographical order. The [size] is unknown and therefore will change accordingly.

    I do not know how to do this
  • Banfa
    Recognized Expert Expert
    • Feb 2006
    • 9067

    #2
    I think your problem would be more easily understood if you had posted code that included the "passed argument 's'".

    Also why are you using an array rather than a vector? Or for that matter why aren't you using string?

    Comment

    • randysimes
      New Member
      • Oct 2009
      • 54

      #3
      I can use vector, but am more familiar with arrays. I hear that vertors are much easier, as the [size] issue is automatically taken care of. Here the the header file:
      class String;

      // stand alone operators
      std::ostream& operator << (std::ostream& os, const String& s);
      std::istream& operator >> (std::istream& is, String& s);

      int operator == (const String& s1, const String& s2);
      int operator != (const String& s1, const String& s2);
      int operator < (const String& s1, const String& s2);
      int operator <= (const String& s1, const String& s2);
      int operator > (const String& s1, const String& s2);
      int operator >= (const String& s1, const String& s2);

      class String
      {

      public:
      String ( );
      explicit String ( const char * cstring );
      String ( size_t sz , char init );
      String ( const String& source );
      ~String ( );

      String& operator = ( const String& source );
      char& operator [] ( size_t i );
      const char& operator [] ( size_t i ) const; // const version of []

      void Wrap ( const char* cstring );

      size_t Size () const;
      size_t Length () const;
      const char* Cstr () const;

      // helper functions
      static int StrCmp ( const String& s1 , const String& s2 );
      static char* NewStr ( size_t size );

      private:
      size_t size_; // 1 + size_ = total space allocation
      char* data_; // last element data_[size_] = '\0'
      };

      Comment

      • Banfa
        Recognized Expert Expert
        • Feb 2006
        • 9067

        #4
        Why have you created your own string class when there is std::string that already has a getline overload for use with an istream?

        Comment

        • randysimes
          New Member
          • Oct 2009
          • 54

          #5
          It is a project for school. Some features: Expandable Size (so input operator can take any string w/o restricting the number of chars.), Equality and comparison operators (so string objects can be compared by client programs), and Constructors, Destructors, and assignment operators to make it a proper type.

          Comment

          • Banfa
            Recognized Expert Expert
            • Feb 2006
            • 9067

            #6
            OK I understand. In your operator you need to read a fixed amount of data at a time, probably 1 char to prevent the function from accidentally reading data destined for a different String.

            Having got the character you need to check it to see if it meets your end condition; that is if it is whatever character you are going to say delimits strings, for std::string that is any white space but you could make it anything you want.

            If it is you end condition return.

            Otherwise add it to the array in your string.

            Here is the problem, as you say you have no idea how many characters you are going to get input so you can not allocate enough data in advance, that means that every-time you store a new character in the String the first thing you have to check is if there is enough data to store the character. If there isn't then you must reallocate the Strings internal array.

            Here is the crunch, if you store the data you have (size and pointer) that implies that the size is the exact size of the String, every time you store a new character you will need to reallocate, that will be very inefficient (but it would work).

            What would be better is to have a array that is at least big enough to store the string but may be bigger. Strings private data should contain 3 members, size, capacity and pointer where size is the actual size of the string and capacity is the current size of the buffer. That way the buffer size can be larger than the string size. Then when you allocate extra data you can expand the buffer by more than a single character which means you wont have to allocate every time you store an extra character.

            What allocation algorithm you use is up to you, it could be something simple like +10 characters, I have sometimes used *1.6 of the current size which is a fairly efficient growth algorithm for its complexity.

            Comment

            • randysimes
              New Member
              • Oct 2009
              • 54

              #7
              I had this to start:
              for(unsigned int 1 =0; 1 < 100; i++)
              {
              is >> s[ i ];
              }
              return is;

              This would return the "String index out of bounds" error seen in the code below.

              const char& String::operato r [] (size_t i) const
              {
              if (i < size_)
              return *(data_ + i);
              if (size_ == 0)
              {
              std::cerr << "** String memory unallocated\n"
              << " Unable to recover\n"
              << " Exiting program\n";
              exit (EXIT_FAILURE);
              }
              std::cerr << "** String index out of bounds\n"
              << " Returning last element\n";
              return *(data_ + (size_ - 1));
              }

              Comment

              • Banfa
                Recognized Expert Expert
                • Feb 2006
                • 9067

                #8
                Of course it will if you are trying to insert data into the string when it is already at behond its current length.

                Firstly you need to read is into a local variable not straight into string.

                Secondly you overloaded operator>> can not use the public interface to string defined by operator[] because it needs to be able to tell the string to insert the character allocating new data if required but operator[] doesn't do this, it checks the array index provided and raises an exception if it is out of bounds.

                Your overloaded operator>> specifically needs a function that will change the bounds not raise an exception if the are exceeded.

                Comment

                Working...