Menu

C# 문자열 int 변환, 캐스팅, 형 변환: Parse, TryParse, Convert

C#에서 int.Parse, int.TryParse, Convert.ToInt32로 문자열을 int로 바꾸는 방법, 암시적 캐스트와 명시적 캐스트의 동작, double을 캐스트하면 소수점이 잘리는 이유, as와 is 연산자, 그리고 "1.5"가 15로 파싱될 수 있는 이유를 알아봅니다.

이 페이지에는 실행 가능한 에디터가 있습니다 - 편집하고 실행하면 결과를 바로 볼 수 있습니다.

C#은 관련 없는 타입 사이를 스스로 변환하지 않습니다. 숫자가 들어 있는 문자열도 여전히 문자열이고, double이 슬그머니 int가 되지도 않습니다. 변환은 명시적으로 하며, 무엇을 변환하느냐에 따라 쓰는 도구가 다릅니다. 텍스트를 숫자로(파싱), 한 숫자 타입을 다른 숫자 타입으로(캐스팅), 객체를 더 구체적인 타입으로(as, is).

문자열을 int로: Parse, TryParse, Convert

텍스트를 int로 바꾸는 표준 방법은 세 가지입니다:

출력:

2500
TryParse ok: 1250
TryParse failed, d = 0
42
-17

int.TryParse는 bool을 반환하고 결과를 out 변수에 쓰며, 실패하면 그 변수는 0이 됩니다. 사용자가 입력하는 모든 것에서 잘못된 입력은 흔한 일이므로, 입력, 파일, 쿼리 문자열에는 TryParse가 기본 선택입니다. 같은 메서드가 모든 숫자 타입에 있습니다: long.TryParse, double.TryParse, decimal.Parse 등.

잘못된 입력에서 각 메서드가 하는 일

세 메서드는 실패하는 방식만 다릅니다:

출력:

int.Parse(null) throws ArgumentNullException
Convert.ToInt32(null) = 0
int.Parse("abc") throws FormatException
int.Parse("12.5") throws FormatException
int.Parse("1,000") throws FormatException
int.Parse("9999999999") throws OverflowException
int.Parse("") throws FormatException

FormatException은 익숙한 메시지 "Input string was not in a correct format"(.NET 8 이상에서는 텍스트를 인용해 "The input string '12.5' was not in a correct format")을 담고 있으며, 가장 흔한 C# 런타임 오류 중 하나입니다. "12.5"는 int가 아니고, "1,000"도 아닙니다. 이런 값을 받으려면 decimal로 파싱하거나, 파서에 허용할 스타일을 알려 주세요:

출력:

1000
255
13
10

문화권: "1.5"가 15가 될 수 있는 이유

파싱은 기본적으로 현재 문화권을 쓰는데, 문화권마다 구분 기호가 다릅니다. 독일어를 비롯한 몇몇 유럽 문화권에서는 소수점 구분 기호가 쉼표이고 마침표는 천 단위를 묶습니다. 같은 문자열이 다른 숫자가 됩니다:

출력:

1.5
15
1.5

데이터 파일, JSON, 설정처럼 기계가 만든 것을 읽는 코드는 파싱할 때와 서식화할 때 모두 항상 CultureInfo.InvariantCulture를 넘겨야 합니다. 그렇지 않으면 같은 프로그램이 개발자 컴퓨터에서는 동작하고, 다른 언어로 설정된 서버에서는 모든 숫자를 잘못 읽습니다. 현재 문화권은 사람이 입력했거나 사람이 읽을 텍스트에만 쓰세요.

암시적 숫자 변환과 명시적 숫자 변환

확대 변환은 암시적으로 일어납니다: int에서 long, int에서 double, float에서 double, int에서 decimal. 값의 크기나 소수 부분을 잃을 수 있는 변환에는 명시적 캐스트 (type)value가 필요합니다. 기억해 둘 예외가 하나 있습니다. int나 long에서 float로, long에서 double로의 변환은 정밀도를 잃을 수 있는데도 암시적입니다. float f = 16_777_217;은 컴파일되고 16777216을 저장합니다.

출력:

9 -9
10
2
4
705032704
9.99
7 7.0 7

기억할 것이 세 가지 있습니다. 부동소수점에서 정수로의 캐스트는 반올림하지 않고 잘라냅니다. Convert.ToInt32(double)은 은행가 반올림(.5는 짝수 쪽으로)으로 반올림합니다. 그리고 담기지 않는 정수 캐스트는 조용히 값이 돌아가며, checked 컨텍스트에서 실행될 때만 OverflowException을 던집니다(자료형 참고).

int x = 3.7;은 컴파일 오류(CS0266: cannot implicitly convert type 'double' to 'int', an explicit conversion exists)입니다. 컴파일러가 캐스트와 반올림 메서드 중 하나를 고르라고 요구하는 것입니다.

숫자와 다른 타입을 문자열로

모든 타입에는 ToString()이 있고, 숫자 타입은 서식 문자열을 받습니다. 문자열 보간도 같은 서식화를 호출합니다:

출력:

42
000042
1234.50
1,234.50
$1,234.50
FF
1010
True
Order 000042: 1234.50

서식 코드(D, F, N, C, X, P, E)와 "0.00" 같은 사용자 지정 패턴은 문자열 보간에서 다룹니다.

문자와 불리언

출력:

7
55
7
7
A
True
False
1
False

(int)'7'은 7이 아니라 문자의 코드인 55입니다. 숫자의 각 자리를 더하려는 사람이 자주 걸리는 부분이니 '0'을 빼거나 char.GetNumericValue를 쓰세요. bool.Parse는 대소문자와 상관없이 "true"와 "false"만 받고, 그 밖의 값("yes", "1")에는 예외를 던집니다.

참조 변환: 캐스트, as, is

클래스 타입의 경우 캐스트는 실행 시점에 객체의 실제 타입을 검사합니다. 기본 클래스로의 업캐스트는 암시적입니다. 파생 클래스로의 다운캐스트에는 명시적 캐스트가 필요하며, 객체가 다른 타입이면 InvalidCastException을 던집니다:

출력:

4242
True
Card ending 4242, 50.00
InvalidCastException
5
cannot unbox int as long

타입에 따라 분기해야 한다면 변수를 붙인 is를 우선 쓰세요. 검사가 한 번이고, 예외를 던질 수 없으며, 새 변수는 검사가 성공한 곳에서만 범위에 있습니다. 다른 타입이 오는 것이 요란하게 실패해야 할 버그라면 일반 캐스트를 쓰세요. 박싱된 int 사례는 object 컬렉션이나 DataRow 셀에서 숫자를 읽는 사람을 자주 괴롭힙니다. 먼저 정확한 타입으로 언박싱하거나((long)(int)boxed), 어떤 숫자 타입이든 처리하는 Convert.ToInt64(boxed)를 쓰세요.

자주 묻는 질문

C#에서 문자열을 int로 바꾸려면 어떻게 하나요?

텍스트가 사용자, 파일, 네트워크에서 온다면 int.TryParse(text, out int number)를 쓰세요. 텍스트가 올바른 숫자가 아니면 예외를 던지는 대신 false를 반환합니다. 잘못된 텍스트가 버그이고 예외가 올바른 반응이라면 int.Parse(text)를 쓰세요. Convert.ToInt32(text)는 null에 0을 반환한다는 점만 빼면 int.Parse와 같게 동작합니다.

int.Parse와 Convert.ToInt32의 차이는 무엇인가요?

문자열에 대해서는 거의 같습니다. 둘 다 "abc" 같은 텍스트에는 FormatException을, 범위를 벗어난 숫자에는 OverflowException을 던집니다. 차이는 null입니다. int.Parse(null)은 ArgumentNullException을 던지고, Convert.ToInt32(null)은 0을 반환합니다. Convert.ToInt32는 다른 타입(double, bool, object)도 받으며, double을 자르지 않고 가장 가까운 짝수 정수로 반올림합니다.

"Input string was not in a correct format"은 무슨 뜻인가요?

텍스트가 기대한 형식의 숫자가 아닐 때(문자, 빈 문자열, int를 파싱하는데 소수점이 있는 경우, 천 단위 구분 기호 등) int.Parse, double.Parse, Convert.ToInt32가 던지는 FormatException의 메시지입니다(.NET 8 이상에서는 텍스트를 인용해 "The input string 'abc' was not in a correct format"이라고 표시됩니다). 예외 없이 잘못된 입력을 처리하려면 TryParse로 바꾸고, 숫자가 어떤 문화권 형식으로 쓰였는지 확인하세요.

C#에서 double을 int로 캐스트하려면 어떻게 하나요?

명시적 캐스트를 씁니다: int n = (int)price;. 캐스트는 0 방향으로 자르므로 (int)9.99는 9이고 (int)-9.99는 -9입니다. 반올림하려면 (int)Math.Round(price)를 쓰세요. Math.Round는 기본적으로 .5를 가장 가까운 짝수로 반올림하므로, 학교에서 배운 반올림을 원하면 MidpointRounding.AwayFromZero를 넘기세요.

C#에서 as와 캐스트의 차이는 무엇인가요?

캐스트 (Dog)animal은 객체가 Dog가 아니면 InvalidCastException을 던집니다. animal as Dog는 대신 null을 반환하므로 뒤에 null 검사가 필요하며, 참조 형식과 nullable 형식에만 쓸 수 있습니다. 최신 대안은 is 패턴입니다: if (animal is Dog dog) { ... }는 검사와 변환을 한 번에 합니다.

Coddy programming languages illustration

Coddy로 코딩 배우기

시작하기