본문 바로가기
코스웨어/16년 스마트컨트롤러

2016-08-22_조재찬_스터디일지_C언어-문자와 문자열 관련 함수

by 알 수 없는 사용자 2016. 8. 23.
728x90
반응형

하나의 문자를 출력하는 함수


int putchar(int c);

int fputc(int c, FILE * stream);

 // *stdout은 모니터 출력, putchar함수와 동일한 결과


하나의 문자를 입력받는 함수


int getchar(void);

int fgetc(FILE * stream);  

// *stdin은 키보드로 문자 입력받음


파일의 끝에 도달하거나 함수호출 실패 시 EOF(End Of File) 반환

EOF는 파일의 끝을 알리기 위한 상수 -1 로 정의된다.



/*

  문자열 관련 입출력 함수

*/


1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>

int main()
{
  int ch1 = getchar();  // 문자 입력
  int ch2 = fgetc(stdin);  // 엔터 키 입력

  putchar(ch1);    // 문자 출력
  fputc(ch2, stdout);  // 엔터키 출력
  
  return 0;
}

/* ouput : 

p

p

두 번째 문자가 엔터 키이므로 하나의 문자가 입력되고 출력된것처럼 착각할 수 있음

(아스키 코드값이 10인 "\n")

*/



/*

  문자열 입출력에서의 EOF

  함수 호출 실패 또는 윈도에서 CTRL+Z 가 입력되는 경우(linux : Ctrl+D)

*/


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>

int main()
{
  int ch;

  while (1)
  {
    ch = getchar();
    if (ch == EOF)
      break;
    putchar(ch);
  }

  return 0;
}



int getchar(void);

int fgetc(FILE * stream);


1바이트 크기 문자를 반환하는데, 반환형이 int인 이유

: char를 unsigned char로 처리하는 컴파일러도 존재


하지만 EOF는 -1로 정의된 상수

변환의 과정에서 양수로 형 변현될 수 있으므로

int형 변수는 기본적으로 signed int이므로 -1 반환에 문제없음



int getchar(void);

int fgetc(FILE * stream);


1바이트 크기 문자를 반환하는데, 반환형이 int인 이유?

: char를 unsigned char로 처리하는 컴파일러도 존재

하지만 EOF는 -1로 정의된 상수인데 

변환의 과정에서 양수로 형 변현될 수 있다.


int형 변수는 기본적으로 signed int이므로 -1 반환에 문제없음



/*

getchar,putchar 함수 이용


소-대문자 변환 출력 (알파벳 이외의 문자는 오류메시지 출력)

*/


#include <stdio.h>

int ConvCase(int ch);

int main()
{
  int ch;

  printf("대<-소문자 변환 : ");
  ch = getchar();
  ch = ConvCase(ch);

  if (ch == -1)  // 예외처리 (문자 아닐때)
  {
    puts("오류");
    return -1;
  }
  putchar(ch);
  puts("");
  
  return 0;
}

int ConvCase(int ch)
{
  int ASCII_Diff = 'a' - 'A';  
  // 아스키 코드에서 모든 영문 대소문자 차가 32로 같음 /  97-65  a-A,  98-66  b-B

  if (ch >= 'A' && ch <= 'Z')
    return ch + ASCII_Diff;
  if (ch >= 'a' && ch <= 'z')
    return ch - ASCII_Diff;
  else
    return -1;
}



/*

문자열 출력함수 puts, fputs


int puts(const char * s);   개행이 포함됨 ("\n")


int fputs(const char * s, FILE * stream);  

두번째 인자 stdout쓸 때 차이는 fputs에는 개행 ("\n")이 포함되지 않음

*/


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>

int main()
{  
  char * str = "simple string";

  printf("1. puts test \n");
  puts(str);
  puts("So Simple String");

  printf("2. fputs test \n");
  fputs(str, stdout); 
  printf("\n");  //  fputs에는 개행이 포함되지 않음

  printf("3. END \n");

  return 0;
}



/*

  gets, fgets

  char * gets(char * s);

  char * fgets(char * s, int n, FILE * stream);  

  

  // int n은 총 문자열의 길이 / sizeof(str)

  NULL문자를 저장할 공간도 필요

*/


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>

int main()
{  
  char str[7];  // 6 + NULL

  int i;
  for (i = 0; i < 3; i++)
  {
    fgets(str, sizeof(str), stdin);  // stdin 문자열 입력
    printf("Read %d: %s \n", i + 1, str);
  }

  return 0;
}


// fgets함수는 \n을 만날때까지 문자열을 읽어들이며,

 \n을 버리지않고 문자열의 일부에 포함시킨다.


중간에 삽입된 공백문자도 문자열의 일부로 받아들인다.



출력버퍼를 비우는 fflush 함수

int fflush(FILE * stream);


fflush(stdout);


출력 버퍼를 비운다는 것은 저장된 데이터를 지우는 것이 아님.

출력버퍼에 저장된 데이터를 목적지로 최종전송하는 것.


입력버퍼를 비운다는 것은 삭제의 의미에 가까움.


fflush(stdin); // 컴파일러에 따라 허용되는 경우도 있으나 사용하지 않는 것이 좋다.


입력버퍼를 비우는 함수가 따로 존재하지 않는 것은

read하면 비워지기 때문


이를 이용해 아래와 같은 함수를 정의할 수 있다.



void ClearLineFromReadBuffer(void)

{

while(getchar()!='\n');    // 개행문자를 만날때까지 읽어들임, 읽어들인 문자는 따로 저장하지않고 비워지게 된다.

}



/*

입력버퍼를 비우는 예제

*/

#include<stdio.h>

void ClearLineFrom_ReadBuffer(void);

int main(void)
{
	char perID[7];
	char name[10];

	fputs("주민번호 앞 6자리 입력 : ", stdout);
	fgets(perID, sizeof(perID), stdin);
	ClearLineFrom_ReadBuffer();

	fputs("이름 입력 : ", stdout);
	fgets(name, sizeof(name), stdin);
	
	printf("주민번호 : %s \n", perID);
	printf("이름 : %s \n", name);

	return 0;
}

void ClearLineFrom_ReadBuffer(void)
{
	while (getchar() != '\n');
}


/*
문자열 길이를 반환하는 함수 strlen
strlen을 활용하고 문자열의 마지막에 삽입되는 null을 없앤 길이 출력
*/
#include <stdio.h>

void RemoveNULL(char str[]);

int main(void)
{
	char str[100];
	printf("문자열 입력 : ");
	fgets(str, sizeof(str), stdin);
	printf("길이 : %d, 내용: %s \n", strlen(str), str);

	RemoveNULL(str);
	printf("RemoveNULL : %d, 내용: %s \n", strlen(str), str);

	return 0;
}

void RemoveNULL(char str[])
{
	int lengh = strlen(str);
	str[lengh - 1] = 0;
}



문자열을 복사하는 함수 strcpy (string copy)

char * strcpy(char * dest, const char * src);


src에서 dest로 복사 (복사된 문자열의 주소 값 반환)


char * strncpy(char * dest, const char * src, size_t n);

복사되는 문자열의 길이를 n으로 제한


메모리 공간의 효율적인 사용과 프로그램 안정성을 위해 strncpy를 더 많이 쓴다.




/*

문자열을 복사하는 함수 strcpy (string copy)

strncpy (복사되는 문자열의 길이를 n으로 제한)

char * strncpy(char * dest, const char * src, size_t n);

*/

#include<stdio.h>

int main(void)
{
	char str1[20] = "1234567890";
	char str2[20];
	char str3[5];
	
	// str1의 문자열이 str1에 복사됨
	strncpy(str2, str1);
	puts(str2);

	// str1의 문자열이 str3에 복사됨(str3의 길이만큼 제한)
	strncpy(str3, str1, sizeof(str3));
	puts(str3);

	strncpy(str3, str1, sizeof(str3) - 1);	// null문자 넣어줄 공간을 빼고 복사
	str3[sizeof(str3) - 1] = 0;	// null문자를 넣어줌
	puts(str3);

	return 0;
}



/*

문자열을 덧붙이는 함수 strcat  (STRing conCATenation)

strncat (복사되는 문자열의 길이를 n으로 제한)

char * strncat(char * dest, const char * src, size_t n);

*/

#include<stdio.h>

int main(void)
{
	char str1[20] = "First~";
	char str2[20] = "Second";

	char str3[20] = "Simple num: ";
	char str4[20] = "1234567890";

	//str2를 str1 뒤에 덧붙임
	strcat(str1, str2);
	puts(str1);

	//n만큼 덧붙이되 null문자 맨뒤에 붙여짐
	strncat(str3, str4, 7); // 1~7까지 붙여지고 끝에 NULL이 포함
	puts(str3);

	return 0;
}



문자열 비교함수 strcmp (string compare)

int strcmp(const char * s1, const char * s2);
int strncmp(const char * s1, const char * s2, size_t n);

두 문자열의 내용이 같으면 0, 같지않으면 0이 아닌값 반환

s1이 더 크면 0보다 큰 값 반환, s2가 더 크면 0보다 작은 값 반환

크고 작음은 아스키 코드값을 근거로 함 
(아스키코드 값이 더 크면 더 큰 문자열로 인식)

문자열에선 가장 앞의 문자를 가지고 비교
(문자열의 끝에는 null이 포함)

/*
문자열 비교함수 strcmp (string compare)

int strcmp(const char * s1, const char * s2);
int strncmp(const char * s1, const char * s2, size_t n);
*/

#include<stdio.h>

int main(void)
{
	char str1[20];
	char str2[20];
	printf("문자열 입력 1: ");
	scanf("%s", str1);
	printf("문자열 입력 2: ");
	scanf("%s", str2);

	if (!strcmp(str1, str2)) // 0이 아닌 값은 true, 같을 때 0(false) 반환 == if(strcmp(str1, str2)==0
	{
		puts("두 문자열 일치");
	}
	else
	{
		puts("두 문자열 불일치");

		if (!strncmp(str1, str2, 3)) // 3글자까지만 비교
			puts("그러나 앞 세 글자는 동일");
	}

	return 0;
}


문자열의 내용을 변환해주는 함수들


int atoi(const char * str); // atoi : 문자열의 내용 -> int형 변환

long atol(const char * str); // atol : 문자열의 내용 -> long형 변환

double atof(const char * str); // atof : 문자열의 내용 -> double형 변환


/*

그 이외의 변환함수 atoi, atol, atof

*/


1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<stdio.h>

int main(void)
{
	char str[20];

	fputs("정수 입력: ", stdout);
	fgets(str, sizeof(str), stdin);
	int result = atoi(str);
		
	printf("%d \n", result*result);

	return 0;
}


728x90