를 반환 내가이 다음 문자열 : 결과가변환 문자열은 잘못된 결과
iStart = 2147483647
이 사람이 내 실수를 볼 수 있는가이다 그러나
sThis = "2154910440";
unsigned int iStart=atoi(sThis.c_str());
?
를 반환 내가이 다음 문자열 : 결과가변환 문자열은 잘못된 결과
iStart = 2147483647
이 사람이 내 실수를 볼 수 있는가이다 그러나
sThis = "2154910440";
unsigned int iStart=atoi(sThis.c_str());
?
atoi
은 문자열을 int
으로 변환합니다. 시스템에서 int
은 32 비트이고 최대 값은 2147483647입니다. 변환하려는 값이이 범위를 벗어나므로 atoi
의 반환 값은 정의되지 않습니다. 귀하의 구현은이 경우 int
의 최대 값을 반환합니다.
대신에 atoll
을 사용할 수 있습니다.이 길이는 long long을 반환하며 64 비트 이상이어야합니다. 또는 stoi/stol/stoll
패밀리의 함수 또는 unsigned counterparts을 사용할 수 있습니다.이 함수는 예외 범위의 범위를 벗어난 값 (및 유효하지 않은 값)에 대한 유용한 오류보고를 실제로 제공합니다.
개인적으로 나는 boost::lexical_cast
을 좋아합니다. 다소 번거롭기는하지만 좀 더 일반적인 맥락에서 사용될 수 있습니다. 템플릿에서 사용할 수 있으며 전문화가 필요하지 않고 형식 인수를 전달할 수 있습니다.
OP는 그가 C++ 11을 사용하고 있다고 말하지 않았습니다. –
@Kyle_the_hacker : 글쎄, 2013 년입니다. 달리 말하지 않는 한, 제 대답으로 계속 추측하겠습니다. –
@BenjaminLindley 어떤 종류의 현실을 무시합니다. –
atoi는 플랫폼에 최대 값이 2^31-1
인 부호있는 int를 반환합니다.
결과를 지정하는 데 아무런 문제가 없으며 반환 유형으로 제한됩니다.
C++ 스트림은 부호없는 int를 읽을 수 있습니다.
std::istringstream reader(sThis);
unsigned int val;
reader >> val;
대신 부호없는 숫자 위해 설계 <cstdlib>
에서 발견 std::strtoul
을, 사용한다 더 큰 범위를 가지고있어 오류를보고 더 나은.
오류 처리를 위해 입력 및 예외에 std::string
을 사용하려면 std::stoul
을 사용하십시오. 다음과 같이 짧은, 매우 효율적인 구현은 다음과 같습니다
#include <string>
#include <stdexcept>
inline unsigned int stoui(const std::string& s)
{
unsigned long lresult = stoul(s, 0, 10);
unsigned int result = lresult;
if (result != lresult) throw std::out_of_range();
return result;
}
이것은 istringstream
보다 훨씬 빠를 것이다, 문화권, (행동 때문에 전혀 예상치 못한 변화 특이한 로케일에서 실행) 완전히 휴대용 및을 사용하여 세 번째 인수 인 경우 다른 숫자 기반을 지원하거나 0x
및 0
접두사를 검색 할 수도 있습니다.
그러나 unsigned int
은 반드시 값을 보유 할 정도로 크지 않으므로 unsigned long
을 사용하면 위의 래퍼가 필요하지 않습니다.
나는 strtoul이 더 이식성이 있다는 것에 동의한다. –
내가 아는 한 unsigned long은 일부 플랫폼과 OS에서 unsigned int와 같지 않다. x86_64 아키텍처의 Linux에서는 크기가 달라야합니다. – Sergey
@ Sergey : 예, 그렇기 때문에'strtoul'이 더 나은 선택입니다. 강제 변환 전후의 값을 'unsigned int'와 비교하여 값이 너무 큰지 여부를 확인할 수 있습니다. –
부호없는 int는 종종 C++의 32 비트 값이며 최대 값은 4,294,967,295입니다. 따라서 2,154,710,440은 부호없는 int로 표현 될 수 있습니다. 그러나 atoi는 부호가있는 int로 변환되며 최대 값은 2,147,483,647입니다. 따라서 문자열이 값 범위를 오버플로하여 답변이 잘못된 이유입니다. 문자열을 64 비트 이상인 긴 long으로 변환하는 atoll을 사용할 수 있습니다. 정수 크기는 C++에서 컴파일러에 따라 다릅니다. stdint.h 헤더 파일을 포함시킨 다음 uint32_t 또는 uint64_t 등을 사용하는 것이 좋습니다. 그러면 처리중인 크기를 알 수 있습니다.
항상 정확히을 수행하는 고유 한 기능을 작성할 수 있음을 잊지 마십시오.
이 코드는 -9223372036854775806 (2^63 + 1)과 9223372036854775807 (2^63-1) 사이의 숫자로 작동합니다. 이 같은
뭔가 :
long long int myAtoi (string str) {
long long int value = 0;
for (int i = 0; i < str.size(); i++) {
if (str[i] != '-') {
value *= 10;
value += (int) ((str[i]) - '0');
}
}
if (str.size() > 0 && str[0] == '-')
return -value;
else
return value;
}
주어진 바와 같이이 함수는 마이너스 기호를 너무 자유롭게 처리하며 -1033589를 반환하여 "----- 10 ---- 33 --- 5-8-9-"와 같은 문자열을 처리합니다. –
당신은 long int와 문자열을 변환 푸티 Atol를 사용할 수 있습니다. 자세한 내용은 Linux의 man atol을 참조하십시오.
#include <stdlib.h>
long atol(const char *nptr);
불행하게도 C++ 서명되지 않은 INT 구문 분석에 대한 임베디드 구현이 없으며이 정말 이상하다 프로토 타입.
#include <stdint.h>
#include <sstream>
inline unsigned int stoui(const std::string& s)
{
std::istringstream reader(s);
unsigned int val = 0;
reader >> val;
return val;
}
// This may be not the same as stoui on some platforms:
inline uint32_t stoui32(const std::string& s)
{
std::istringstream reader(s);
uint32_t val = 0;
reader >> val;
return val;
}
아무도 필요로하지 않았기 때문입니다. 'strtoul'은 유효한'unsigned int '값을 파싱하는데 완벽하게 잘 작동하며, 오버 플로우를 감지하기 위해서는 단지 하나의 여분의 비교가 필요합니다.간단히 말해서, 제공 한 오류 코드에서 깨진 (오류 검출에 완전히 부족한) 코드보다 훨씬 더 효율적입니다. –
BTW, [기존 답변]을 회상하기 위해 downvoting (http://stackoverflow.com/a/18037886/103167). –
@BenVoigt : 당신은 나쁜 해결책을 제안하고 있습니다. 불행히도 여기서는 코드 샘플을 넣을 수 없으므로 회신을 주요 질문으로 업데이트했습니다. – Sergey
atoi
이 std::string
부호 INT int
에하지 변환 : 여기
unsigned int iStart = *(unsigned*)(sThis.c_str());
합니다. atoi() 문서를 자세히 읽으면서 표지판이 무엇인지 살펴보십시오. – GreatBigBore