0

I was practicing about cutting a string into parts, and I wrote these codes.

string a = "12/1322.39102";
int current = 0;
int next;

while (true)
{
    next = a.find_first_of("/.", current);

    if (next != current)
    {
        cout << "c = " << current << endl;
        cout << "n - c = " << next-current << endl;
        string tmp = a.substr(current, next-current);

        if (tmp.size())
            cout << tmp << endl;
    }

    if (next == string::npos)
        break;

    current = next + 1;
}

I was confused because if find_first_of cannot find any character (i.e. '/' and '.'), it'll return npos, or return -1.

In that case, I think it'll not output the last number 39102 because next-current equal -9.

Another question is, what's the difference between npos and end() (used in vector or map) ?

Steffen Moritz
  • 7,277
  • 11
  • 36
  • 55
niorix
  • 65
  • 6
  • btw, codes mainly refer to [here](http://justimchung.blogspot.com/2018/03/c.html) – niorix Jul 05 '19 at 07:58
  • Does this compile? As far as I remember std::find_first_of expects iterators as input. Please check. – A M Jul 05 '19 at 08:06
  • @ArminMontigny [`std::find_first_of`](https://en.cppreference.com/w/cpp/algorithm/find_first_of) does take iterators, but [`std::basic_string::find_first_of`](https://en.cppreference.com/w/cpp/string/basic_string/find_first_of) takes string/char and optionally a starting position. – Yksisarvinen Jul 05 '19 at 08:41
  • npos is a size_t type whereas end is an iterator. – macroland Jul 05 '19 at 08:44
  • I just wonder when `std::find_first_of` cannot find any character matched in string, it'll return `string::npos`, but it'll make `next-current` to be a negative integer, then how does `substr()` works? – niorix Jul 05 '19 at 09:21
  • @Yksisarvinen. Sorry, You are right. With std::string takes other parameters. Sorry again – A M Jul 05 '19 at 09:21
  • And [this](https://ideone.com/AC4MBB) is the result after I run this code, hope it helps, thanks. – niorix Jul 05 '19 at 09:22
  • `if (next == string::npos)` should be the first check after your search. – UmNyobe Jul 05 '19 at 09:29
  • @JstMonika You're right, my answer was invalid. Removed it now. – Yksisarvinen Jul 06 '19 at 09:26

1 Answers1

0

Aside of the very good point Yksisarvinen made, right now you first try to exploit the result, before checking if there is any valid result. In your code next ==string::npos is true, and nothing inside the first if will behave as expected.

The absolute first check you should make when searching, whichever technique you use (find, regex, homemade code) is did we find anything ? if (next == string::npos) should be the first thing after find...

UmNyobe
  • 22,539
  • 9
  • 61
  • 90
  • Can I just move this check below the output? I think `if (next == string::npos)` is meant to check if there has any other character between to substring, which means it will has another output after `next == string::npos` is true. This is my [code](https://ideone.com/2gOYBc), the previous one is refer to the web, sorry for that. – niorix Jul 06 '19 at 05:12
  • no you can't. `next != current` will be true if the string is non empty and there is no match. – UmNyobe Jul 08 '19 at 07:49