업무에 사용하는 Go 언어 3 – 입출력

Go 언어에서 입력과 출력을 다루는 방법을 알아보고 fmt 패키지를 사용해보도록 합시다.

필자의 경우 Go 언어로 업무를 진행하면서 데이터를 저장할 때 데이터베이스에 저장했기 때문에 파일 입출력을 거의 사용하지 않았던 것 같습니다.
본 시리즈에서 파일 입출력은 아예 포함하지 않을까 생각했지만 간단하게 다루어보도록 하겠습니다.

입출력은 기본적으로 프로그램과 사용자가 대화를 한다고 생각하면 됩니다.
어떤 방식으로 출력할 것인지, 어떤 방식으로 입력할 것인지 미리 약속을 정해두고 그 형식에 맞게 대화를 하는 것이지요.

업무에 사용하는 Go 언어 썸네일
업무에 사용하는 Go 언어 썸네일

Go 언어 화면 입출력

기본적으로 화면을 통해 입력과 출력을 다루어보도록 합시다.
Go 언어 화면 출력 혹은 입력은 fmt 패키지를 주로 사용하여 처리합니다.

약간의 여담

fmt는 format의 줄임말이다.
https://pkg.go.dev/fmt 이 주소에 들어가면 fmt 패키지에서 제공하는 많은 기능을 전부 확인할 수 있다.
필자의 경우에는 업무에서 이 기능을 모두 사용해야 하는 경우는 없었다.
관심이 있는 사람이라면 해당 링크를 통해 살펴볼 가치는 존재한다.
엔지니어라면 분명 이런 관심이 있을 것이다.

이번 학습을 위해 우리가 만들었던 프로젝트에 input, output을 줄여서 io.go라는 파일을 만들고 진행하도록 하겠습니다.

fmt 패키지를 이용한 출력

Go 언어 화면 출력에서 사용되는 기본적인 함수는 Println과 Printf입니다.

  • Println
    • 문자열을 출력한 후 자동으로 줄바꿈을 출력한다.
  • Printf
    • 형식이 정해진 문자열을 사용하여 다양한 타입의 값을 출력할 수 있다.

다음 예시와 같이 직접 사용해보도록 합시다.

출력 예시
Go 언어 출력 예시

fmt 패키지를 이용한 코드를 보면 다른 프로그래밍 언어와 굉장히 유사합니다.
위와 같이 형식을 정해서 사용해도 되고 직접 변수를 사용하여 출력이 가능합니다.

출력 예시
Go 언어 화면 출력 예시

Print 함수를 사용하여 직접 변수를 사용하여 출력을 한 예시입니다.
필자의 경우 Printf를 더 선호합니다.

fmt 패키지는 출력에 있어서 굉장히 다양한 포맷 지정자를 제공합니다.
이에 대한 목록은 다음과 같습니다.

기본 데이터 타입

  • %v: 값(value)의 기본 형식으로 출력
  • %+v: 구조체의 필드 이름과 값을 함께 출력
  • %#v: 값의 Go 문법을 따라 출력 (Go 소스 코드 형식)
  • %T: 값의 타입(type)을 출력
  • %%: % 자체를 출력

정수 (Integers)

  • %d: 10진수(decimal) 정수로 출력
  • %b: 2진수(binary) 정수로 출력
  • %o: 8진수(octal) 정수로 출력
  • %x: 16진수(hexadecimal, 소문자) 정수로 출력
  • %X: 16진수(hexadecimal, 대문자) 정수로 출력
  • %c: 유니코드 값에 해당하는 문자 출력

부동소수점 수 (Floating-Point Numbers)

  • %f: 소수점 이하 고정된 자릿수로 출력 (기본 6자리)
  • %e: 지수 표기법(exponential notation, 소문자 e)으로 출력 (예: 1.234000e+05)
  • %E: 지수 표기법(exponential notation, 대문자 E)으로 출력 (예: 1.234000E+05)
  • %g: 유효 자릿수에 따라 %f 또는 %e 중 더 적절한 형식으로 출력
  • %G: 유효 자릿수에 따라 %f 또는 %E 중 더 적절한 형식으로 출력

문자열 및 문자 (Strings and Characters)

  • %s: 문자열(string)을 그대로 출력
  • %q: 이스케이프 문자 포함하여 문자열을 큰따옴표로 묶어 출력
  • %x: 문자열을 16진수로 출력 (각 바이트를 두 자리 16진수로)
  • %X: 문자열을 대문자 16진수로 출력

포인터 (Pointers)

  • %p: 포인터의 메모리 주소를 출력

Boolean

  • %t: true 또는 false 값을 출력

너비와 정밀도 (Width and Precision)

  • %10s: 문자열을 10칸 너비로 출력 (오른쪽 정렬)
  • %-10s: 문자열을 10칸 너비로 출력 (왼쪽 정렬)
  • %.2f: 부동소수점 수를 소수점 아래 2자리까지 출력
format specifiers 예시
Go 언어 format specifiers 예시

예시와 같이 꼭 사용해보시길 바랍니다.

fmt 패키지 입력

입력은 사용자로부터 값을 받는다는 것만 다른 점이며 출력과 거의 동일합니다.

  • Scanln
    • 공백을 기준으로 여러 값을 입력받고, 줄바꿈으로 입력을 종료한다.

출력에 있어서 Hello, World를 출력하는 것이 기본인 것처럼
입력에 있어서 Hello, World인 이름과 나이를 입력받고 값을 변수에 저장하여 다시 출력하는 코드를 작성해봅시다.

입력 예시

코드를 살펴보면 이름은 string 타입으로, 나이는 int 타입으로 받아들여야 한다는 약속을 정한 것입니다.
그럼 만약 나이에 문자열을 입력하게 되면 어떻게 될까요? 직접 시도해보고 경험해보도록 합시다.

Go 언어 파일 입출력

서론의 바와 같이 파일 입출력에 대한 내용은 간단한 프로그램을 만들어보면서 익혀보도록 합시다.

Go
package main

import (
	"fmt"
	"io"
	"log"
	"os"
)

func main() {
	// 파일 열기
	srcFile, err := os.Open("example.txt")
	if err != nil {
		log.Fatalf("파일을 열 수 없습니다: %v", err)
	}
	defer srcFile.Close()

	// 파일 내용 읽기
	content, err := io.ReadAll(srcFile)
	if err != nil {
		log.Fatalf("파일을 읽는 중 오류가 발생했습니다: %v", err)
	}

	// 파일 내용을 화면에 출력
	fmt.Println("파일 내용:")
	fmt.Println(string(content))

	// 복사를 위해 다시 파일 열기
	srcFile.Seek(0, io.SeekStart)

	// 파일 생성
	destFile, err := os.Create("example2.txt")
	if err != nil {
		log.Fatalf("파일을 생성할 수 없습니다: %v", err)
	}
	defer destFile.Close()

	// 파일 복사
	_, err = io.Copy(destFile, srcFile)
	if err != nil {
		log.Fatalf("파일 복사 중 오류가 발생했습니다: %v", err)
	}

	log.Println("파일 복사가 완료되었습니다.")
}
파일 입출력 예시
Go 언어 파일 입출력 실행 예시

io 패키지를 사용하여 example.txt 파일의 내용을 읽어서 example2.txt 파일을 생성하여 내용을 복사하는 코드입니다.
보통은 for문을 통해 무한루프를 돌려서 파일의 내용이 끝날 때까지 일정 바이트만큼 계속 읽는 방식을 사용합니다.
하지만, 우리는 아직 for문을 학습하지 않았기 때문에 시리즈 순서를 감안하여 io 패키지의 ReadAll 함수를 사용했습니다.

직접 사용해보시고 경험해봅시다.

이번 글을 통해 Go 언어로 입출력을 처리하는 방법을 알아봤습니다.
앞으로의 내용은 연산자에 대해 알아보겠습니다.