Trying to a string character iterator class but it doesn't iterate.

I wanted to write my own StringCharacterIterator class, like the one in Java, in C++. I've written the code below. The problem is in the for loop. It does the initialization, and the boolean but it doesn't proceed with the rest of the loop. I've written the ouput the code produces.

I want to know where my fault it.

StringCharacterIterator.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef STRINGCHARACTERITERATOR_H
#define STRINGCHARACTERITERATOR_H

class StringCharacterIterator{
      public:
             StringCharacterIterator(const char* s);
             ~StringCharacterIterator();
             const char firstCharacter();
             const char lastCharacter();
             const char nextCharacter();
             const char previousCharacter();
             const char currentCharacter();
             bool haveReachedEndOfString();
      private:
             const char* first;
             const char* current;
             int lengthOfStringBeingIterated;
};

#endif 


StringCharacterIterator.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include "StringCharacterIterator.h"
#include <iostream>

StringCharacterIterator::StringCharacterIterator(const char* stringBeingIterated)
{                                                   
 this->lengthOfStringBeingIterated=strlen(stringBeingIterated)-1;  
 this->first = stringBeingIterated;
 this->current = stringBeingIterated;                 
}

const char StringCharacterIterator::firstCharacter()
{
      this->current = this->first;
      std::cout<<*first<<std::endl;
      return *first;                                
}

const char StringCharacterIterator::lastCharacter()
{
      const char* last = this->first+lengthOfStringBeingIterated;
      this->current = last;
      return *last;                            
}

const char StringCharacterIterator::nextCharacter()
{
      std::cout<<"nextCharacter"<<std::endl;
      this->current++;
      return *current;                             
}

bool StringCharacterIterator::haveReachedEndOfString()
{
     std::cout<<"haveReachedEndOfString() invoked."<<std::endl;
     if(*current == '\0')
     {
      std::cout<<"true"<<std::endl;                     
      return true;
     }
     else{
      std::cout<<"false"<<std::endl;                     
      return false;
     }
}


main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "StringCharacterIterator.cpp"
#include <iostream>
#include <string>

int main()
{
 StringCharacterIterator *s= new StringCharacterIterator("abcd");
 for(char c = s->firstCharacter(); s->haveReachedEndOfString();c=s->nextCharacter())
 {
  std::cout<<"Here are the letters: "<<std::endl;        
  std::cout<<c<<std::endl;         
 }
 system("pause");
 return 0;
}


output

a
haveReachedEndOfString() invoked.
false

I just wrote this to kinda practice pointers. Any suggestions for improving efficiency will be appreciated.

Thanks.
Last edited on
I've figured it out.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "StringCharacterIterator.cpp"
#include <iostream>
#include <string>

int main()
{
 StringCharacterIterator *s= new StringCharacterIterator("abcd");
 for(char c = s->firstCharacter(); !s->haveReachedEndOfString();c=s->nextCharacter())
 {
  std::cout<<"Here are the letters: "<<std::endl;        
  std::cout<<c<<std::endl;         
 }
 system("pause");
 return 0;
}
Last edited on
Objects are normally not created with new in C++ - and when you do, you have to delete them afterwards.
You should create the iterator as follows:
StringCharacterIterator s("abcd");
Or a more common syntax for constructors with one parameter:
StringCharacterIterator s="abcd";

And instead of having a function called nextCharacter, it would be better to use operator++ for this.
Instead of haveReachedEndOfString, you can make use of operator bool (conversion to bool), which shortens your loop condition to "s". To get the current character, making use of operator* (dereferencing) would be appropriate.
In summary, it should be possible to rewrite the code to look like this:

1
2
3
4
5
  StringCharacterIterator s="abcd";
  for(;s;++s)
  {
    std::cout << *s << std::endl;         
  }


I'm not sure if you're aware of it, but it's already possible to iterate over a string:
1
2
string str="abcd";
for (string::iterator it=str.begin();it!=str.end();++it)cout << *it << endl;


Or with C++11:
for (auto c : str)cout << c << endl;
or
for_each(begin(str),end(str),[](char c) {cout << c << endl;});

Objects are normally not created with new in C++ - and when you do, you have to delete them afterwards.
You should create the iterator as follows:
StringCharacterIterator s("abcd");
Or a more common syntax for constructors with one parameter:
StringCharacterIterator s="abcd";


Thanks for that tip. I've been using Java for learning Android development, and got into the 'new' habit. Your other suggestions about the operators really do clean up the code.

I'm not sure if you're aware of it, but it's already possible to iterate over a string:
I'm both aware, and have used string iterators before. I'm just not very good with pointers, especially where character arrays are concerned, so I decided to make this, kinda like a practice exercise.

Thanks a lot for your help.
Last edited on
Topic archived. No new replies allowed.