2

I want to iterate through a string vector in c++. I want to open each item in the list with fopen.

const char *filep //fopen needs a constant char pointer.
for (vector<string>::iterator it = filelist.begin(); it != filelist.end(); it++)
{
    filep = (const char *)it; //This isn't working. How can I fix this
    fopen(filep, "rb"); 
}
gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • try `*it` ...... – valdo Nov 30 '17 at 08:47
  • The really scary thing is that this might have compiled on some compilers, and then only crashed at runtime. – Sebastian Redl Nov 30 '17 at 08:56
  • @SebastianRedl - that's why the use of explicit type conversions (like `(const char *)` in this case) is deemed poor practice in C++ and actively discouraged by quite a few coding guidelines and by experienced developers. Essentially, such conversions force the compiler to do a conversion that would otherwise be diagnosed as an error. – Peter Nov 30 '17 at 09:00

4 Answers4

6

You should have used it->c_str() as it is essentially a pointer to the element in the std::vector. But for an easier life use

for (const auto& s : filelist){
    // s is a const reference to an element in filelist
    // use s.c_str() if you need the character buffer
}

This is valid from C++11 onwards. Using const auto& rather than auto obviates a std::string copy.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
2

Change this:

filep = (const char *)it;

to this:

filep = it->c_str();

However, you do extra, unnecessary steps, since you could just do this instead:

for (vector<string>::iterator it = filelist.begin(); it != filelist.end(); it++)
    fopen(it->c_str(), "rb"); 

which reduces the number of lines of your code to just two, and doesn't use an extra pointer.


PS: A more modern approach can be found in Bathsheba's answer, or use the auto&& approach.

gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • But seriously, there's no harm in having similar answers: why not re-introduce yours? SO works best when there are a few answers to choose from. – Bathsheba Nov 30 '17 at 08:51
  • @Bathsheba it was like a synopsis of yours, without a const. I will updated to suggest your answer though, I like it more! ;) – gsamaras Nov 30 '17 at 08:53
  • 1
    Yeah, it [seems like it](https://stackoverflow.com/questions/13230480/what-does-auto-tell-us) ;) – gsamaras Nov 30 '17 at 08:56
0

A std::string is a type which is completely different from const char *. Hence, you need to get underlying character buffer stored in string. For that You must use method std::string::c_str() or std::string::data() whatever you like.

Do it like below (Inspired from other answers now using range-based for-loop),

const char *filep //fopen needs a constant char pointer.
for (auto & str : filelist)
{
    filep = str.c_str();
    fopen(filep, "rb"); 
}
Pravar Jawalekar
  • 605
  • 1
  • 6
  • 18
0

create a method getstring in which you will return the string.

for(unsigned int i=0; i<iterator.size();i++){
cout << iterator[i]->getstring()<<endl;
}
D.U
  • 1
  • 3