strlen (String Lenth) : 문자열의 길이를 리턴하는 함수.


#include <string.h>

size_t strlen(const char* s);

문자열의 길이 정보 반환






strcpy (String Copy), strncpy (String Number Copy) : 문자열 복사 함수.


#include <string.h>

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

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

첫 번째 매개변수에 전달된 주소 값(dest에 전달된 값) 반환.






strcat (String Concatenate), strncat (String Number Concatenate) : NULL문자 뒤에 문자열을 추가하는 함수.


#include <string.h>

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

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

첫 번째 매개변수에 전달된 주소 값(dest에 전달된 값) 반환.




: 만약 abcd\0 이 있는데 efg\0를 붙인다면, \0를 없애고 그자리부터 붙여짐. -> abcdefg\0




strcmp (String Compare), strncmp (String Number Compare) : 문자열의 비교 함수.

#include <string.h>

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

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

두 문자열이 동일하면 0, 동일하지 않으면 0이 아닌 값 반환 (더 정확히 말하자면, 음수를 리턴하면 그것은 앞서는 문자열이고, 양수를 리턴하면 그것은 뒤서는 문자열이다.)

앞서거나 뒤선다는 것은 사전편찬순으로 말함.


: strncmp함수는 비교하는 문자열의 길이가 세 번째 전달 인자의 값보다 크면, 세 번째 전달인자의 길이만큼만 부분 비교를 한다.







strchr (String Character), strrchar : 문자가 언제 처음 또는 마지막에 등장하는지 알아내는 함수.


#include <string.h>

char* strchr(const char* s, int c);

char* strrchr(const char* s, int c);

문자를 찾을 시 해당 문자의 포인터를, 못 찾을 시 NULL 포인터를 반환.


: strchr 와 strrchr의 차이점

: strrchr은 문자열의 끝에서부터 찾기 시작한다.








strstr (String String) : 문자열 안에 문자열 검색


#include <string.h>

char* strstr(const char* src, const char* sub);

문자열을 찾을 시 해당 문자열의 시작 주소를, 못 찾을 시 NULL 포인터를 반환


: 문자열 안에 특정 문자열이 존재하는지 확인하고 싶을 때 사용하는 함수.







strtok (String Token) : 문자열을 토큰 기준으로 나누는 경우에 활용하는 함수.


#include <stdio.h>

char* strtok(char* str, const char* set);

다음 번 토큰의 주소 값을 반환하며, 반환할 토큰이 없다면 NULL 포인터 반환.




※ strtok 함수를 활용할때의 주의점

: 문자열을 변경시킨다. 때문에 strtok 함수의 호출 이후에도 그 내용이 보전되어야 하는 문자열이라면, strtok함수를 호출하기 이전에 원본을 복사해 두는 것이 좋다.





atoi, atol, atoll, atof : 문자열에 저장되어 있는 숫자 정보는 실제 숫자로 변환하는 함수.


#include <stdlib.h>

int atoi(const char* str);           //int형 데이터로 변환.

long atoi(const char* str);        //long형 데이터로 변환.

long long atoi(const char* str); //long long형 데이터로 변환.

double atoi(const char* str);    //double형 데이터로 변환.


'Programming > C' 카테고리의 다른 글

실행파일이 만들어 지는 과정.  (0) 2013.02.15
sprintf 함수, sscanf 함수  (0) 2013.02.15
getchar 함수로 입력버퍼 비우는 사용 예.  (0) 2013.02.15
bsearch 함수 사용법.  (0) 2013.02.15
assert 문 사용하기  (0) 2013.02.15
Posted by scii
:




hoop를 입력하게되면, h만 출력이 되고 나머지 oop\n(엔터키)는 입력버퍼에 남아있게 된다. 그래서 버퍼를 비워주지 않으면 문자열을 입력할때 입력할 기회를 잃게된다.


입력버퍼를 비우는 방법에는 fflush(stdin) 함수가 있지만 이 함수는 visual studio에서만 국한된다. 다른 컴파일러에서는 사용이 안될수도 있다.

그래서 일반적인 방법이 getchar 함수로 입력버퍼를 비워주는 것이다. 


while(getchar() != '\n'); 라는 것으로 입력버퍼를 비워주고 있는데, 이 명령의 뜻은, 일단 getchar()함수로 버퍼에 남아있는 것을 읽어들인다. 문자 단위로

그런 다음, \n과 비교를 한다. 비교를 하여서 \n이 아니면 남아있는 것을 계속 읽어들이면서 비워낸다. 마지막으로 \n을 읽어들인 후 비교를 한다. 조건에 부합되지않기 때문에 반복문 종료. 

따라서 버퍼에는 아무것도 남아 있지 않게 된다.


저것을 풀어 쓰면, 


char a;

while(1)

{

      a = getchar();

      if(a == '\n')

            break;

}


Posted by scii
:

표준 검색 함수 : bsearch (binary search)


qsort 함수와 함께 유용하게 사용할 수 있는 bsearch 함수.


: bsearch 함수는 이진 검색 알고리즘을 구현한 함수이다. 간단히 말해서 원하는 데이터를 찾아주는 기능을 제공하는 함수이다. 다만 이진 검색 알고리즘은 "저장된 데이터가 정렬되어 있어야 한다.(오름차순으로) 그래서 qsort 함수와 더불어 유용하게 사용할 수 있다.


#include <stdlib.h>

void* bsearch(

      const void* key,        // 찾고자 하는 데이터가 저장되어 있는 주소 값.

      const void* base,    // 검색 대상이 되는 배열의 주소.

      size_t count,          // 배열 요소의 개수.(배열의 길이)

      size_t size,           // 배열 요소의 크기.

      int (*compare)(const void*, const void*)  // 값의 비교 기능 제공 함수.

);

검색 성공 시 검색 대상의 주소 값 반환, 검색 실패 시 NULL 반환.

((bsearch 함수는 검색의 대상이 오름차순으로 정렬되어 있을 것을 요구)


int compare(const void* key, const void* value)

{  

      if(key가 참조하는 값이 value가 참조하는 값보다 크다)

            return "양수";

      else if(key가 참조하는 값이 value가 참조하는 값보다 작다)

            return "음수";

      else // key가 참조하는 값과 value가 참조하는 값이 같다.

            return 0;

}


이 함수는 bsearch 함수 내부에서 호출이 되는데, bsearch 함수의 첫 번째 전달인자가 이 함수의 첫 번째 전달인자가 된다. 이는 이 함수의 반환 값을 참조하여 찾고자 하는 데이터를 찾기 위해서다. 

그리고 찾는 대상을 찾았을 때, 이의 주소 값을 반환하면서 bsearch 함수를 종료한다.




============================================================================================



strcmp 함수 대신 값의 비교 기능 함수 만들어서 코딩.



Posted by scii
:

assert 문 사용하기

Programming/C 2013. 2. 15. 03:03 |

프로그램의 오류를 찾기 위해 가장 기본적으로 쓰는 기능 중 하나가 바로  assert 문 입니다.

 

사용법은 다음과 같지요.

 

#include <assert.h>              // C++ 로는 #include <cassert>

 

Pointer* p = new Pointer();      // 임의로 메모리를 할당하곤

 

assert( p != NULL );               // 메모리가 할당되지 않았다면 메세지 박스와 함께 프로그램이 죽습니다.

 

...                                        // 그렇지 않으면 프로그램은 계속 실행되겠죠.

 

보다시피 사용방법은 매우 직관적입니다.

 

assert( p != NULL ); 구문은 디버그 모드에서만 작동되며 p가 반드시 NULL이 아니어야 한다는 조건을 부여합니다. 따라서, p가  NULL 이라면 메세지 박스가 활성화 되면서 assert가 걸린 라인 수까지 표시가 되지요.

 

물론 릴리즈 모드로 컴파일하면 위의 구문들은 모두 생략됩니다.

 

 

 

이제, 기본적인 사용방법을 알았으니 추가적인 비법을 알려드리지요.

 

 #include  <assert.h>              // C++ 로는 #include <cassert>

 

Pointer* p = new Pointer();      // 임의로 메모리를 할당하곤

 

assert( p != NULL && "포인터 메모리 할당을 실패했잖아" );             

 

...                                        // 그렇지 않으면 프로그램은 계속 실행되겠죠.

 

결과는 메세지 박스에 "포인터 메모리 할당을 실패했잖아" 라는 문구까지 부가적으로 표시됩니다.

 

 

매우 간단한 반면 그 기능은 탁월합니다. 저 같은 경우는 항상 포인터 NULL  여부 및 인덱스 참조 시에  assert 문을 사용하곤 합니다만

 

여러분도 필요한 곳에 사용하시길 바랍니다.



출처 -  http://blog.naver.com/hermet/54763810

'Programming > C' 카테고리의 다른 글

getchar 함수로 입력버퍼 비우는 사용 예.  (0) 2013.02.15
bsearch 함수 사용법.  (0) 2013.02.15
qsort 함수 사용법  (0) 2013.02.15
qsort (Quick Sort) 함수.  (0) 2013.02.15
atexit 함수, exit 함수, abort 함수  (2) 2013.02.15
Posted by scii
:

qsort 함수 사용법

Programming/C 2013. 2. 15. 02:58 |

qsort 사용 예

 

실제 이것을 사용할 때는 이미 작성되어 라이브러리로 제공하는 함수를 사용하면 된다. 기본적인 리얼타임 라이브러리이다. 따라서 어떻게 호출하는가만 알면 사용은 쉽다.

 

qsort( (void *)데이터의 시작 주소, (size_t) 리스트의 갯수, 바꿀 데이터의 길이, 비교함수 );

 

데이터는 여러 변수의 형태를 사용할 수 있다. 따라서 소트의 길이 및 비교는 모두 다르다. 이것을 처리하기 위해 위와 같은 함수의 모양을 갖는다.

- 데이터의 시작 주소 : 데이터의 형태는 소트할 상황에 따라 다르므로 데이터가 존재하는 시작 주소를 넣으면 된다. int 일수도 있고, struct 일수도 있다. 따라서 이것은 void 포인트 변수로 타입 변환하여 넣어주면 된다.

- 리스트의 갯수 : 소트해야할 데이터의 갯수를 넣는다.

- 바꿀 데이터의 길이 : 데이터의 상황에 따라 변수의 형태와 길이가 다르므로 가급적 포인터등을 사용하려 교환하는 길이를 줄이는 것이 소트 시간을 단축할 수 있을 것이다.

- 비교함수 : 두 개의 데이터 엘리먼트를 비교하는 함수를 작성하고 함수 포인터로 넣어 주면, sort 과정 상 비교할 때 호출 된다. 이때 역시 데이터의 형태를 모르므로 void 포인터로 넘어 온다. 비교할 2개의 데이터의 위치를 포인터로 받는다.

 

#include <stdlib.h>
#include <string.h>
//#include <conio.h>

 

#include <stdio.h>

 

 

struct student {
    char name[20];
    char tel[20];
    char id[15];

    char stid[10];
    char part[20];
    char etc[100];
};

 

struct student gStudent[] = {
   { "홍길동", "010-3234-2344", "840305-1373848", "200341056", "전자공학과", "" },
   { "김홍영", "010-3344-2675", "840505-1365648", "200341057", "전자공학과", "" },
   { "박수만", "010-5234-4644", "840305-1453848", "200341066", "전자공학과", "" },
   { "송석만", "011-564-1345",  "640305-1375468", "200351056", "컴퓨터공학과", "" },
   { "전승혁", "010-3344-2334", "340305-1566648", "200351012", "컴퓨터공학과", "" },
   { "김만수", "016-764-5664",  "740311-1454568", "200351016", "컴퓨터공학과", "" },
};

 

struct student *gpStudent[] = {
    &gStudent[0],
    &gStudent[1],
    &gStudent[2],
    &gStudent[3],
    &gStudent[4],
    &gStudent[5]
};
 
#define SZ_STUDENT sizeof(gStudent)/sizeof(gStudent[0])
 
int compareName( const void *arg1, const void *arg2 )
{
   return strcmp( ((struct student *)arg1)->name, ((struct student *)arg2)->name);
}

 

int compareSiId( const void *arg1, const void *arg2 )
{
   return strcmp( (*(struct student **)arg1)->stid, (*(struct student **)arg2)->stid);
}


int main(int argc, char* argv[])
{

    qsort( (void *) &gStudent, (size_t)SZ_STUDENT, sizeof(struct student), compareName);

 

   int cnt;

    printf("구조체에서 이름으로...\n");
    for (cnt = 0;cnt < SZ_STUDENT;cnt++) {
        printf("[%s] %s - %s\n", gStudent[cnt].stid, gStudent[cnt].name, gStudent[cnt].tel );
    }
 
    printf("\n포인터에서 학번으로...\n");
    qsort( (void *) gpStudent, (size_t)SZ_STUDENT, sizeof(struct student*), compareSiId);

    for (cnt = 0;cnt < SZ_STUDENT;cnt++) {
       printf("[%s] %s - %s\n", gpStudent[cnt]->stid, gpStudent[cnt]->name, gpStudent[cnt]->tel );
    }

    //getch();
    return 0;
}


실행을 하면 :

구조체에서 이름으로...
[200351016] 김만수 - 016-764-5664
[200341057] 김홍영 - 010-3344-2675
[200341066] 박수만 - 010-5234-4644
[200351056] 송석만 - 011-564-1345
[200351012] 전승혁 - 010-3344-2334
[200341056] 홍길동 - 010-3234-2344

 

포인터에서 학번으로...
[200341056] 홍길동 - 010-3234-2344
[200341057] 김홍영 - 010-3344-2675
[200341066] 박수만 - 010-5234-4644
[200351012] 전승혁 - 010-3344-2334
[200351016] 김만수 - 016-764-5664
[200351056] 송석만 - 011-564-1345

 

 

이 프로그램에서 쏘트의 방법상 다음 2가지 방법을 생각해 본다.

 

(1) qsort( (void *) &gStudent, (size_t)SZ_STUDENT, sizeof(struct student), compareName);

(2) qsort( (void *) gpStudent, (size_t)SZ_STUDENT, sizeof(struct student*), compareSiId);

 

1번은 struct 전부를 바꾸어야 하고

2번은 struct 포인터만을 바꾼다.

 

이렇게 되면 2가지의 쏘트에서 실행 시간이 다르게 된다. 비교 후 데이터의 교환 조건이 되면 교환을 수행할 때

- 1번 : struct의 전 사이즈를 수행 한다. 따라서 sizeof(struct student) 바이트 수 만큼 교환 된다. 

- 2번 : 단순히 포인터 4바이트(32비트 CPU에서)만을 바꾸면 끝이다.

따라서 데이터 교환을 줄이려면 이런 경우 포인터가 유용하다.

 

 

프로그램 예


#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <conio.h>

char *msg[] = {
    "Hello",
    "홍길동",
    "우리집에",
    "computer",
    "TV",
    "12345"
};
 
int compareAlpha( const void *arg1, const void *arg2 );
int compareLength( const void *arg1, const void *arg2 );

void printList(char **msg, int szlist);

 

int main(int argc, char* argv[])
{
   int szlist;

     szlist = sizeof(msg) / sizeof(msg[0]);

     printf("원래 리스트...\n");
     printList(msg, szlist);
 
  // 알파벳 순서 소트
     qsort( (void *)msg, (size_t)szlist, sizeof( char * ), compareAlpha );

     printf("\n알파벳 순서 소트 결과...\n");
     printList(msg, szlist);

  // 문자의 길이 순서 소트
     qsort( (void *)msg, (size_t)szlist, sizeof( char * ), compareLength );

     printf("\n문자의 길이 순서 소트 결과...\n");
     printList(msg, szlist);

 

     getch();
     return 0;
}

void printList(char **msg, int szlist)
{
   int cnt;

     for (cnt = 0;cnt < szlist;cnt++)
          printf("[%d] %s\n", cnt+1, msg[cnt]);
}

// 알파벳 순서 비교
int compareAlpha( const void *arg1, const void *arg2 )
{
   return _stricmp( * ( char** ) arg1, * ( char** ) arg2 );
}

// 문자의 길이 비교
int compareLength( const void *arg1, const void *arg2 )
{
   return strlen( *( char** ) arg1) - strlen ( *( char** ) arg2 );
}

 

 

결과 :

 

원래 리스트...
[1] Hello
[2] 홍길동
[3] 우리집에
[4] computer
[5] TV
[6] 12345

 

알파벳 순서 소트 결과...
[1] 12345
[2] computer
[3] Hello
[4] TV
[5] 우리집에
[6] 홍길동

 

문자의 길이 순서 소트 결과...
[1] TV
[2] Hello
[3] 12345
[4] 홍길동
[5] 우리집에
[6] computer

 


올림순, 내림순하는 경우의 비교는 다음과 같은 비교함수를 바꾸면 된다.



// 알파벳 순서 비교
int compareAlpha2( const void *arg1, const void *arg2 )
{
   return _stricmp( * ( char** ) arg2, * ( char** ) arg1 );
}


[1] 홍길동
[2] 우리집에
[3] TV
[4] Hello
[5] computer
[6] 12345



// 문자의 길이 비교
int compareLength2( const void *arg1, const void *arg2 )
{
   return strlen( *( char** ) arg2) - strlen ( *( char** ) arg1 );
}


[1] computer
[2] 우리집에
[3] 홍길동
[4] Hello
[5] 12345
[6] TV

 

 

Linux에서 예

Linux man page
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>

static int
cmpstringp(const void *p1, const void *p2)
{
    /* The actual arguments to this function are "pointers to
       pointers to char", but strcmp() arguments are "pointers
       to char", hence the following cast plus dereference */

   return strcmp(* (char * const *) p1, * (char * const *) p2);
}

int
main(int argc, char *argv[])
{
    int j;

   assert(argc > 1);

   qsort(&argv[1], argc - 1, sizeof(char *), cmpstringp);

   for (j = 1; j < argc; j++)
        puts(argv[j]);
    exit(EXIT_SUCCESS);
}


'Programming > C' 카테고리의 다른 글

bsearch 함수 사용법.  (0) 2013.02.15
assert 문 사용하기  (0) 2013.02.15
qsort (Quick Sort) 함수.  (0) 2013.02.15
atexit 함수, exit 함수, abort 함수  (2) 2013.02.15
함수 포인터를 반환하는 함수의 정의  (0) 2013.02.15
Posted by scii
:

 표준 정렬 함수 : qsort


이름 그대로 빠른 속도로 정렬하도록 디자인 된 알고리즘.

#include <stdlib.h> 

void qsort (

void* buf,                                                 //정렬의 대상이 되는 배열의 주소.

size_t num,                                                //배열 요소의 개수 (배열길이).

size_t size,                                               //배열 요소의 크기.

int (*compare)(const void*, const void*) //정렬 규칙 제공 함수.(함수 포인터)

);

대상의 자료형에 상관없이 정해진 규칙에 근거해 정렬 수행을 한다.

 

qsort 함수의 마지막 전달인자가 될 함수를 정의 할 때, 함수의 정의 규칙이 있다.

 반환 값 0     ->  비교 대상의 정렬 순서가 동일한 경우.

 반환 값 1     ->  두 번째 포인터가 가리키는 대상이 정렬 순서상 앞서는 경우.

 반환 값 -1     -> 첫 번째 포인터가 가리키는 대상이 정렬 순서상 앞서는 경우.


 

  

'Programming > C' 카테고리의 다른 글

assert 문 사용하기  (0) 2013.02.15
qsort 함수 사용법  (0) 2013.02.15
atexit 함수, exit 함수, abort 함수  (2) 2013.02.15
함수 포인터를 반환하는 함수의 정의  (0) 2013.02.15
함수 포인터  (0) 2013.02.15
Posted by scii
:

atexit 함수와 유사 부류의 함수들.


atexit 함수.


#include <stdlib.h>

int atexit(void (*func)(void));

함수 호출 성공 시 0, 실패 시 0 아닌 값 반환.


반환형과 매개변수 형이 void로 선언된 함수의 이름이(주소 값이) atexit함수의 인자로 전달되어야 한다. 그리고 이렇게 인자로 전달된 함수가 프로그램 종료 시 자동으로 호출되며, 이렇게 자동으로 호출되어야 할 함수는 32개 이상 등록할 수 있다.

※ atexit 함수의 특성: 등록된 순서의 역순으로 호출된다. 그리고 atexit 함수를 통해서 등록된 함수는 프로그램이 정상적으로 종료될 때에만 호출된다.



exit 함수와 abort 함수.


#include <stdlib.h>

void exit(int status);

void abort(void);

두 함수 모두 실행중인 프로그램을 종료시킨다.


abort 함수는 프로그램의 오류로 인한 비정상적 종료를 의미.

즉, abort 함수는 프로그램 자체에 아주 치명적인 오류가 발생해서 어쩔수 없이 프로그램을 종료해야만 하는 경우에 호출하도록 정의된 함수이다. 때문에 이 함수가 호출이 되면, 운영체제에서 특별한 액션을 취해준다.


exit 함수는 프로그램의 정상적 종료도, 비정상적 종료도 나타낼 수 있는 함수이다. 일반적으로 정상적으로 종료하는 경우에는 정수 0을, 그리고 비정상적으로 종료하는 경우에는 0이 아닌 값을 인자로 전달하면서 exit함수를 호출한다. 그리고 0과 1을 대신해서 각각 다음을 인자로 전달해도 된다.


⊙ EXIT_SUCCESS -> 0

⊙ EXIT_FAILURE -> 1


이 둘은 매크로로 정의 된 상수이다. 각각 0과 1을 의미한다.

그리고 exit 함수를 호출하면서 인자로 전달하는 값은 main 함수에서 return 문을 통해 반환하는 값과 동일한 의미를 지닌다. 


※ 두 함수 모두 운영체제로 값이 넘어가서 프로그램의 정상 종료 여부를 판단하는데 사용된다.



'Programming > C' 카테고리의 다른 글

qsort 함수 사용법  (0) 2013.02.15
qsort (Quick Sort) 함수.  (0) 2013.02.15
함수 포인터를 반환하는 함수의 정의  (0) 2013.02.15
함수 포인터  (0) 2013.02.15
메모리 컨트롤 함수. memmove, memcpy  (0) 2013.02.15
Posted by scii
:

아래의 코드에서 void (*RetFctPtr (int))(void); 라는 함수의 선언이 보인다.

이것을 풀어서 설명하면, "RetFctPtr의 함수는 매개변수로 int형 자료를 하나 받을 수 있고 함수의 반환형으로 반환형과 매개변수 형이 void인 함수의 포인터이다." 라고 풀어서 말 할 수 있다.


void (*RetFctPtr (int))(void);


함수의 이름        : RetFunPtr

함수의 매개변수  : int형 변수 하나

함수의 반환형     : 반환형과 매개변수 형이 void인 함수의 포인터








typedef 선언과 함수 포인터를 반환하는 

함수의 정의




배열 및 배열 포인터 형의 typedef 선언과 구조가 매우 유사하다.


※ typedef로 새로운 이름을 만들어서 쓰면 정말 편한데 모든 사람들이 typedef로 정의해서 쓰는 것이 아니기 때문에 위의 함수의 정의도 기억해야 한다.


'Programming > C' 카테고리의 다른 글

qsort (Quick Sort) 함수.  (0) 2013.02.15
atexit 함수, exit 함수, abort 함수  (2) 2013.02.15
함수 포인터  (0) 2013.02.15
메모리 컨트롤 함수. memmove, memcpy  (0) 2013.02.15
volatile 과 restict  (0) 2013.02.15
Posted by scii
: