-
[C,C++] 문자열과 포인터ETC/[C, C++] 2022. 4. 22. 21:05반응형
포인터와 문자열 출력(printf)
int main(){ printf("%s", "rain"); }
컴파일러는 rain을 문자열 자체로 처리하는 것이 아닌 별도의 메모리에 보관을 하고, 시작 위치 값으로 처리해버린다.
[0] [1] [2] [3] r a i n \0 문자열은 그래서 항상 첫번째 문자의 주소 값으로 바뀌게 된다.
int main(){ printf("%c", *"rain"); }
문자열은 주소 값이니까 간접 참조 연산자 *를 붙일 수 있게 된다.
따라서 출력 값: r
int main(){ printf("%c", *("rain"+3)); }
주소에 + 3을 하게 되면 가리키는 공간의 형태(char) 만큼 곱해서 더해짐.
r의 주소 값 +(3*4)가 되는 것이다.
따라서 출력 값: n
여기서 *("rain"+3) 은 *"rain"[3]과 같은 의미이다.
p.s. % s는 출력할 문자열의 첫 문자 위치는 원한다.
int main(){ char *cp="rain"; printf("%s",cp); }
cp포인터로 rain이라는 문자열을 연결할 수 있다.
따라서 출력을 할 때에
시작 주소 값인 r부터 출력을 하면서 주소 값을 더해가면서 출력을 하는데, \0를 만나면서 종료하게 된다.
int main(){ char *cp= "rain"; printf("%s",cp); cp="snow"; printf("%s",cp); }
이렇게 되면 cp는 r의 주소를 저장해 rain을 출력하고, 이 연결을 끊고 s의 주소를 저장해 snow를 출력하게 된다.
문자열은 char 배열의 주소 값이 된다.
이런 방법은 사용자가 문자열을 입력할 때는 사용하지 못한다->배열 선언배열과 문자열 입력(scanf, getchar, gets, fgets)
int main(){ char str[20]; scanf("%s", str);//공백전까지의 문자열만 입력받음. gets(str);//공백까지 포함해 한 줄을 입력받음. }
int main(){ char str[20]; char ch; ch=getchar(); while(ch!='\n'){ str[i]=ch; i++; ch=getchar(); } str[i]='\0'; //끝에 NULL문자가 있어서 문자열이 될 수 있음. }
실행시키면 getchar()는 버퍼로 가서 값을 가져오려고 하는데 버퍼가 비어있어서 사용자가 입력할 때까지 기다린다.
입력: Rainy Day
결과:
str
R a i n y D a y \0 gets()
이 과정을 gets() 함수로 처리할 수 있는데
주의할 점은 여러 번 gets() 함수를 불러올 때 버퍼에 '\n'가 남아있을 수 있어 바로 넘어가는 것만 조심하면 됨.
또 주의할 점은, 배열의 크기를 넘었을 때 체크할 수 있는 게 없어서 계속 받아오는데, 이때 메모리를 넘겨도 계속 저장하게 되어 위험하다
fgets()
int main(){ char str[20]; fgets(str,sizeof(str),stdin); str[strlen(str)-1]='\0';//개행문자 자리에 널문자를 넣어서 출력할 때 원치않은 줄바꿈이 일어나지 않도록함. }
한 줄을 입력받는데 만약에 메모리를 넘어서면 19번째까지만 받고 마지막을 NULL문자로 채워줌.
gets() 보다 안전한 함수.
하지만, fgets()는 gets()와 다르게 개행 문자(\n)를 입력하면 배열 마지막에 저장을 하고, 그 뒤에 NULL문자로 채워줌.
따라서 strlen()가 NULL문자 나오기 전까지 배열의 길이를 반환해주므로 -1을 해 개행문자 자리에 NULL문자를 넣어 개행 문자를 삭제시켜주는 프로세스가 필요하다. 약간의 공식 같은 느낌?
마지막으로 문자열 전용 출력 함수 puts()도 있는데
puts(str)하면 str배열을 출력해주지만, 자동으로 개행된다는 단점이 있다.
scanf 함수는 공백전까지 입력(NULL)
gets 함수는 공백 포함한 줄 입력(NULL)
fgets 함수는 최대 배열 크기까지만 입력(개행, NULL)
표준 입력 함수들은 같은 버퍼를 공유한다.반응형'ETC > [C, C++]' 카테고리의 다른 글
[C,C++] 포인터 배열 (0) 2022.04.30 [C,C++] C에서 함수의 데이터 전달 방법(Call-by-Value, Call-by-Reference) (0) 2022.04.25 [C,C++] 변수의 종류(지역, 전역, 정적 ,레지스터) (0) 2022.04.24 [C,C++] 문자열 함수(strcpy, strncpy, strlen, strcat, strncat, strcmp, strncmp) (0) 2022.04.22 Hello World! (0) 2022.04.22