Изменить: в c ++ 17 или новее from_chars
предпочтительнее. Подробнее см. Здесь: https://topanswers.xyz/cplusplus?q=724#a839 а>
Для данного string str
есть несколько способов добиться этого, каждый со своими преимуществами и недостатками. Я написал здесь живой пример: https://ideone.com/LO2Qnq и обсудите каждый ниже:
Как было предложено, здесь strtol
out-параметр может использоваться для получения количества прочитанных символов. strtol
фактически возвращает long
, а не int
, поэтому при возврате выполняется приведение.
char* size;
const int num = strtol(str.c_str(), &size, 10);
if(distance(str.c_str(), const_cast<const char*>(size)) == str.size()) {
cout << "strtol: " << num << endl;
} else {
cout << "strtol: error\n";
}
Обратите внимание, что здесь используется str.c_str()
для ссылки на ту же строку. c_str
Возвращает указатель на базовый массив, служащий хранилищем символов, а не временным если у вас C ++ 11:
c_str()
и data()
выполняют одну и ту же функцию
Также обратите внимание, что указатель, возвращаемый c_str
, будет действителен между вызовами strtol
и distance
, если:
- Передача не
const
ссылки на string
любой стандартной библиотечной функции
- Вызов функций-членов, отличных от
const
, на string
, за исключением operator[]
, at()
, front()
, back()
, begin()
, rbegin()
, end()
и rend()
Если вы нарушите любой из этих случаев, вам нужно будет сделать временную копию i
, лежащего в основе const char*
, и выполнить на ней проверку.
sscanf
может использовать %zn
для возврата количества прочитанных символов, что может быть более интуитивно понятным, чем сравнение указателей. Если база важна, sscanf
может быть не лучшим выбором. В отличие от strtol
и stoi
, которые поддерживают базы 2–36, sscanf
предоставляет спецификаторы только для восьмеричного (%o
), десятичного (%d
) и шестнадцатеричного (%x
).
size_t size;
int num;
if(sscanf(str.c_str(), "%d%zn", &num, &size) == 1 && size == str.size()) {
cout << "sscanf: " << num << endl;
} else {
cout << "sscanf: error\n";
}
Как было предложено здесь stoi
's выходной параметр работает как sscanf
%n
, возвращая количество прочитанных символов. В соответствии с C ++ для этого требуется string
, и в отличие от описанных выше реализаций C stoi
выдает _47 _ если первый непробельный символ не считается цифрой для текущей базы, и это, к сожалению, означает, что, в отличие от реализаций C, он должен проверять наличие ошибки как в блоках try
, так и catch
.
try {
size_t size;
const auto num = stoi(str, &size);
if(size == str.size()) {
cout << "stoi: " << num << endl;
} else {
throw invalid_argument("invalid stoi argument");
}
} catch(const invalid_argument& /*e*/) {
cout << "stoi: error\n";
}
person
Jonathan Mee
schedule
07.10.2015
cout << "\tinput string: " << i << (all_of(i, i + strlen(i), bind(isdigit, placeholders::_1)) ? " is good\n" : " is bad\n");
Однако, хотя я могу проверять так я не хочу. Все остальные функции также должны проходить через каждого персонажа, и я хотел бы иметь способ использовать то, что они уже знают. - person Jonathan Mee   schedule 07.10.2015stoi
. Мне удалось найти решение, использующееstrtol
, которое также является жизнеспособным. Однако тот факт, что ответ, отвечающий на мой вопрос, предоставлен по отдельному вопросу, не делает его дубликатом. Я искал на stackoverflow.com вопрос о преобразовании всей строки в число, но не нашел ни одного . Этот вопрос избавляет следующего человека от необходимости повторять его. - person Jonathan Mee   schedule 07.10.2015stoi
, как вы предложили, и поэтому, если вы хотите набрать ответ, я приму ваш, поскольку вы сначала были справа от него. - person Jonathan Mee   schedule 07.10.2015