독하게 시작하는 JAVA part1-섹션 08

2024. 12. 13. 15:28언어들/자바

728x90
반응형

콘솔 입/출력

콘솔, 터미널, 셸의 차이점

콘솔

  • 콘솔은 컴퓨터 시스템에 직접 연결된 물리적 장치입니다. 초기 컴퓨터에서는 콘솔이 모니터와 키보드로 구성되어 있었으며, 시스템의 직접적인 입력 및 출력을 담당했습니다.

터미널

  • 터미널사용자와 컴퓨터 간의 인터페이스 역할을 하는 장치 또는 소프트웨어입니다. 과거에는 물리적인 텔레타이프나 비디오 디스플레이 터미널을 가리켰으나, 현대에서는 주로 소프트웨어 기반의 터미널 에뮬레이터를 의미합니다. 사용자는 터미널을 통해 명령어를 입력하고 결과를 확인할 수 있습니다.

  • 은 운영 체제의 사용자 인터페이스로, 사용자가 명령어를 입력하여 시스템을 제어할 수 있게 해줍니다. 셸은 명령어 해석기 역할을 하며, 다양한 명령어를 실행하고 스크립트를 처리합니다. 일반적으로 사용하는 셸로는 Bash, Zsh 등이 있습니다.

https://philipholt.wordpress.com/2019/09/23/whats-the-difference-between-a-console-a-terminal-and-a-shell/

 

What’s the difference between a console, a terminal, and a shell?

I see a lot of questions that are close but the questions themselves show an underlying misunderstanding of some important terms. Why would I use Windows Terminal over PowerShell? I don’t nee…

philipholt.wordpress.com

버퍼라는건 메모리로 구현이되는데 I/O buffer는 무엇으로 이해하면 되는가?

  • 키보드로 입력
  • 버퍼에 입력값 저장
  • 버퍼에서 값을 CPU로 가져옴
  • CPU는 값 처리, 화면에 출력, 출력 시에도 out 버퍼를 사용
  • 버퍼를 비우는게 flushing

예전에 타자를 꾹 눌루고 있다가 시간이 지날 때 "삐삐삐" 소리가 나는건 버퍼가 가득차 사용자에게 더이상 입력이 안된다고 경고해 준거.

 

프로그램이 예기치 않게 종료되는 경우 데이터가 유실되지 않도록 하기 위해 FLUSH 명령문 또는 flush_ 서브루틴을 사용하여 버퍼된 데이터를 파일에 기록할 수 있습니다.

FLUSH 문은 이식성을 향상시키기 위해 권장되며 다음 예제에서 사용됩니다.

https://www.ibm.com/docs/ko/xl-fortran-aix/16.1.0?topic=io-flushing-buffers

 

I/O 버퍼 플러싱

프로그램이 예기치 않게 종료되는 경우 데이터가 유실되지 않도록 하기 위해 FLUSH 명령문 또는 flush_ 서브루틴을 사용하여 버퍼된 데이터를 파일에 기록할 수 있습니다. FLUSH 문은 이식성을 향상

www.ibm.com


콘솔 입력 키코드 값 읽기

  • 키코드 값은 대부분 ASCII코드와 일치
  • 1바이트씩 읽어서 값을 반환
  • 한글 한 글자는 2바이트

System.in.read()

단일 키 입력 처리

import java.io.IOException;

public class KeyCodeExample {
    public static void main(String[] args) throws IOException {
        System.out.print("키를 입력하세요: ");
        int keyCode = System.in.read(); // 키 입력
        System.out.println("입력된 키의 ASCII 코드: " + keyCode);
    }
}

반복 입력 및 종료 조건

import java.io.IOException;

public class RepeatKeyInput {
    public static void main(String[] args) throws IOException {
        int keyCode;
        System.out.println("q를 입력하면 종료됩니다.");
        while (true) {
            keyCode = System.in.read();
            System.out.println("입력된 키코드: " + keyCode);
            if (keyCode == 113) { // ASCII 코드 113은 'q'
                break;
            }
        }
    }
}

위 예제 한글 입력하면?

  • '가나다'에 대한 UTF-8 인코딩 결과
    • 234,176,128 / 235,130,152 / 235, 139, 164 / 10
  • UTF-8은 유니코드 값을 1~4바이트로 가변 인코딩
  • 자바에서 문자열의 끝은 NULL이 아님 

자바 인코딩 규칙

  • 자바 환경에서 문자열은 UTF-16(BE)로 인코딩
  • 문자열 처리 과정에서는 UTF-16 BE를 Modified UTF-8로 변경해 처리
  • 문자열의 끝인 NULL(0x0000)은 본래 UTF-8 규칙으로 인코딩 시 0ㅇ지만 Modified UTF-8로 인코딩할 경우 0xC080

 Scanner 클래스와 입력 버퍼 - 숫자 입력

  • s.nextInt()
  • s.nextDouble()
import java.util.Scanner;

public class ScannerTest {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        int a = s.nextInt();
        double b = s.nextDouble();
        System.out.println("a: "+a);
        System.out.println("b: "+b);
        s.close(); // Scanner 닫기
    }
}

세부 분석

  1. import java.util.Scanner;
    • Scanner 클래스는 Java의 java.util 패키지에 포함되어 있으며, 표준 입력(System.in)으로부터 데이터를 읽을 수 있도록 도와줍니다.
  2. Scanner s = new Scanner(System.in);
    • Scanner 객체 s를 생성하여 표준 입력 스트림(System.in)과 연결합니다. 이를 통해 콘솔에서 사용자가 입력한 데이터를 읽을 수 있습니다.
  3. int a = s.nextInt();
    • nextInt() 메서드는 사용자가 입력한 정수를 읽습니다. 이 메서드는 사용자가 유효한 정수를 입력할 때까지 대기합니다. 만약 비정수형 데이터를 입력하면 InputMismatchException이 발생할 수 있습니다.
  4. double b = s.nextDouble();
    • nextDouble() 메서드는 사용자가 입력한 실수를 읽습니다. 이 메서드도 마찬가지로 유효한 실수형 데이터를 필요로 하며, 잘못된 형식의 데이터를 입력하면 InputMismatchException이 발생할 수 있습니다.

개선

import java.util.InputMismatchException;
import java.util.Scanner;

public class ScannerTest {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        try {
            System.out.print("정수를 입력하세요: ");
            int a = s.nextInt();
            System.out.print("실수를 입력하세요: ");
            double b = s.nextDouble();
            System.out.println("a: " + a);
            System.out.println("b: " + b);
        } catch (InputMismatchException e) {
            System.out.println("잘못된 입력입니다. 숫자를 입력해주세요.");
        } finally {
            s.close(); // Scanner 닫기
        }
    }
}

Scanner 클래스와 BufferedReader 클래스의 차이점

https://velog.io/@gawgjiug/%EC%9E%90%EB%B0%94JAVA-Scanner-BufferedReader

 

자바(JAVA) - Scanner & BufferedReader

자바를 처음 배울 때 사용자(키보드) 입력받기 위해 보통 Scanner를 많이 사용한다. 알고리즘 문제를 풀다보니, Scanner를 사용하여 입력을 받을 경우에 시간이 초과되거나 하는 경험을 하였다. 그래

velog.io

측면 Scanner BufferedReader
패키지 java.util java.io
버퍼 크기 1 KB 8 KB
입력 파싱 정규 표현식을 사용하여 기본 데이터 타입 및 문자열을 파싱할 수 있음 문자열로만 입력을 읽으며 별도의 파싱 필요
데이터 타입 다양한 데이터 타입(int, double 등)을 직접 읽을 수 있음 문자열만 읽으며, 다른 데이터 타입으로 변환하려면 추가 파싱 필요
동기화 동기화되지 않음(스레드 안전하지 않음) 동기화됨(스레드 안전함)
성능 파싱 오버헤드 때문에 상대적으로 느림 더 큰 버퍼로 인해 대량의 데이터를 읽을 때 더 빠름
예외 처리 내부적으로 예외를 처리함 IOException을 발생시켜 명시적인 예외 처리가 필요
사용 사례 작은 입력을 다루거나 파싱이 필요한 경우 적합 대용량 파일이나 스트림을 효율적으로 읽어야 할 때 적합
구분자 처리 공백 및 줄바꿈을 구분자로 사용 줄바꿈을 구분자로 사용

사용 시기

  • Scanner를 사용할 때: 입력 데이터를 다양한 데이터 타입으로 직접 파싱해야 하거나, 입력 크기가 비교적 작을 때 적합합니다.
  • BufferedReader를 사용할 때: 대량의 입력이나 파일을 다루어야 하며 성능이 중요한 경우, 특히 멀티스레드 애플리케이션에서 사용하기 적합합니다.

Scanner 클래스와 입력 버퍼 - 문자열 입/출력

  • s.nextInt()
  • s.nextLine() - 개행문자가 나올때까지 읽어서 출력, 개행문자는 저장하지 않음

"엔터[\n]"는 완료를 의미(구분자), 엔터말고 "공백(스페이스, tap)"도 구분자로 사용

import java.util.Scanner;

public class ScannerStringTest {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        String tmp = s.nextLine();
        System.out.println(tmp);
    }
}

import java.util.Scanner;

public class ScannerStringTest {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        int data = s.nextInt();
        String tmp = s.nextLine();
        System.out.println(data);
        System.out.println(tmp);
    }
}

세부 분석

  1. Scanner s = new Scanner(System.in);
    • Scanner 객체 s를 생성하여 표준 입력 스트림(System.in)과 연결합니다. 이를 통해 콘솔에서 사용자가 입력한 데이터를 읽을 수 있습니다.
  2. int data = s.nextInt();
    • nextInt() 메서드는 사용자가 입력한 정수를 읽습니다. 이 메서드는 유효한 정수가 입력될 때까지 대기합니다.
    • 사용자가 비정수형 데이터를 입력하면 InputMismatchException이 발생할 수 있습니다.
  3. String tmp = s.nextLine();
    • nextLine() 메서드는 현재 줄의 나머지를 읽어서 반환합니다.
    • 여기서 중요한 점은 nextInt()가 정수를 읽고 나면 줄바꿈 문자가 남아있다는 것입니다. 이 줄바꿈 문자(\n) 또는 화이트스페이스도 nextLine()에 의해 즉시 읽혀져 반환하게 됩니다.
    • 따라서 test 앞에 "스페이스 공간"이 출력되면서 test가 출력 됨.

강제 형변환 문자 출력

 


이스케이프 시퀀스

  • \n: 줄바꿈(New line). 커서를 다음 줄의 시작 위치로 이동시킵니다.
  • \t: 탭(Tab). 커서를 다음 탭 위치로 이동시킵니다.
  • \r: 캐리지 리턴(Carriage return). 커서를 현재 줄의 시작 위치로 이동시킵니다.
  • \b: 백스페이스(Backspace). 커서를 한 칸 뒤로 이동시킵니다.
  • \f: 폼 피드(Form feed). 프린터의 다음 페이지로 이동합니다.
  • \: 백슬래시(Backslash) 자체를 출력합니다.
  • \': 작은따옴표(Single quote)를 출력합니다.
  • \": 큰따옴표(Double quote)를 출력합니다.
  • \ooo: 8진수(Octal) ASCII 코드로 문자를 표현합니다.
  • \xhh: 16진수(Hexadecimal) ASCII 코드로 문자를 표현합니다.
public class EscapeSequenceExample {
    public static void main(String[] args) {
        // 줄바꿈 \n
        System.out.println("Hello\nWorld!"); // "Hello"와 "World!"가 다른 줄에 출력됩니다.

        // 탭 \t
        System.out.println("Java\tProgramming"); // "Java"와 "Programming" 사이에 탭 간격이 추가됩니다.

        // 백슬래시 \\
        System.out.println("This is a backslash: \\"); // 백슬래시 하나를 출력합니다.

        // 큰따옴표 \"
        System.out.println("He said, \"Java is awesome!\""); // 큰따옴표를 포함한 문자열 출력

        // 작은따옴표 \'
        System.out.println("It\'s a beautiful day!"); // 작은따옴표를 포함한 문자열 출력

        // 캐리지 리턴 \r
        System.out.println("Hello\rWorld!"); // "World!"로 줄의 시작 부분을 덮어씁니다.

        // 백스페이스 \b
        System.out.println("Hello\bWorld!"); // "Hello"에서 마지막 문자 'o'가 지워지고 "HellWorld!"가 출력됩니다.

        // 폼 피드 \f (잘 사용되지 않음)
        System.out.println("Page 1\fPage 2"); // 폼 피드로 페이지를 나누는 효과(콘솔에서는 잘 보이지 않음)

        // 8진수와 16진수 표현
        System.out.println("Octal: \101");    // 8진수 ASCII 코드로 'A' 출력 (65의 8진수는 101)
        System.out.println("Hexadecimal: \u0041"); // 유니코드(16진수)로 'A' 출력 (0041은 'A')
    }
}

형식문자

  1. 정수 관련
    • %d: 10진수 정수. 예를 들어, System.out.printf("%d", 10);은 10을 출력합니다.
    • %o: 8진수 정수.
    • %x, %X: 16진수 정수. %x는 소문자, %X는 대문자로 표시합니다.
  2. 실수 관련
    • %f: 부동 소수점 실수. 기본적으로 소수점 이하 6자리까지 표시합니다.
    • %e, %E: 지수 표기법으로 실수를 표시합니다.
    • %g, %G: 자동으로 %f 또는 %e 형식을 선택하여 실수를 표시합니다.
  3. 문자 및 문자열
    • %c: 단일 문자.
    • %s: 문자열.
  4. 기타
    • %%: % 문자를 출력합니다.
public class FormatExample {
    public static void main(String[] args) {
        int num = 10;
        float pi = 3.14159f;
        char letter = 'A';
        String str = "Hello";

        // 정수를 출력
        System.out.printf("정수: %d%n", num);
        
        // 실수를 소수점 이하 두 자리까지 출력
        System.out.printf("실수: %.2f%n", pi);
        
        // 문자를 출력
        System.out.printf("문자: %c%n", letter);
        
        // 문자열을 출력
        System.out.printf("문자열: %s%n", str);
        
        // 16진수로 정수를 출력
        System.out.printf("16진수: %x%n", num);
    }
}

  • println() 하무가 아닌 printf()함수 사용

필수실습 1

이름부터입력

import java.util.Scanner;

public class test1 {
    public static void main(String[] args) {
        //나이와 이름 입/출력하기
        Scanner s = new Scanner(System.in);
        System.out.println("이름을 입력하세요: ");
        String name = s.nextLine();
        System.out.println("나이을 입력하세요: ");
        int age = s.nextInt();

        System.out.println("이름은: "+name+"입니다.");
        System.out.println("나이은: "+age+"입니다.");
    }
}

나이부터입력

import java.util.Scanner;

public class test1 {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        //나이와 이름 입/출력하기
        System.out.println("나이을 입력하세요: ");
        int age = s.nextInt();
        s.nextLine(); // 개행 제거

        System.out.println("이름을 입력하세요: ");
        String name = s.nextLine();


        System.out.printf("이름은 %s이고, 나이는 %d입니다", name, age);
    }
}

 

개행 제거를 하지 않으면 아래와 같은 결과가 나옴.

반응형