strcmp : 2개의 문자열을 비교하는 함수

NAME
       strcmp, strncmp - compare two strings

SYNOPSIS
       #include <string.h>

       int strcmp(const char *s1, const char *s2);

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

 

문자열의 길이를 비교하는것이 아니라 바이트 크기를 비교한다.

 

strcmp(const char *s1, const char *s2);

이러한데 리턴값은 아래와 같다.

s1 = s2 이면 0

s1 > s2 이면 -1

s1 < s2 이면 1

 

예제를 보면 이해하기 쉬울 것 같다.

 

#include 
#include 

int main()
{
    char *temp1 ="HPUX";
    char *temp2="LINUX";
    char *temp3 ="SOLARIS";

    printf("s1[%7s], s1[%7s]  ret =[%2d]\n", temp1, temp2, strcmp(temp1,temp2));
    printf("s2[%7s], s3[%7s]  ret =[%2d]\n", temp2, temp3,  strcmp(temp2,temp3));
    printf("s3[%7s], s1[%7s]  ret =[%2d]\n", temp3, temp1,  strcmp(temp3,temp1));

    return 0;
}
[ 결과 값 ] 
$ ./a.out 
s1[   HPUX], s1[  LINUX]  ret =[-1]
s2[  LINUX], s3[SOLARIS]  ret =[-1]
s3[SOLARIS], s1[   HPUX]  ret =[ 1]

 

 

원시함수 소스코드를

보면 어떤식으로 동작하는지 알 수 있다.

출처 : http://opensource.apple.com/source/Libc/Libc-262/ppc/gen/strcmp.c

 

#import 

/* This routine should be optimized. */

/* ANSI sez:
 *   The `strcmp' function compares the string pointed to by `s1' to the
 *   string pointed to by `s2'.
 *   The `strcmp' function returns an integer greater than, equal to, or less
 *   than zero, according as the string pointed to by `s1' is greater than,
 *   equal to, or less than the string pointed to by `s2'.  [4.11.4.2]
 */
int
strcmp(const char *s1, const char *s2)
{
    for ( ; *s1 == *s2; s1++, s2++)
	if (*s1 == '\0')
	    return 0;
    return ((*(unsigned char *)s1 < *(unsigned char *)s2) ? -1 : +1);
}

 

 

반응형

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

itoa 함수 예제  (468) 2012.10.17
strspn 함수 예제  (3488) 2012.09.20
strchr 함수 예제  (442) 2012.08.14
strdup 함수 예제  (476) 2012.08.14
getutxent 함수 예제  (3681) 2012.08.13

strchr() 함수는 문자열에서 특정문자의 시작 포인터를 알려주는 함수

 

NAME
       strchr, strrchr, strchrnul - locate character in string

SYNOPSIS
       #include <string.h>

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

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

       #define _GNU_SOURCE
       #include <string.h>

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

 

 

의외로 유용하게 쓰일곳이 많을 것 같다.

예제 소스코드를 보면 아래와 같다.

입력하는 문자열은 august wednesday 인데

이중에서 w 문자열을 찾으면 거기의 포인터를 가져온다.

따라서 아래의 코드를 돌려보면 wednesday가 결과로 나옴.

 

 

#include 
#include 

int main()
{
    int delim = 'w';
    char *ret = NULL;
    const char *str = "august wednesday";


    ret = strchr(str, delim);
    if(ret == NULL) {
        printf("No [%c] in string\n", (char)delim);
        return -1;
    }
    else
        printf("Found[%c]\n"
               "Start point==> [%s]\n",
               (char)delim, ret);


    return 0;
}

 

 

이어서 원시코드를 살펴보면

아래와 같다.

출처는 : http://www.koders.com/c/fidD4BECC4286AEE76BCD9BE4C37C3FB8E2A515D529.aspx

#include 

char *
strchr (s, c)
  register const char *s;
  int c;
{
  do {
    if (*s == c)
      {
	return (char*)s;
      }
  } while (*s++);
  return (0);
}

 

반응형

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

strspn 함수 예제  (3488) 2012.09.20
strcmp 함수 예제  (3161) 2012.08.17
strdup 함수 예제  (476) 2012.08.14
getutxent 함수 예제  (3681) 2012.08.13
strtok 함수 예제  (3377) 2012.08.06

strdup()함수는 입력받은 문자열을 복사한 새로운 문자열 포인터를 반환해준다.

 

NAME
       strdup, strndup, strdupa, strndupa - duplicate a string

SYNOPSIS
       #include <string.h>

       char *strdup(const char *s);

       char *strndup(const char *s, size_t n);
       char *strdupa(const char *s);
       char *strndupa(const char *s, size_t n);

 

 

#include 
#include 

int main()
{
    char *me;
    me = strdup("who am I");
    printf("%s\n", me);

    return 0;
}

 

 

[추가 내용]

배열 같은경우

1. char a[] = "test "; 
2. char *a = "test";

1. 문자열 상수의 복사가 이루어져서 스택에 저장. 
2. 문자열 상수의 static 영역의 주소값이 저장이 되기 때문에 리턴값을 사용할수 있다.

 

[함수의 원시 소스코드]

=> strdup.c

출처 : http://opensource.apple.com/source/texinfo/texinfo-4/texinfo/lib/strdup.c?txt

 

 

#if HAVE_CONFIG_H
# include 
#endif

#ifdef STDC_HEADERS
# include 
# include 
#else
char *malloc ();
char *strcpy ();
#endif

/* Return a newly allocated copy of STR,
   or 0 if out of memory. */

char *
strdup (const char *str)
{
  char *newstr;

  newstr = (char *) malloc (strlen (str) + 1);
  if (newstr)
    strcpy (newstr, str);
  return newstr;
}

 

반응형

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

strcmp 함수 예제  (3161) 2012.08.17
strchr 함수 예제  (442) 2012.08.14
getutxent 함수 예제  (3681) 2012.08.13
strtok 함수 예제  (3377) 2012.08.06
writev 함수 예제  (472) 2012.07.31

사용자 관련 정보 검색함수 getutxent()에 대해서
오늘 우연히 사용하게 되어 이에 대한 기록을 남겨놓고 감.

utmp => who 명령어에서 사용함.

wtmp => last 명령어에서 사용함

 

함수를 사용할때 추가해야할 해더파일

#include <utmpx.h>

   

getutxent함수와 관련된 다른 함수들

struct utmpx *getutxent(void);

void setutxent(void);

void endutxent(void);

int utmpxname(const char *file);     => file - 교체할 파일이름이 매개변수로 넘어간다. 

   

 getutxent 함수는 /var/adm/utmpx 파일에서 로그인 정보를 순차적으로 읽어들임.

 setutxent 함수는 /var/adm/utmpx 파일의 오프셋을 파일의 시작에 위치시킴.

 endutxent 함수는 /var/adm/utmpx 위에서 열었던 파일을 닫는다.

 utmpxname 함수는 로그인 정보 파일을 file로 지정한 다른 파일로 변경.

   

해당 정보가 있는 파일의 경로 (각 OS별)

로그파일

Solaris

HP UX

LINUX

wtmp,utmp

/var/adm/wtmpx

/var/adm/utmpx

/usr/adm/wtmp

/etc/utmp

/var/log/wtmp

/var/run/utmp

   

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

 

#include "sys/types.h"
#include 
#include 

int main(void) {

    struct utmpx *utx;

    printf("-----------------\n");
    printf("   Login User\n");
    printf("-----------------\n");

    while((utx=getutxent()) != NULL) {
        if(utx->ut_type != USER_PROCESS)
            continue;

        printf("%10s %5s\n", utx->ut_user, utx->ut_line);
    }

    return 0;

}
결과화면
$ ./a.out 
-----------------
   Login User
-----------------
  telcosys  tty1
     fresh pts/4
      jeon pts/3

* who 명령의 결과화면
$ who
telcosys tty1         May 17 09:08
fresh    pts/4        Aug 13 14:34 (10.10.101.55)
jeon     pts/3        Aug 13 19:57 (10.10.104.55)

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

   

utmp파일에는 현재 접속중(Telnet ..) 사용자의 정보가 저장되는데,

로그아웃을 하면 이에 대한 정보가 삭제됨.

   

wtmp파일은 로그인시 utmp파일에 쓰이는 것과 같은 정보가 쓰여지고,

사용자가 로그아웃을 하면 정보도 쓰여지게 됨.(updwtmp).

또한 컴퓨터의 리부팅과, 몇몇정보들이 추가로 쓰여짐.

   

 

원본 source 파일을 첨부해서 살펴보면 아래와 같다.

출처 : http://www2.oldlinux.org/Linux.old/Linux-0.98/Yggdrasil-0.98.3/usr/src/sbin/getty_ps/getutent.c

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

 

/* getutxent.c */

#include 
#include 

struct utmpx *
getutxent (void)
{
  return (struct utmpx *) __getutent ();
}
/* getutent.c */


#include "getty.h"

#if defined(RCSID) && !defined(lint)
static char *RcsId =
"@(#)$Id: getutent.c,v 2.0 90/09/19 20:00:51 paul Rel $";
#endif

typedef	struct utmp	UTMP;

static	char	*utmpfil = UTMP_FILE;	/* default utmp file */
static	FILE	*ufp = (FILE *) NULL;	/* file pointer to utmp file */
					/* NULL = no utmp file open  */
static	UTMP	ut;			/* buffer for utmp record */


/*
**	getutent() - get next valid utmp entry
**
**	Returns (UTMP*)NULL if no vaild entry found.
*/

UTMP *
getutent()
{
	if (ufp == (FILE *) NULL)
		if ((ufp = fopen(utmpfil, "r+")) == (FILE *) NULL)
			return((UTMP *) NULL);

	do {
		if (fread((char *)&ut, sizeof(ut), 1, ufp) != 1)
			return((UTMP *) NULL);

	} while (ut.ut_name[0] == '\0');	/* valid entry? */

	return(&ut);
}


/*
**	getutline() - get utmp entry that matches line.
**
**	Returns (UTMP*)NULL if no match found.
*/

UTMP *
getutline(line)
register UTMP *line;
{
	do {
		if (strequal(ut.ut_line, line->ut_line))
			return(&ut);	/* match! */

	} while (getutent() != NULL);

	return((UTMP *) NULL);
}


/*
**	setutent() - rewind utmp back to beginning
*/

void
setutent()
{
	if (ufp != (FILE *) NULL)
		rewind(ufp);
}

/*
**	endutent() - close utmp file
*/

void
endutent()
{
	if (ufp != (FILE *) NULL) {
		(void) fclose(ufp);
		ufp = (FILE *) NULL;
	}
}

/*
**	utmpname() - change utmp file name to "file"
*/

void
utmpname(file)
register char *file;
{
	endutent();
	utmpfil = strdup(file);
}

/* end of getutent.c */

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

반응형

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

strchr 함수 예제  (442) 2012.08.14
strdup 함수 예제  (476) 2012.08.14
strtok 함수 예제  (3377) 2012.08.06
writev 함수 예제  (472) 2012.07.31
readv 함수 예제  (480) 2012.07.30

이름
       strtok, strtok_r - 문자열에서 토큰들을 뽑아낸다.

사용법
       #include <string.h>

       char *strtok(char *s, const char *delim);

       char *strtok_r(char *s, const char *delim, char **ptrptr);

 

예제를 보면 아래처럼 쉽게 테스트할 수 있다.

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

 

#include 
#include 
#include 

int main()
{
    char *temp = "/home/test/HISTORY/history/test_file";
    char *aa, buf[256];

    strncpy(buf, temp, sizeof(buf));

    printf("before strtok : %s\n", buf);
    aa = strtok(buf, "/");
    printf("after strtok :%s\n", buf);
    printf("result : %s\n", aa);

    return 0;
}

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

위의 함수를 실행한 결과는 아래처럼 나온다.

$ ./a.out
before strtok : /home/test/HISTORY/history/test_file
after strtok :/home
result : home

 

딜리미터로 슬래쉬 '/'를 썼는데

슬래쉬가 2번째 나타나는 부분 이전까지 잘리는 것을 볼 수 있다.

그리고 return 하는 char 포인터는

첫번째 '/'의 다음을 가리키고 있다.

 

 

 

strtok 함수의 실제 코드를 뜯어보면 아래와 같다.

출처 : http://opensource.apple.com/source/Libc/Libc-167/string.subproj/strtok.c

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

 

#include 
#include 

char *
strtok(s, delim)
	register char *s;
	register const char *delim;
{
	register char *spanp;
	register int c, sc;
	char *tok;
	static char *last;


	if (s == NULL && (s = last) == NULL)
		return (NULL);

	/*
	 * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
	 */
cont:
	c = *s++;
	for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
		if (c == sc)
			goto cont;
	}

	if (c == 0) {		/* no non-delimiter characters */
		last = NULL;
		return (NULL);
	}
	tok = s - 1;

	/*
	 * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
	 * Note that delim must have one NUL; we stop if we see that, too.
	 */
	for (;;) {
		c = *s++;
		spanp = (char *)delim;
		do {
			if ((sc = *spanp++) == c) {
				if (c == 0)
					s = NULL;
				else
					s[-1] = 0;
				last = s;
				return (tok);
			}
		} while (sc != 0);
	}
	/* NOTREACHED */
}

 

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

 

 

반응형

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

strdup 함수 예제  (476) 2012.08.14
getutxent 함수 예제  (3681) 2012.08.13
writev 함수 예제  (472) 2012.07.31
readv 함수 예제  (480) 2012.07.30
poll 함수 예제  (150) 2012.07.26

오늘 파일을 하나 지워야 하는데

파일명이 \ 여서 지울라다 보니까

아래와 같은 방법으로 지웠다.

 

% ls -al
total 996
drwxr-xr-x   4 jeon     jeon           1024 Jul 31 14:02 ./
drwxr-xr-x  54 jeon     jeon           2048 May  3 18:30 ../
-rw-r--r--   1 jeon     jeon          21975 Jun 22 13:34 .dependencies
drwxr-xr-x   6 jeon     jeon           1024 Jul 31 12:30 .svn/
-rw-r--r--   1 jeon     jeon           1843 Jan 30  2012 Makefile
-rw-r--r--   1 jeon     jeon            359 Jan 30  2012 \

 

아래와 같이 i 옵션을 추가해서 inode값을 확인한다.

 

% ls -ali
total 996
100149 drwxr-xr-x   4 jeon     jeon           1024 Jul 31 14:02 ./
 97838 drwxr-xr-x  54 jeon     jeon           2048 May  3 18:30 ../
 100792 -rw-r--r--   1 jeon     jeon          21975 Jun 22 13:34 .dependencies
 100150 drwxr-xr-x   6 jeon     jeon           1024 Jul 31 12:30 .svn/
 102895 -rw-r--r--   1 jeon     jeon           1843 Jan 30  2012 Makefile
 113475 -rw-r--r--   1 jeon     jeon            359 Jan 30  2012 \

 

아래와 같은 명령어로 삭제했다.

그런데 권한이 root였는지 어떤거였는지 기억이 나지 않는다.

아마도 루트권한이었을듯...

# find ./ -inum 113475 -exec rm -rf {} \;

 

예전에 실수로 파일명을 $HOME이라고 되어있는거

아무생각없이 rm썼다가 다 날릴뻔해서 저런 식으로 지웠던 기억이 난다..ㅎㄷㄷㄷ

반응형

NAME
       readv, writev - read or write data into multiple buffers

SYNOPSIS
       #include <sys/uio.h>

       ssize_t writev(int fd, const struct iovec *iov, int iovcnt);

소스코드 출처 : http://www.ccplusplus.com/2012/02/writev-example-linux.html

---------------------------------------------------------

 

#include 
#include 
#include 
#include 
#include 
#include "sys/uio.h"

int main(int argc,char **argv) {
    static char part2[] = "THIS IS FROM WRITEV : http://www.ccplusplus.com/";
    static char part3[] = "]\n";
    static char part1[] = "[";
    struct iovec iov[3];

    iov[0].iov_base = part1;
    iov[0].iov_len = strlen(part1);

    iov[1].iov_base = part2;
    iov[1].iov_len = strlen(part2);

    iov[2].iov_base = part3;
    iov[2].iov_len = strlen(part3);

    writev(1,iov,3);

    return 0;
}
수행결과 화면

$ ./a.out 

[THIS IS FROM WRITEV : http://www.ccplusplus.com/]

---------------------------------------------------------

내용 출처 : http://blog.naver.com/playboy999/140117532970

writev 함수는 여러 개의 packet을 쪼게 거나 또는 나누어서 송, 수신한다.

즉 함수의 호출 횟수가 줄어든다. 그러면 성능상의 효율성이 높아진다.

일반적으로 함수의 호출이 일어날 경우 각각의 호출이 stack에 저장되고 함수의 실행이 끝나면 stack에서 pop이 된다. 그럼으로 이러한 stack의 사용의 횟수가 적어짐으로 이점이 발생한다.
그러나 이 부분 보다 전송되는 packet의 수를 줄일 수 있다는 것이 더 큰 이유가 된다.

예를 들어 Nagle algorithm이 off 일 경우를 생각해 보자.

  

   

Nagle algorithm이 off 인 경우 출력 buffer에 data가 들어오자 마자 data를 블록화 하여 전송하기 때문에 각각의 data가 packet화 하여 전송된다. 한번에 블록화 하여 전송할 수 있는 data를 여러 개의 packet으로 나누어 전송한 상황이 된다. 이러한 전송은 전송되는 packet이 적을 경우 문제가 되지 않지만 packet이 많아질 경우 전체 network에 영향을 끼치게 된다.

같은 양의 data를 전송하더라도 여러 packet으로 나누어 전송하면 각각의 packet에 header의 수가 증가함으로 network 입장에서는 traffic의 증가와 수신하는 호스트 입장에서는 처리해야 하는 packet의 수가 증가하는 꼴이 된다.

이러한 경우에 기존의 write함수보다 writev함수를 사용하면 높은 buffer에 저장되어 있는 data를 하나로 블록화하여 전송할 수 있다.

 

 

반응형

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

getutxent 함수 예제  (3681) 2012.08.13
strtok 함수 예제  (3377) 2012.08.06
readv 함수 예제  (480) 2012.07.30
poll 함수 예제  (150) 2012.07.26
GCC 컴파일러 에러 메세지 리스트(Error Message List)  (159) 2012.07.24

read 함수와 매우 동일한 함수다. 

다만 다중 버퍼를 사용할 수 있다는 것만 차이점이다. 


NAME

       readv, writev - read or write data into multiple buffers


SYNOPSIS

       #include <sys/uio.h>


       ssize_t readv(int fd, const struct iovec *iov, int iovcnt);



리턴값 : 성공시 전송한 바이트 수, 실패시 -1 리턴

인자값 :

 - fd : 데이터 전송의 목적지를 나타내는 소켓의 파일 디스크립터를 전달한다.

        반드시 소켓에만 제한되는 함수가 아니다. read, write 함수처럼 파일이나

         콘솔을 입, 출력 대상으로 할 수도 있다.

 - vector : 일반적으로 iovec 구조체 배열의 이름을 인자로 전달하는데, iovec 구조체에는

               전송하고자 하는 데이터에 대한 정보가 담겨진다.

 - count : 데이터를 전송하기 위해 참고할 iovec 구조체 변수의 수를 지정한다. 만약에 3이 인자로
              전달되면, vector가 가리키는 iovec 구조체 변수를 시작으로 총 3개의 iovec 변수를 참고하여

               데이터를 전송하게 된다.



iovec (I/O vector)의 구조체는 /etc/include/sys/uio.h 에 선언되어있다.

       

           struct iovec {

               void  *iov_base;    /* Starting address */

               size_t iov_len;     /* Number of bytes to transfer */

           }

 

 

 


 

간략한 예제는 다음과 같다.

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



#include 
#include 
#include 
#include 
#include 

int main ()
{
    char foo[48], bar[51], baz[49];
    struct iovec iov[3];
    ssize_t nr;
    int fd, i;

    fd = open ("test.txt", O_RDONLY);
    if (fd == -1) {
        perror ("open");
        return 1;
    }

    /* set up our iovec structures */
    iov[0].iov_base = foo;
    iov[0].iov_len = sizeof (foo);
    iov[1].iov_base = bar;
    iov[1].iov_len = sizeof (bar);
    iov[2].iov_base = baz;
    iov[2].iov_len = sizeof (baz);

    /* read into the structures with a single call */
    nr = readv (fd, iov, 3);
    if (nr == -1) {
        perror ("readv");
        return 1;
    }

    for (i = 0; i < 3; i++)
        printf ("%d ==>> %s\n", i, (char *) iov[i].iov_base);

    if (close (fd)) {
        perror ("close");
        return 1;
    }

    return 0;
}
시험결과는 다음과 같다.
$ ./a.out 
0 ==>> LONDON ? The swimmer Dana Vollmer is an unabashe?
1 ==>> d fan of the gymnasts Shannon Miller and Nastia LiuLONDON ? The swimmer Dana Vollmer is an unabashe?
2 ==>> kin, which makes sense. Miller and Liukin won Olyd fan of the gymnasts Shannon Miller and Nastia LiuLONDON ? The swimmer Dana Vollmer is an unabashe?

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

3개의 버퍼를 선언하는데 48, 51, 49 byte로 각기 다른 사이즈로 했다.

1번째 줄은 49 byte 출력

2번째 줄은 100byte 출력

3번째 줄은 149byte 출력


버퍼보다 사이즈가 하나 더 늘어나서 출력되는 것 같은데

마지막에 ? (물음표)가 더해졌다. 이유는 아직 잘 모르겠다. OTL.. 

 

 

반응형

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

strtok 함수 예제  (3377) 2012.08.06
writev 함수 예제  (472) 2012.07.31
poll 함수 예제  (150) 2012.07.26
GCC 컴파일러 에러 메세지 리스트(Error Message List)  (159) 2012.07.24
select 함수 예제  (167) 2012.07.23

+ Recent posts