c# 초보 ConsoleKey를 사용하여 x,y 좌표 값 설정 질문 드립니다.

안녕하세요 선배님들 c# 반복문 까지 익힌 초보 프로그래머 입니다.
다름이 아니라 c언어를 배웠을 때 x, y 좌표를 입력하면 해당하는 좌표에 오목 돌을
올려두는 프로젝트를 진행했었습니다.

요번에 배우는 c# 또한 위와 같은 방식으로 오목판을 제작해 볼까 하는데

Console.WrithLine("X, Y ?");
string num = Console.ReadLine();

>>  X,Y ?  12 8

위 방식으로 X와 Y 좌표값을 설정하고 싶었으나 12와 8의 사이의 공백으로 인해 int.Parse(num) 써도 값이 출력되지 않습니다…
찾아 보니 문자열 분리 메서드를 사용하면 되지만 현재 까지 배운 내용을 토대로 만들어 보고 싶기 때문에 사용하지 않았습니다.

그래서 생각한 것이 ConsoleKey.Spacebar를 사용하여 12를 입력하고 스페이스바를 입력하면 12값만 먼저 출력하고 나머지 8의 값은 따로 출력하게 만들어
x좌표와 y좌표를 설정하고 싶은데 도저히 감이 잡히지 않아 선배님들께 도움 요청을 드립니다…

3개의 좋아요

원하는 동작을 하는 기능은 Console에서 제공하지 않아요. Console.ReadKey()를 이용해 직접 구현해야 해요.

C#에서 일반적으로 사용하는 방법는 Console.ReadLine()을 이용해 문자열을 입력 받고 이것을 정규식으로 처리하거나 문자열 Split()을 이용합니다.

3개의 좋아요

다음의 코드처럼 원하는 결과를 얻을 수 있습니다.
(ConsoleKey.Spacebar를 이용해서 처리하는 방법은 Console.ReadKey()를 이용해 구현해야 해서 처리가 좀 더 복잡할 것 같습니다.)

| 소스코드 (.NET 6, C# 10 이용)

Console.Write("X, Y ? ");
var input = Console.ReadLine();

// 구분자를 이용하는 방법
var values = input!.Split(new[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
    .Select(x =>
    {
        var bResult = int.TryParse(x, out var value);
        return (Result: bResult, Value: value);
    }).ToArray();

if (values.Length >= 2)
{
    Console.WriteLine($"X: {values[0]}, Y: {values[1]}");
}

| 결과

X, Y ? 12 8
X: (True, 12), Y: (True, 8)

입력된 값이 정수가 아닐 수 있어서 관련된 처리를 하였습니다.

코드가 좀 복잡해 보일수도 있지만 하나하나 살펴보면,

input!.Split(new { ’ ', ‘,’ }, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)

문자열을 구분자로 나눠줍니다. 여기서는 ’ '(스페이스) 와 ‘,’(컴마)를 구분자로 사용하였습니다.
옵션을 붙였는데, StringSplitOptions.RemoveEmptyEntries 옵션은 빈값을 제거, 예를 들어
‘5,4,’ 라고 입력 했을 경우 마지막 ''빈 문자열을 제거해 줍니다.
StringSplitOptions.TrimEntries 옵션은 분리된 문자열을 트림 (공백제거) 합니다.

.Select(x =>

LINQ 메소드인데 분리된 문자열을 숫자로 변환하기 위함입니다. Select()에 의해 원자(분리된 개별 문자열)를 순회하며 숫자로 변환해 줍니다.

var bResult = int.TryParse(x, out var value);
return (Result: bResult, Value: value);

순회하는 문자열을 int.TryParse()해서 숫자로 변환하는데 변환에 실패한 것도 확인할 수 있도록 (Result, Value) 형태의 튜플로 반환합니다.

}).ToArray();

Select()의 반환값은 IEnumerable<string>이므로 인덱스로 접근할 수 있도록 배열로 변환합니다.

이 코드를 이해하기 위해서는 다음의 사전 지식이 필요합니다.

  • string.Split() 메소드 이해
  • Select() LINQ 메소드 이해
  • ValueTuple 예) (Result: bResult, Value: value) 이해
4개의 좋아요

혹시나 스페이스바가 아닌 엔터를 통해 X와 Y를 따로따로 받으시면 문제가 될까요?

Console.WrithLine("PLEASE ENTER THE X, Y");
Console.WrithLine("X ?");
string numX = Console.ReadLine();
Console.WrithLine("Y ?");
string numY = Console.ReadLine();

>>  X,Y ?  12 8

위와 같이 구성한다면 X와 Y를 따로 받아서 따로 출력도 가능할것으로 보입니다.

흠… 근데 이게 아니라 스페이스바를 이용해서 구분하셔야 한다면 @dimohy 님 말씀대로 Split 메소드에 대해서 공부하셔서 사용하셔도 될거같습니다.

3개의 좋아요