내장형 하드웨어/C언어

C언어 복습 5(token, strncpy, strtok, 디버깅)

동화다아아 2011. 6. 17. 17:48

// strncpy 함수를 사용한 token(의미있는 조각으로 나눈 것) 실습


#include<stdio.h>

#include<string.h>

int main()

{

        const char *p;

        const char *Text = "This is a ATMega";

        char T[4][7];

        

        p=Text;

        strncpy(T[0],p,4); // 문자를 복사하는 함수

        p=p+5; // 다음에 출력할 문자만큼 이동한다.

        T[0][4]=0; // Null 문자 입력

        strncpy(T[1],p,2);

        p=p+3;

        T[1][2]=0;

        strncpy(T[2],p,1);

        p=p+2;

        T[2][1]=0;

        strncpy(T[3],p,6);

        p=p+7;

        T[3][6]=0;


        printf("T[0] = [%s]\n",T[0]); // This만 출력

        printf("T[1] = [%s]\n",T[1]); // is만 출력

        printf("T[2] = [%s]\n",T[2]); // a만 출력

        printf("T[3] = [%s]\n",T[3]); // ATMega만 출력

        return 0;

}

⇒ strncpy

문자열을 복사한다.

헤더

string.h

형태

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

인수

char *dest

복사할 위치

char *src

원문 문자열

반환

복사한 문자열을 반환


// ※ strtok(⇒ string token)를 사용하는 다른 소스


#include<stdio.h>

#include<string.h>

int main()

{

        char Text[] = "This is a ATMega";

        char *p;

        

        p=strtok(Text, " "); // string token, Text문자열에서 공백을 찾아낸다.

        while(NULL !=p)

        {

                printf("%s\n",p);

                p=strtok(NULL," ");

        }

        return 0;

}


⇒ strtok 함수

문자열을 문자로 자르는 함수. 예로, "forum.falinux.com"을 "."으로 자르기를 하면 함수를 호출할 때 마다 "forum", "falinux", "com"의 선두 번지의 포인터를 반환한다.


처음에는 자르기 대상인 문자열과 자르기를 위한 문자를 인수로 호출한다.

strtok( str, sep);

이후에는 문자열 대상을 NULL과 자르기를 위한 문자만 인수로 전달한다.

strtok( NULL, sep);

더 이상 구할 문자열이 없다면 NULL이 반환된다.


단, strtok()는 잘라 낸 문자열을 구하기 위해 대상 문자열에 NULL을 추가한다. 즉, 원래의 문자열 내용이 변경 되므로 주의.

헤더

string.h

형태

char *strtok(char *restrict s1, const char *restrict s2);

인수

char *s1

자르기 대상 문자열

char *s2

잘라 내기 위한 문자 모임

반환

char *

잘라 내기한 문자열의 첫번째 포인터를 반환하며,

문자열이 없다면 NULL을 반환


⇒ const

 const char *p = "test"; // p를 사용해서 test 수정이 안된다.

 char *const p = "test"; // p가 test를 가리키는 것을 수정할 수 없다.

 const char * const p = "test"; // p가 가리키는 주소와 값 둘 다 바꾸지 않겠다.

⇒ const. 즉, 상수는 코드 영역에 있다. 물론 “  ” (문자열)도 코드 영역에 존재

  그러므로 “  ”는 모두 const char *
⇒ printf("const char *  "); 이다.

 linux에서 man 3 printf로 확인 가능(SYNOPSIS에서)

 

 

char A[ ] = "test";

printf(A);

// printf는 const char *,

  A는 char* 로 일치

const char *p = '1111';

print(char *p); // 비교를 위한 임의의 함수

print(p) → warning

// 수정할 수 없는 const를 수정할 수 있는 임의의 print 함수에 넣었으므로

※ char *Text = "This is ATMega"; // 코드 영역  → 코드 영역은 수정하면 안된다.

  char Text[ ] = "This is ATMega"; // 코드 영역에 생성과 함깨 stack 영역에도 생성


#include<stdio.h>

#include<string.h>

int main()

{

        char *Text1 = "This is a ATMega";

        char Text2[] = "This is a ATMega";

        printf("%08X\n", Text1);

        printf("%08X\n", Text2);

        return 0;

}

 
#include<stdio.h>

int main()

{

        unsigned char A;

        unsigned int B;

        unsigned int C;

        A=-1;

        B=A;

        C=B;


        return 0;

}

⇒ 디버깅 모드에서 분석

 

⇒ sub     esp, 4Ch를 보면 어셈블리에서 4C만큼의 공간을 확보하는 것을 확인 할 수 있다. 변수가 늘어날 때마다 이 크기는 변수의 크기만큼 늘어난다.(50, 54, …).

⇒ 처음에 어셈블리는 변수의 수 만큼 stack 크기만 벌려 놓는다.

        

 

⇒ movsx라는 명령이 붙었다. 여기서 s는 signed를 의미하고 크기를 맞추기 위해 x가 붙었다. 크기가 다른 두 변수를 맞추기 위해 확장이 일어난 것이다. 즉, 명령이 하나 더 실행되었다.

        

 

⇒ 다시 변수에 unsigned를 붙이고 디버깅 모드를 실행시키면

        

 

⇒ and가 생긴 것을 볼수 있다. 이것은 논리 연산 and와 같다.



 

※ p3_4.c 예제에서 디버그 중

if(num1<num2) 를 살펴보면

mov      eax, dword ptr[ebp-4]

cmp      eax, dword ptr[ebp-8]

jge main +4Eh(0040105e)

라고 출력되는데 여기서

⇒ cmp 결과는 jge에 영향을 미친다. (cmp는 상태레지스터를 가리킨다.)

⇒ 참이면 cmp, 거짓이면 jge로 간다.

⇒ jge 는 jump great equal로 if문을 만족시키지 않으면(크거나 같거나에 해당하면) 040105e 주소로 이동하게 되는데 이것은 if 다음의 printf문의 시작 주소와 같다.