И если вы не возражаете против использования C ++ вместо C (обычно нет веской причины, почему бы и нет), то вы можете сократить свое решение до двух строк кода (используя генератор синтаксического анализатора AX):
vector<int> numbers;
auto number_rule = *(*(axe::r_any() - axe::r_num())
& *axe::r_num() >> axe::e_push_back(numbers));
Теперь проверьте это:
std::string str = "pt112parah salin10n m5:isstupid::42$%&%^*%7first3";
number_rule(str.begin(), str.end());
std::for_each(numbers.begin(), numbers.end(), [](int i) { std::cout << "\ni=" << i; });
и, конечно же, вы вернули свои номера.
И в качестве бонуса вам не нужно ничего менять при разборе строк в формате Unicode:
std::wstring str = L"pt112parah salin10n m5:isstupid::42$%&%^*%7first3";
number_rule(str.begin(), str.end());
std::for_each(numbers.begin(), numbers.end(), [](int i) { std::cout << "\ni=" << i; });
и, конечно же, вы вернули те же цифры.