사전캠프/걷기반

걷기반 Lv.2 본격 프로그래밍 시작해보기

서보훈 2024. 8. 16. 15:50

1. 입력받은 데이터가 숫자인지 문자열인지 판단

캐스팅의 TryParse 를 응용하여 만들 수 있습니다.

  • 입력받은 데이터가 숫자 - “숫자입니다.”
  • 아니라면 - “문자열입니다.”

 

TryParse를 사용하여 입력된 문자열이 숫자(정수형) 인지, 문자열인지 판단하는 코드를 작성하는 문제입니다.

1번과 2번 공통으로 TryParse의 사용을 유도하고 있으며, 함수가 어떤 역할을 하는지 알아보도록 하겠습니다.

 

TryParse문의 정의를 확인해보도록 하겠습니다. 원하는 함수에 드래그를 한 후, 우클릭을 통해 해당 함수가 정의된 스크립트로 넘어갈 수 있습니다.

System 네임스페이스의 Int32 스크립트의 TryParse 함수로 넘어온 모습입니다.

TryParse 함수만 5개가 정의되어 있는데, 이는 함수 오버로드 기능으로, 같은 이름의 함수라도 매개변수를 어떤것을 전달받는지에 따라 다르게 작동하도록 여러개의 함수를 정의하는 방식입니다.

 

또한 자세히보면, 화살표 함수를 통해 마지막 2개의 TryParse 함수중 하나로 함수를 넘기는것을 볼 수 있습니다.

public static bool TryParse([NotNullWhen(true)] string? s, NumberStyles style, IFormatProvider? provider, out int result)
{
    NumberFormatInfo.ValidateParseStyleInteger(style);

    if (s is null)
    {
        result = 0;
        return false;
    }
    return Number.TryParseBinaryInteger(s.AsSpan(), style, NumberFormatInfo.GetInstance(provider), out result) == Number.ParsingStatus.OK;
}
public static bool TryParse(ReadOnlySpan<char> s, NumberStyles style, IFormatProvider? provider, out int result)
{
    NumberFormatInfo.ValidateParseStyleInteger(style);
    return Number.TryParseBinaryInteger(s, style, NumberFormatInfo.GetInstance(provider), out result) == Number.ParsingStatus.OK;
}

두개의 함수도 보기엔 굉장히 복잡해 보입니다.

하지만 지금 알아야할것은 단 2가지로, 함수의 반환값과 마지막 매개변수 out int result 입니다.

 

bool isInt = int.TryParse(input, out number);

실제로 우리가 사용할 TryParse는 이런 형태인데 이는

public static bool TryParse([NotNullWhen(true)] string? s, out int result) => TryParse(s, NumberStyles.Integer, provider: null, out result);

이 함수로 들어가서, 비어있는 나머지 매개변수를 기본값으로 다시 채워서 오버로딩된 TryParse 함수로 넘겨주는것 입니다.

 

모든 함수의 반환값은 bool 으로 선언되어 있기 때문에, 해당 함수를 사용하면 true와 false만 반환받게 됩니다.

if (s is null)
    {
        result = 0;
        return false;
    }

이 구문을 보시면 입력된 string 값이 비어있으면( = null 값이 입력되면) result에 0을 저장하고, false를 반환합니다.

여기서 result 값이 TrtParse 함수에 적는 out 값, 즉 함수에서 매개변수로 받아간 정수형 변수에 0을 저장하도록 만들어줍니다.

out 구문의 경우, 하나의 함수에서 2개 이상의 값을 반환해야하는 경우, 유용하게 사용할 수 있습니다.

 

※out 키워드에 관한 마이크로소프트 공식 문서

https://learn.microsoft.com/ko-kr/dotnet/csharp/language-reference/keywords/out

 

out 키워드 - C# reference

out 키워드 - C# 참조

learn.microsoft.com

 

bool isInt = int.TryParse(input, out number);

즉, 이 구문은 input 변수를 입력해서 해당 변수가 정수형인지 아닌지를 판단해 isInt에 ture, false를 저장하고,

추가로 값이 true일 경우 number 변수에 변환된 정수값을 저장하고 false면 0을 저장하라는 명령이 됩니다.

 

문제를 완성해보도록 하겠습니다.

{
    //데이터 읽기, Write를 사용해 이 부분에 입력하도록 유도
    Console.Write("Input Data : ");
    //입력이 완료되면 줄바꾸기
    string input = Console.ReadLine();

    //out을 받아줄 정수형 변수
    int number;
    bool isInt = int.TryParse(input, out number);

    if (isInt)
    {
        Console.WriteLine($"숫자입니다.");
    }
    else
    {
        Console.WriteLine($"문자열입니다.");
    }
}

 

 

isInt는 true, false만 저장되는 bool 형 변수이기 때문에, 이를 직접 if문에 넣을경우 true가 저장되어있으면 if를, false가 저장되어 있으면 else를 실행하게 됩니다.

여기서 number변수에 어떤값이 저장되어있는지 표기하도록 바꿔보겠습니다.

{
    //데이터 읽기, Write를 사용해 이 부분에 입력하도록 유도
    Console.Write("Input Data : ");
    //입력이 완료되면 줄바꾸기
    string input = Console.ReadLine();

    //out을 받아줄 정수형 변수
    int number;
    bool isInt = int.TryParse(input, out number);

    if (isInt)
    {
        Console.WriteLine($"숫자입니다. 저장된 number변수 값 : {number}");
    }
    else
    {
        Console.WriteLine($"문자열입니다. 저장된 number변수 값 : {number}");
    }
}

정수형 값을 입력한경우, number 변수에 1이 저장된것을 볼 수 있고, 문자열을 입력한경우 0이 저장된것을 볼 수 있습니다.

 

정의에서 false값을 반환할때, result에 0을 반환하도록 되어있기 때문에 변환에 실패하면 0값을 반환하고, 성공하면 변환된 값을 반환하게 됩니다.


2. 입력받은 데이터가 숫자인지 문자열인지 불리언인지 판단

입력받은 데이터에 맞게 출력하는 프로그램 만들기

  • 숫자면 “숫자입니다.
  • true, false 면 “불리언 입니다.”
  • 아니라면 “문자열입니다.”

 

true,false가 입력되면 bool 형태로 판단하여 또다른 답을 반환하는 프로그램을 작성해야합니다.

원리는 위와 마찬가지로, int.TryParse와, bool.TryParse 2가지 형태를 사용합니다.

 

마찬가지로 변수에 어떤 값이 저장되었는지를 확인하며 결과를 보도록 하겠습니다.

{
    //데이터 읽기, Write를 사용해 이 부분에 입력하도록 유도
    Console.Write("Input Data : ");
    //입력이 완료되면 줄바꾸기
    string input = Console.ReadLine();

    //out을 받아줄 정수형 변수
    int number;
    bool isInt = int.TryParse(input, out number);

    //out을 받아줄 불리형 변수
    bool boolean;
    bool isBool = bool.TryParse(input, out boolean);


    if (isInt)
    {
        Console.WriteLine($"숫자입니다. 저장된 number변수 값 : {number}, 저장된 boolean변수 값 : {boolean}");
    }
    else if (isBool)
    {
        Console.WriteLine($"불리언 입니다. 저장된 boolean변수 값 : {boolean}, 저장된 number변수 값 : {number}");
    }
    else
    {
        Console.WriteLine($"문자열입니다. 저장된 number변수 값 : {number}, 저장된 boolean변수 값 : {boolean}");
    }
}

if, else if, else 를 사용하였습니다.

if문을 실행하기 전, 2가지 변환을 모두 시도한 뒤, 변수에 결과를 저장하고 정수형이 아닐경우 불리언 형태인지 확인, 불리언이 아닐경우 문자열입니다를 출력하는 형태입니다.

 

결과를 보도록 하겠습니다.

bool 형태가 아닌 값이 들어올경우,boolean 변수에 기본값으로 false가 입력되는것을 볼 수 있습니다.

또한 true를 입력할경우, boolean 변수에 true값이 저장됩니다.

false를 입력한경우, 불리언으로 판단함과 동시에 boolean에 false값이 저장되는것을 볼 수 있습니다.

 


3. 입력받은 데이터가 숫자라면 100 보다 큰지 작은지 알려주는 프로그램 만들기

  • 입력받은 데이터가 문자라면 - “숫자가 아닙니다.”
  • 입력받은 데이터가 숫자라면
    • 수가 100 이상이라면 크다면 “xx 은(는) 100 보다 같거나 큰 수 입니다.”
    • 수가 100 보다 작다면 “xx 은(는) 100 보다 작은 수 입니다.”

입력받은 데이터의 형태를 판단해서, 숫자면 100보다 큰지 작은지, 아니면 숫자가 아니라고 출력하는 형태 입니다.

out을 통해 저장한 int형 변수를 사용하고, 2중 if문을 물어보는 문제입니다.

 

if문을 다중으로 사용할경우, 여러개의 조건을 만족하는 경우에만 원하는 코드가 작동하도록 만들 수 있습니다.

해당 문제의 경우 정수형 변환이 가능한 문자열이, 100보다 큰지 작은지, 2개의 조건을 만족하는지를 물어보는 형태 입니다.

 

문제를 완성해보겠습니다.

{
    //데이터 읽기
    Console.Write("숫자를 입력해주세요 : ");
    string input = Console.ReadLine();

    //out을 받아줄 정수형 변수
    int number;
    bool isInt = int.TryParse(input, out number);

    //if문, 정수형인지 아닌지
    if (isInt)
    {
        //2중 if문, 정수형일경우, 100보다 큰지 작은지
        if (number >= 100)
        {
            Console.WriteLine($"{number} 은(는) 100보다 같거나, 큰 수 입니다.");
        }
        else
        {
            Console.WriteLine($"{number} 은(는) 100 보다 작은 수 입니다.");
        }
    }
    else
    {
        //정수형이 아니면
        Console.WriteLine("숫자가 아닙니다.");
    }
}

총 3개의 결과물을 확인할 수 있습니다.

단 다중if문을 너무 많이 사용할경우, 코드가 복잡해지며 읽기 힘들어지는 즉, 유지보수가 어려운 코드가 될 가능성이 높아집니다.


4. 입력받은 데이터가 숫자라면 짝수인지 홀수인지 알려주는 프로그램 만들기

  • 입력받은 데이터가 문자라면 - “숫자가 아닙니다.”
  • 입력받은 데이터가 숫자라면
    • 수가 짝수라면 - “xx 은(는) 짝수 입니다.”
    • 수가 홀수라면 - “xx 은(는) 홀수 입니다.”
    • 짝수를 어떻게 구하는지 모르겠다면 Tip!
    • 숫자를 2로 나누었을때 나머지가 0이라면 짝수입니다. 산술 연산을 응용해 보세요.

 

3번과 비슷한 문제이지만, 홀수, 짝수를 구분하는 연산이 추가되었습니다.

기본 베이스는 같지만, 정수형인지 확인하는 if문이 true일경우, 여기서 짝수, 홀수를 구분하는 연산을 한 후 if문을 사용해 결과를 출력해야합니다.

 

홀수, 짝수는 해당 수를 2로 나누었을때 나누어떨어지면 짝수, 아니면 홀수입니다.

% 연산기호를 사용하면 나머지연산을 해주기 때문에, number 변수를 % 2 연산하여 나온 결과값을 저장해 해당값이 0이면 짝수, 0이 아니면 홀수로 판단해주면 됩니다.

 

문제를 완성해보도록 하겠습니다.

{
    //데이터 읽기
    Console.Write("숫자를 입력해주세요 : ");
    string input = Console.ReadLine();

    //out을 받아줄 정수형 변수
    int number;
    bool isInt = int.TryParse(input, out number);

    //if문, 정수형인지 아닌지
    if (isInt)
    {
        //나머지연산, 0이면 짝수, 1이면 홀수
        int moduloNum = number % 2;
        if (moduloNum == 0)
        {
            Console.WriteLine($"{number} 은(는) 짝수입니다..");
        }
        else
        {
            Console.WriteLine($"{number} 은(는) 홀수입니다.");
        }
    }
    else
    {
        //정수형이 아니면
        Console.WriteLine("숫자가 아닙니다.");
    }
}

 

만약, int moduloNum = number % 2; 연산을 첫번째 if문 밖에서 진행할경우, 문자열이 입력되면 굳이 할 필요가 없는 연산을 진행하게 됩니다. (TryParse 실패시, 0이 저장되어 0 % 2 연산을 진행하게됨)

지금은 큰 연산값이 아니기때문에 성능에 중대한 영향을 끼치지 않지만, 최적화를 위해 쓸데없는 연산을 진행하는 경우를 최대한 피하는것이 좋습니다.

결과값 입니다.


5. 언제 if 를 쓰고 언제 case 를 쓸까요?

한가지 문제에 관하여, 예와 아니오로 대답을 나눌 수 있으면 if문을 사용하게 됩니다.

if문의 and, or 연산의 경우에도 각각의 질문이 예와 아니오 단 2개로 나누어지기 때문에 if문을 사용할 수 있게됩니다.

 

하지만 답이 객관식처럼, 여러개로 나누어져 각각 결과가 다르다면 case 문을 사용하는것이 효과적입니다.

if (num == 1)
else if ( num == 2)
else

 

물론 이러한 형태로 사용할 수 있지만, 이 방법은 코드가 복잡해 보이는 문제를 만들 수 있습니다.

 

또한 case문의 경우 break를 사용하지 않으면, 해당 case문을 실행한 후, 다음 case문을 실행하게 됩니다.