leejun332211   5년 전


문제의 직접적 질문은 아니지만 기초적인 질문 ...

문제를 많이 풀다보니 기초가 부족함을 알고 혼자 여기저기 찾았지만
어려워서.. 몇가지를 고수님께 질문드립니다.

모든것은 c언어에서 string.h를 제외하고 생각하겠습니다.

많은 도움 바랍니다 죄송합니다...


===================첫질문..===================
char str[101];
scanf("s",str);

이런상황에서 입력을 okay로 받았습니다.

스트림에는 okay\n 가들어왔는데
\n때고 okay가 str에 박힙니다.
그러면 str[0]=='o' str[1]=='k' str[2]=='a' str[3]=='y'
일텐데

1. str[4]는 무엇인지 ....

2. if(str=="okay)할때, 왜 okay라고 비교했을때 같다가 안되는지...

3. 보통 gets();로 받을때는 문자열 마지막에 \n으로 끝남을 확인할수있는데
   scanf로 받은경우는 문자가 끝난다 판단을 어떻게 하는지....
   (저는 초기에 문자열을 char str[101]={};처럼 null 로 초기화하고 null이나오면 끝났다라고
    판단하는데 그게 맞는지..)


==================두번째질문=======================

char str[101]={}; //받는 문자열
char tmp[101]={}; //앞단어 빼고 옮길 문자열
scanf("s",str);//입력
int i;      //for를 위한 i
int a,b;       //숫자변환용 int

for(i=4; i<101; i++){
tmp[i-4]=str[i];
}


a=aoi(str);
b=aoi(tmp);

printf("%d\n",a);
printf("%d\n",b);


이런상황에서 100 101을 입력받습니다.

1.이런상황에서 a는 정상출력이 100으로 되는데
  왜 b는 101 이안나오고 0 이나올까요...?
  그리고만약 b를 101로 정상적으로 받으려면 어떻게 해야하나요...

2. char str[101]={}을 한목적이 null로 초기화한건데 맞는가요..?



djm03178   5년 전

===================첫답변..=================== 

  1. scanf의 %s는 화이트스페이스 문자 (공백, 탭, 개행 문자 등)을 delimiter로만 사용하고, 결과 문자열에 저장하지 않습니다. 즉 우리가 입력할 때는 okay[엔터] 이렇게 치겠지만, scanf는 [엔터]가 나오는 순간 그 전까지를 타겟으로 보고 okay만 str에 저장해준다는 거죠. 그러면 대체 str[4]는 뭐가 되느냐 하면, 널 문자라는 것으로 만들어줍니다. 널 문자는 값이 0인 문자로, 문자열의 끝을 나타내는 데에 사용됩니다. 왜 이게 필요할까요? 문자열이라는 것은 char형이 연속적으로 있는 것인데, 문자열의 길이를 모르는 상태라면 과연 어디까지가 우리가 원하는 문자열이고 어디부터는 그 문자열에 속하지 않는 것들인지를 알아낼 방법이 있어야 합니다. 그 방법으로 C에서는 널 문자를 문자열의 끝을 나타내는 데에 사용합니다.
  2. str는 배열의 시작 주소를 나타냅니다. "okay"도 "okay"라는 문자열 상수가 저장된 곳의 주소를 나타냅니다. 두 주소를 == 으로 비교하는 것은 말 그대로 두 주소가 같은지를 보는 것입니다. 비슷한 예를 들자면 아래의 코드와 비슷합니다. 두 문자열이 같은지를 보려면 그 문자열이 담고 있는 내용이 같은지를 봐야 하는 것이지, 그게 저장되어 있는 주소가 같은지를 보면 안 되겠죠? 그걸 편하게 해주는 함수가 strcmp입니다.
  3. gets도 scanf와 마찬가지로 개행 문자는 delimiter로만 사용하고 결과 문자열에는 담아주지 않습니다. scanf의 %s와는 다르게 그 외의 화이트스페이스들은 담아준다는 거고요. 그리고 모든 문자열 입력 함수들은 결과 문자열의 마지막에 널 문자를 반드시 삽입해줍니다. 그러지 않으면 그걸 문자열이라고 부를 수도 없거든요. 그러니 미리 널 문자로 초기화할 필요도 없습니다. 쭉 읽다가 널 문자가 나오면 거기를 문자열의 끝으로 보면 됩니다.

==================두번째답변=======================

  1. 위에서 말씀드렸지만 scanf는 공백 문자도 역시 delimiter로 사용합니다. 그래서 100 101이라고 입력했으면 100만 읽어서 str에 저장하고, 나머지 [공백]101[엔터] 부분은 그대로 입력 버퍼에 남겨둡니다. 이 말은, 추후에 scanf를 다시 호출하면 저 나머지 부분을 읽어들일 수 있다는 뜻입니다. 아무튼, 지금은 %s가 하나만 쓰였기 때문에 100 밖에 읽어들일 수가 없으니, 나머지 부분이 원하는 대로 동작하지 않는 이유는 자명합니다.
  2. 초기화를 하는 것이 나쁜 경우는 거의 없습니다. 다만 필수는 아닙니다. 문자열의 정의와 다루는 법을 정확하게 알고 있다면 초기화를 안 해도 무방합니다.

leejun332211   5년 전

너무감사합니다. 공부하는데 너무 도움주셔서 감사합니다
더열심히할께요 지존님

댓글을 작성하려면 로그인해야 합니다.