표준 입출력

GoLang의 표준 입출력은 다른 언어와 같이 터미널이 기본이며, 파일등으로 수정이 가능하고 fmt패키지에서 제공을 한다.

입출력은 BitStream형태로 되어있다.


표준 출력

◾ 함수

함수 기능
Print() 입력값들을 출력
Println() 마지막에 개행문자를 포함한 입력값들을 출력
Printf() c의 printf와 같이 특정 포맷에 맞게 출력


◾ 포맷 서식

포맷형태 설명
%d 정수
%f 실수(소수점 6자리까지 표현)
%v 기본형태(자동으로 맞는 값으로 변경)
%g 길이에 맞는 실수형태로 변경해서 출력(%v로 사용시 실수의 경우 %g로 바뀜)
%3d 3자리 칸에 맞춰 오른쪽 정렬해 출력
%03d 3자리 칸에 맞춰 출력하는데 빈칸을 0으로 채움
%-3d 3자리 칸에 맞춰 왼쪽정렬해 출력
package main

import fmt

func main(){
  a := 1
  b := 0.5
  c := 123456789

  fmt.Println(a+c)
  fmt.Prnit(b)
  fmt.Printf("%3d, %03d, %-3f\n",a,b,c)
}



표준 입력

◾ 함수

함수명 기능
Scan() 표준 입력(키보드)에서 공백과 개행을 기준으로 값을 입력
Scanf() 특정 포맷형태에 맞게 값을 입력
Scanln() 표준 입력에서 공백을 기준으로 값을 입력

Scan()과 Scanln() 차이점 : Scan()은 공백,개행을 기준으로 값을 나눠 입력받고, Scanln()은 공백을 기준으로 값을 나눠 입력받는다.

package main

import fmt

func main(){
  var a int
  var b int
  var c int

  n, err := fmt.Scanln(&a, &b, &c)
  if err != nil {
    fmt.Printlnf(err)
  }else{
    fmt.Println(n,a,b,c)
  }
}

fmt의 입력함수 인자값으로 C처럼 변수의 메모리 주소를 주어야 하며, 반환 값으로는 두개가 있는데 첫번째가 입력받은 값의 개수이고 두번째는 err메세지이다. 따라서 위처럼 error처리를 해줄 수 있다.

표준 입력장치(키보드)로부터 입력받아 쌓인 데이터는 버퍼에 저장이 되며 버퍼의 값을 입력함수를 통해 읽어오는 방식으로 동작을 하는데, 중간에 error가 발생했거나 개행문자가 남아있거나 하는등의 문제가 발생하는 경우가 존재한다. 이때 버퍼를 비워주어야 하는데 이는 아래와 같이 bufio 패키지를 추가하여 접근할 수 있다.

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	stdin := bufio.NewReader(os.Stdin)    // 표준 입력

	var a int
	var b int
	var c int

	n, err := fmt.Scanln(&a, &b, &c)
	if err != nil {
		fmt.Println(err)
		stdin.ReadString('\n') // 표준입력을 통해 개행문자가 올때까지 읽는 것이기 때문에 에러 발생시 버퍼를 비울 수 있다.
	} else {
		fmt.Println(n, a, b,c)
	}
}


위와 같이 기본 Scan함수들을 사용하면 문자열은 무조건 공백으로 구분을 하기 때문에 한줄씩 읽을 수가 없는데 개행으로 구분하고 싶다면 위와 비슷하게 구성하면 된다.

//개행을 구분으로 문자열 입력
import (
    "fmt"
    "bufio"
    "os"
)

func main() {

  //Reader이용
    in := bufio.NewReader(os.Stdin)
    line, _ := in.ReadString('\n')

    strings.TrimSuffix(line,"\n")
    fmt.Println(line)

  //Scanner 이용
    sc := bufio.NewScanner(os.Stdin)
    sc.Scan() //한줄 읽기
    str := sc.Text() //읽은 문자열을 변수에 할당

  //여러줄의 문자열 읽기
    for sc.Scan(){
      fmt.Println(sc.Text())
    }
}

ReadString()으로 읽은 string은 구분문자(delimeter)를 포함하여 반환하기 때문에 마지막에 \n을 제거하고 싶다면 한줄을 추가해주어야 한다.

Scanner의 Scan()은 delimeter가 제거된 문자열을 반환해주기 때문에 조금더 편하게 사용할 수 있다. NewReader에는 ReadByte,ReadBytes등의 저수준의 데이터를 읽어올 수 있는 함수가 있기 때문에 상황에 맞게 사용하면 된다.



추가 내용

◾ go run

실행파일을 만들지 않고 스크립트형태로 그냥 바로 실행시키는 명령어

◾ go build

컴파일을 통해 실행 파일을 만드는 명령어

◾ 패키지와 모듈

패키지와 모듈은 다른 개념이다.

모듈은 데이터,함수,구조체 등이 담겨져있는 파일 하나하나이고 패키지는 연관된 모듈들의 집합이다.

예를 들어 main이라는 패키지에서도 표준 입출력을 위해 fmt모듈과 bufio, os 모듈을 사용한 것과 같다.





Reference

『Tucker의 Go 언어 프로그래밍』 스터디 요약 노트