[Swift 공부] 1. Swift I/O, Xcode에서 input 받기

김나경·2020년 12월 27일
3

iOS 공부

목록 보기
3/3

언어공부는 코딩테스트 문제를 풀면서 Swift 공식문서를 참고하여 그때그때 정리하는 방식으로 진행한다.

모든 문제에서 공통으로 수행해야하는 입력/출력을 먼저 다룬다.

1. 출력 Print()

Declaration

func print(_ items: Any..., separator: String = " ", terminator: String = "\n")

Parameters

items : 여러 개의 파라미터를 넣을 수 있음
separator : items가 2개 이상일 때 item 사이마다 출력할 것. 디폴트 값은 스페이스.
terminator : items를 모두 출력한 후 마지막에 붙이는 종결자. 디폴트 값은 개행('\n'). 즉 print()는 자동개행을 해줌.

Basic Usage

1)

print("Hello, World!",2021,"See you soon")
print("I Love Swift.")

2) separator, terminator을 명시

print("Hello, World!","Bye Covid19!",separator:". ", terminator:" ")
print("I Love Swift.")

3) 문자열 보간(String Interpolation) : \(변수명)

let hi = "하이" // let은 상수란 의미. swift에서 type는 inferring(추론)됨
print("상수 hi의 값은 \(hi).")



2. 입력 readLine()

입력을 하기 전에, playground는 sandbox이기 때문에 commandline input에 접근할 수 없다. 따라서 playground 가 아니라 project를 Command Line Tool로 해서 만들어줘야한다.

이렇게 swift 파일이 생기면 완료

Declaration

func readLine(strippingNewline: Bool = true) -> String?

Parameters

strippingNewline : true라면 개행문자와 문자조합이 결과에서 제거된다. false면 개행문자 또는 문자조합이 유지된다. 기본값은 true.

Return Value

String? (Optional String) 값을 반환. 만약 readLine()이 불리기 전에 EOF에 도달하면 결과는 nil

Swift에서 nil : 특정 타입에 대한 값의 부재, Optional은 값을 가질 수도, nil일 수도 있음을 나타냄.

Basic Usage

1)

print("Please Enter your favorite programming language",terminator:" : ")
let name = readLine()
print("Your favorite programming language is \(name).")

여기서 코드 마지막 줄 문자열보간이 들어간 부분이 컴파일된 결과를 보면 Optional("")이 생기고,
Xcode 상에서도 이러한 경고가 뜨는데, 이는 readLine()의 리턴값이 Optional이기 때문이다. 이런 상황에선 뒤에 '!'를 넣어 강제로 언래핑하는 방법도 있지만 런타임 에러 트리거라며 권고하지 않는 방법이다. (즉, 개발자 차원에서 이 변수엔 값이 무조건 들었다 확신할 때 사용.) 그래서 Optional Binding을 하면 된다.

if let (Optional Binding) 처리
새로운 상수(let)를 만들어 판별(if) 출력한다

print("Please Enter your favorite programming language",terminator:" : ")
let name = readLine()
if let optionalBinding = name{
    print("Your favorite programming language is \(optionalBinding).")
}

한글은 readLine() 했더니 커맨드라인에서 한글 자모음 분리현상이 일어난다. 알아봐도 별 상관없는 내용이 많아서 천천히 알아봐야겠다.


3. 문제 적용

자바로 네이버 블로그에 한번 정리했던 내용.
우선 코딩테스트 문제의 입력 유형을 보면 크게 다음과 같다.

  • 첫 줄에 숫자의 개수 N, 둘째 줄부터 줄바꿈하며 N개의 숫자
ex) 
3	// N
1
8
2
  • 첫 줄에 숫자의 개수 N, 둘째 줄에 띄워쓰기없이 N개의 숫자
ex) 
3	// N
182
  • 첫 줄에 숫자의 개수 N, 둘째 줄에 띄워쓰기하며 N개의 숫자
ex) 
3	// N
1 8 2

큰 틀은 결국 첫 줄의 값 N을 받아 해당 크기만큼 배열을 만들고 다음에 오는 숫자들을 적절한 방법으로 배열에 하나씩 집어넣으면 되는 것. 두번째는 한자릿수만 입력할 수 있는 한계도 있고, 보통 세번째가 제일 많다.
좀더 응용한다면 첫 줄에 N, M을 받아 2차원 배열을 만드는 것 정도..

따라서 첫 번째, 세 번째 유형에 대해 swift로 코드를 짜보았다.


  • 첫 줄에 숫자의 개수 N, 둘째 줄부터 줄바꿈하며 N개의 숫자
///// 입력 /////
var array = [Int]()
if let N = readLine(){
    for _ in 1 ... Int(N)!{
        if let item = readLine(){
            array.append(Int(item)!)
        }
    }
}
///// 출력 /////
for num in array{
    print(num, terminator: " ")
}
print()


  • 첫 줄에 숫자의 개수 N, 둘째 줄에 띄워쓰기하며 N개의 숫자

방법 1) components

Foundation에 포함된 instance method이기 때문에 import Foundation 필수.
단 : 용량 추가됨 / 장 : [String]으로 리턴해서 바로 사용하기 쉬움

import Foundation
///// 입력 /////
var array = [String]()
if readLine() != nil{
    if let items = readLine(){
        array = items.components(separatedBy: " ")
    }
}
///// 출력 /////
for num in array{
    print(num, terminator: " ")
}
print()

방법 2) splits

import가 필요없는 기본 method.
단 : [String.SubSequence]를 리턴해서 map으로 처리를 해주어야 함 / 장 : import할 필요가 없어 용량 적음

///// 입력 /////
var array = [String]()
if readLine() != nil{
    if let items = readLine(){
        array = items.split(separator: " ").map{(value) -> String in return String(value)}
    }
}
///// 출력 /////
for num in array{
    print(num, terminator: " ")
}
print()


Swift에선 사실 배열 크기를 지정해주지 않아도 append 하면서 사용할 수 있어서 실상 첫 째줄 N이 거의 필요없는 듯 하다.

그리고 코딩테스트를 겸해서 언어를 배우는 거라 if let (optional binding)을 나름 성실하게 붙여줬지만, 실제 코테에서는

let N = readLine()!

이렇게 강제 언래핑하는게 빨리 작성할 수 있고 좋을 듯하다.

볼수록 코틀린이랑 유사한 점이 많은거 같다. 오늘은 끝~~

profile
develog

1개의 댓글

comment-user-thumbnail
2021년 8월 16일

잘 보고 갑니다.

답글 달기