이 장에서는 C 프로그램의 입출력(I/O) 에 대한 NASA의 권장 원칙을 다룬다.
NASA의 코딩 표준은 단순한 기능 구현이 아니라,
안정성과 재현성(reproducibility) 을 보장하기 위한 구체적 설계 철학을 담고 있다.
표준 입출력 함수의 사용 제한
printf(), scanf() 등은 디버깅용으로만 사용하며,모든 입출력은 검증(validation)을 거쳐야 한다
if (input_value < MIN || input_value > MAX) {
report_error();
}모든 출력은 목적을 명확히 해야 한다
파일을 열 때는 반드시 반환값을 검사하여 오류를 처리한다.
FILE *fp;
fp = fopen("data.txt", "r");
if (fp == NULL) {
report_error("파일 열기 실패");
}
파일을 닫을 때도 fclose()의 반환값을 검사한다.
if (fclose(fp) != 0) {
report_error("파일 닫기 실패");
}
입력 함수 사용
scanf() 대신 fgets()를 사용하는 것을 권장한다. char buffer[100];
fgets(buffer, sizeof(buffer), stdin);이유: scanf()는 버퍼 오버플로우 위험이 크고, 예외 처리가 어렵기 때문이다.출력 함수 사용
printf()는 디버깅 목적에 한정한다.void log_message(char *msg) {
fprintf(logfile, "%s\n", msg);
}출력 형식 명시
"%d", "%f", "%s"표준 오류 스트림 사용
stderr로 출력한다. fprintf(stderr, "Error: invalid input.\n");일관된 오류 형식 유지
[ERROR] <function_name>: <description>예:[ERROR] read_data: 파일 포인터가 NULL입니다.로그 파일 관리
fprintf(logfile, "[%s] %s(): status=%d\n", timestamp, func_name, status);출력 정렬 및 폭 지정
printf("%10.3f", value);입력 포맷의 명확성
로케일(locale) 독립성 보장
. vs ,)과 같은 로케일 의존 동작을 피한다.이식성 문제 주의
fwrite(&header.version, sizeof(int), 1, fp);엔디언(endian) 처리
uint16_t swap16(uint16_t x) {
return (x << 8) | (x >> 8);
}파일 구조 정의
NASA는 입출력을 계층화(abstraction) 하여 관리한다.
이 구조를 통해 입출력 장치의 변경이 프로그램 전체에 영향을 미치지 않는다.
입력 길이 검사
if (strlen(input) >= MAX_SIZE) {
report_error("입력 초과");
}유효한 문자 검사
if (!isprint(ch)) {
report_error("잘못된 문자");
}값 범위 검사
if (temperature < -100 || temperature > 200) {
report_error("온도 범위 오류");
}출력 성공 확인
fprintf() 또는 fwrite()의 반환값을 검사한다. 출력 버퍼 플러시
fflush()를 호출한다.이중 기록 방지
NASA의 입출력 규칙은
안전성, 일관성, 이식성을 최우선으로 한다.
모든 입력은 검증되어야 하며, 모든 출력은 예측 가능한 형식으로 제어되어야 한다.
이는 단순한 코딩 규칙이 아니라, 미션 크리티컬 시스템에서 오류를 0으로 줄이기 위한 절대 원칙이다.
번역을 하며 틀린 부분이 있을 수 있으니 유의해서 봐주시고,
잘못된 점이나 수정이 필요하다면 댓글로 부탁드립니다.원문: https://ntrs.nasa.gov/api/citations/19950022400/downloads/19950022400.pdf