0

I've been constantly getting this error for the following block of program, isn't an iterator also a pointer when using such string data types?

 error: cannot convert 'std::basic_string<char>::iterator 
 {aka __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >}'
 to 'const char*' for argument '2' to 'char* strcat(char*, const char*)'
 strcat(temp, str1.begin());
                        ^





            int areRotations(string str1, string str2)
            {
              int size1   = str1.length();
              int size2   = str2.length();
              char* temp= new char[size1+size2+1];
              void *ptr;
              if (size1 != size2)
              return 0;


              strcat(temp, str1.begin());
              strcat(temp, str1.begin());

              /* Now check if str2 is a substring of temp */
               ptr = strstr(temp, str2);


               if (ptr != NULL)
               return 1;
               else
               return 0;
            }
nalzok
  • 14,965
  • 21
  • 72
  • 139
Yash Kant
  • 458
  • 1
  • 6
  • 11
  • Why do you use `strcat` with `std::string`? Or, rather, why isn't `temp` a `std::string`? – M Oehm Mar 21 '16 at 09:25
  • Iterators are not pointers. Pointers are iterators. – Simple Mar 21 '16 at 09:26
  • 1
    `str1.begin()` and `C`? How exactly? – Sourav Ghosh Mar 21 '16 at 09:27
  • 1
    You know that you can concatenate std::strings using `+`? – LiMuBei Mar 21 '16 at 09:28
  • 2
    This function boils down to a single line: `return str1.size() == str2.size() && (str1+str1).find(str2) != string::npos;` – paddy Mar 21 '16 at 09:33
  • @LiMuBei Yes I know that, thanks for the down-vote anyways! – Yash Kant Mar 21 '16 at 09:34
  • Iterators *behave* very much like pointers - but they don't (necessarily) have the same type as pointers. Your code has a bug given `areRotations( "abcdefghijklmnopqrstuvw", "1")` - you will overflow temp. Also you have a memory leak. You want `bool areRotations(const std::string& str1, const std::string& str2) { return (str1+str1).find(str2) != std::string::npos;}` – Martin Bonner supports Monica Mar 21 '16 at 09:35
  • @MartinBonner Hey I've allotted temp variable a **space** of char* temp= new char[size1+size2+1]; Isn't that sufficient? – Yash Kant Mar 21 '16 at 09:42
  • Nothing like receiving advice and then refusing to follow it. – paddy Mar 21 '16 at 09:43
  • @paddy Hey I've solved it!! by passing the pointer to string as an argument....thanks :) – Yash Kant Mar 21 '16 at 09:46
  • 1
    All other proposed solutions are better than what you just described. – paddy Mar 21 '16 at 09:49
  • @paddy yes I get it exactly, but I was pondering over the properties of strcat() function....thanks again :V – Yash Kant Mar 21 '16 at 09:51
  • 1
    Then you should probably accept the answer that mentions using `c_str` to obtain a pointer to the buffer, amongst other explanations. Don't forget to free your temporary memory with the correct array-delete operator on all control paths, or use `std::unique_ptr`. – paddy Mar 21 '16 at 09:54
  • @YashKant: No. In my example, you would allows 23+1+1 characters, and then copy 23+23+1 characters in. That won't fit. *pause* Ah! I missed the `if (size1!=size2) return 0;`. In that case the allocation is confusing but safe (better would be `2*size1+1`). – Martin Bonner supports Monica Mar 21 '16 at 09:55
  • @YashKant I did not down-vote. My comment was not ill-intended. I was simply wondering why you chose to use strcat with std::strings... – LiMuBei Mar 21 '16 at 14:07

2 Answers2

4

You ask,

isn't an iterator also a pointer when using such string data types

No, not necessarily.

For std::string it can be a pointer because std::string has a guaranteed contiguous buffer, so incrementing a pointer moves it forward in the buffer. However, I don't know of any extant C++ standard library implementation where it is a pointer.

A simple way to get a pointer to the buffer, that works also for an empty string, is to use the data member function. When you know that the string is non-empty you can also use &s[0] for this. A simple way to get a pointer to non-modifiable zero-terminated string, is to use the c_str member function.


Instead of strcat, with std::string you can just use + or +=.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
3

Pointer are iterators. the other way around is not always true. You can find here more information: How are iterators and pointers related?

However you are mixing up quite some things... C, C++. A simple C++ solution to your problem which simply uses std::string would be:

#include <iostream>

using namespace std;
bool areRotations(const string& str1, const string& str2)
{
    const string temp = str1 + str1;
    return ((temp.find(str2)!=std::string::npos) && (str1.size()==str2.size()));
}

int main()
{
    const std::string str1 = "hello";
    const std::string str2 = "lohel";
    cout << areRotations(str1,str2) << endl;
}
Community
  • 1
  • 1
Stefano
  • 3,981
  • 8
  • 36
  • 66