우연히 Junior, Senior, Lazy 프로그래머를 구분하는 

코딩에 대한 글을 보았다. 

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

물론 EDW519를 보다가 생각이 났다. 

====

Junior Programmer:
if (m==1){Month="January")}
if (m==2){Month="February")}
if (m==3){Month="March")}
if (m==4){Month="April")}
if (m==5){Month="May")}
if (m==6){Month="June")}
if (m==7){Month="July")}
if (m==8){Month="August")}
if (m==9){Month="September")}
if (m==10){Month="October")}
if (m==11){Month="November")}
if (m==12){Month="December")}
---------------------------------------------------------------
Senior Programmer:
switch(m)
{
case 1:
Month = "January"
break;
case 2:
Month = "February"
break;
case 3:
Month = "March"
break;
case 4:
Month = "April"
break;
case 5:
Month = "May"
break;
case 6:
Month = "June"
break;
case 7:
Month = "July"
break;
case 8:
Month = "August"
break;
case 9:
Month = "September"
break;
case 10:
Month = "October"
break;
case 11:
Month = "November"
break;
case 12:
Month = "December"
break;
default:
Month = "unknown"
}
---------------------------------------------------------------
Lazy Programmer:
MonthNames == ["","January","February","March",...]
Month = MonthNames[m]


====

위의 글을 볼때만 해도 음... 보기가 깔끔해서 그런건가 싶었다. 

뭔가 성능적인 문제도 있겠지만..

아래의 글을 보면서 난 아직도 형편없나보다 싶어서 찾게 되었다. 


Signs You’re a Crappy Programmer

==> You execute too much code because you don’t know the difference between “if” and “case”.


매우 많은 코드를 실행한다면 당신은 형편없는 프로그래머, 

왜냐면, 당신은 if와 case의 차이를 모르기때문에..


그렇다.. 난 여태 if와 case문의 차이점에 대해서 알려는 시도조차 안했다. OTL..


그래서 구글링으로 뒤적이다보니 아래의 링크에 아주 기가 막히게 설명을 해두었다.

http://blog.naver.com/PostView.nhn?blogId=kki2406&logNo=80041410085

완전 감사한마음으로 읽었고 요약하면 대략 이렇다. 


1. 성능을 향상시키느냐, 메모리 사용량을 줄이느냐의 문제가 있다.

  -  성능이 중요한 경우 : switch case문을 사용

  -  메모리 사용을 줄이고자 하는 경우 : if else문을 사용


2. swtich-case문의 특성

  - case값은 가급적 순차적으로 감소 혹은 증가하는 것이 메모리 관리면에서 좋다. 

  - case문의 개수가 4 미만이면 jump table을 사용하지 않고 그 이상이면 jump table을 사용한다.

    물론 사용하지 않는것이 성능면에서 좋을것 같다.

  - 1,2,3,1000 이런 경우에는 1,2,3에 대한 table을 생성하고 진입할 때, 1000은 따로 분기함.

  - gcc 4.4.3의 경우에는 table을 생성하지 않는다..는 추가내용까지


위의 내용은 링크된 블로그에 assembly 코드를 가지고 설명을 해뒀는데 

참.. 볼수록 잘 썼다. ㅋㅋ


이어서 클라이언트에서는 아래와 같습니다. 

IP주소, 포트번호, 파일 경로 및 인자 값 입력 받는 등의 추가 옵션은

코드를 약간만 변경하시면 됩니다.


해더파일은

#include <netinet/in.h>

#include <arpa/inet.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

----

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

    int client_len;
    int client_sockfd;
    char buf[256];
    struct sockaddr_in clientaddr;

    clientaddr.sin_family = AF_INET;
    clientaddr.sin_addr.s_addr = inet_addr("100.10.1.57");
    clientaddr.sin_port = htons(8002);
    client_len = sizeof(clientaddr);

    client_sockfd = socket(AF_INET, SOCK_STREAM, 0);

    if (connect (client_sockfd, (struct sockaddr *)&clientaddr,
                client_len) < 0)
    {
        perror("connect error :");
        exit(0);
    }

    int nbyte;
    size_t filesize = 0, bufsize = 0;
    FILE *file = NULL;

    file = fopen("test.jpg", "wb");

    ntohl(filesize);
    recv(client_sockfd, &filesize, sizeof(filesize), 0);
    printf("file size = [%d]\n", filesize);
    bufsize = 256;
    while(filesize != 0)
    {
        if(filesize < 256)
            bufsize = filesize;

        nbyte = recv(client_sockfd, buf, bufsize, 0);
        filesize = filesize -nbyte;

        fwrite(buf, sizeof(char), nbyte, file);

        nbyte = 0;

    }

    close(client_sockfd);
    fclose(file);
    return 0;
}


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

fwrite함수 예제  (0) 2012.11.06
switch case문과 if문의 성능차이  (0) 2012.10.31
바이너리 파일전송 C언어 예제 -클라이언트-  (0) 2012.10.18
바이너리 파일전송 C언어 예제 -서버-  (1) 2012.10.18
itoa 함수 예제  (0) 2012.10.17
strspn 함수 예제  (0) 2012.09.20

파일전송하는데 그냥 write, read를 사용하는 경우에는

TEXT파일만 전송하는 문제가 생겼습니다. 

그래서 바이너리 파일 전송을 해야해서 여기저기 참고해서 작성했습니다. 


참고 : http://altibase.net/66


추가해야할 해더파일은

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

이렇습니다. 


아래의 소스코드가 맘대로 복사되게 해야하는데 방법을 모르겠습니다. 

아시는 분은 좀 알려주시길...


파일 사이즈를 얻는 방식은 2가지가 있습니다. 하나는 주석처리함.

----

int main(int argc, char **argv)
{
    int server_sockfd, client_sockfd;
    int state, client_len;
    size_t fsize = 0, nsize = 0, fpsize = 0;
    size_t fsize2 = 0;
    size_t fsize3 = 0;
    FILE *file = NULL;

    int ret;
    struct stat file_stat;

    struct sockaddr_in clientaddr, serveraddr;

    char buf[256];
    memset(buf, 0x00, 256);
    state = 0;

    client_len = sizeof(clientaddr);

    if ((server_sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        perror("socket error : ");
        exit(0);
    }

    memset(&serveraddr,0x00, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
    serveraddr.sin_port = htons(8002);

    state = bind(server_sockfd , (struct sockaddr *)&serveraddr,
            sizeof(serveraddr));
    if (state == -1) {
        perror("bind error : ");
        exit(0);
    }
    state = listen(server_sockfd, 5);
    if (state == -1) {
        perror("listen error : ");
        exit(0);
    }


    file = fopen("test.jpg", "rb");
    fseek(file, 0, SEEK_END);
    fsize = ftell(file);
    fseek(file, 0, SEEK_SET);

    /*
    ret = lstat("test.jpg", &file_stat);
    if (ret < 0) {
        return -1;
    }
    if (file_stat.st_size == 0) {
        return -1;
    }

    fsize3 = file_stat.st_size;
    printf("file size 1 [%d]\n", fsize);
    printf("file size 2 [%d]\n", fsize3);
    */

    client_sockfd = accept(server_sockfd,
            (struct sockaddr *)&clientaddr, &client_len);
    printf("file size [%d]\n", fsize);
    fsize2 = htonl(fsize);
    printf("file size [%d]\n", fsize2);

    send(client_sockfd, &fsize2, sizeof(fsize), 0);

    while(nsize != fsize)
    {
        fpsize = fread(buf, 1, 256, file);
        nsize = nsize+fpsize;
        send(client_sockfd, buf, fpsize, 0);
    }
    printf("file send \n");
    close(client_sockfd);
    fclose(file);

    return 0;
}


----

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

switch case문과 if문의 성능차이  (0) 2012.10.31
바이너리 파일전송 C언어 예제 -클라이언트-  (0) 2012.10.18
바이너리 파일전송 C언어 예제 -서버-  (1) 2012.10.18
itoa 함수 예제  (0) 2012.10.17
strspn 함수 예제  (0) 2012.09.20
strcmp 함수 예제  (0) 2012.08.17
  1. 2020.05.28 16:13

    비밀댓글입니다

가끔가다가 integer, long, float 타입을 char 형식으로 바꿔야할

일이 생겼습니다.

 

예를 들면 itoa 함수를 찾아보니 따로 존재하지 않았습니다.

물론 구글에 검색하면 비슷한 기능을 수행하는 함수의 예를 확인하실 수 있습니다.

 

본 페이지의 하단에 대략적인 itoa 함수를 나타냈습니다.

하지만 http://www.cfaq.com 웹페이지에서 제안하는 방식은.

snprintf(sprintf) 함수를 이용하는 것 입니다.

 

예를 들면 아래처럼 사용할 수 있다.

 

char test_char[16] = {0,};
int test_int = 10000;

snprintf( test_char, sizeof(test_char), "%s", test_int);

 

 

 

 

 

#define INT_DIGITS 19		/* enough for 64 bit integer */

char *itoa(i)
     int i;
{
  /* Room for INT_DIGITS digits, - and '\0' */
  static char buf[INT_DIGITS + 2];
  char *p = buf + INT_DIGITS + 1;	/* points to terminating '\0' */
  if (i >= 0) {
    do {
      *--p = '0' + (i % 10);
      i /= 10;
    } while (i != 0);
    return p;
  }
  else {			/* i < 0 */
    do {
      *--p = '0' - (i % 10);
      i /= 10;
    } while (i != 0);
    *--p = '-';
  }
  return p;
}

--------

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

바이너리 파일전송 C언어 예제 -클라이언트-  (0) 2012.10.18
바이너리 파일전송 C언어 예제 -서버-  (1) 2012.10.18
itoa 함수 예제  (0) 2012.10.17
strspn 함수 예제  (0) 2012.09.20
strcmp 함수 예제  (0) 2012.08.17
strchr 함수 예제  (0) 2012.08.14
strspn() : 문자열에서 특정 문자열로 구성된 문자의 수를 구하는 함수

NAME

       strspn, strcspn - search a string for a set of characters


SYNOPSIS

       #include <string.h>


       size_t strspn(const char *s, const char *accept);


       size_t strcspn(const char *s, const char *reject);


#include 
#include 
int main ()
{
    int i;
    char compare_text[] = "123th";
    char character_set[] = "123456th123th";

    i = strspnn (compare_text, character_set);
    printf ("The length of initial number is [%d].\n", i);
    return 0;
}

결과 값은 5가 나옴.

compare_text에는 비교당할 문자열이 들어간다.

character_set에 있는 문자들 중에서 compare_text에 들어있는

문자와 비교해서 개수를 나타냄

==> 단점은 ... 중복된 문자열에 대해서는 카운트를 하지 않는다. 
                    예상으로는 결과가 10이어야 하는데 실제 컴파일 수행하면 5가 결과로 출력됨.





#include "sys/cdefs.h"
#include 

/*
 * Span the string s2 (skip characters that are in s2).
 */
size_t
strspn(s1, s2)
        const char *s1;
        register const char *s2;
{
    register const char *p = s1, *spanp;
    register char c, sc;

    /*
     *   * Skip any characters in s2, excluding the terminating \0.
     *       */
cont:
    c = *p++;
    for (spanp = s2; (sc = *spanp++) != 0;)
        if (sc == c)
            goto cont;
    return (p - 1 - s1);
}


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

바이너리 파일전송 C언어 예제 -서버-  (1) 2012.10.18
itoa 함수 예제  (0) 2012.10.17
strspn 함수 예제  (0) 2012.09.20
strcmp 함수 예제  (0) 2012.08.17
strchr 함수 예제  (0) 2012.08.14
strdup 함수 예제  (0) 2012.08.14

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 함수 예제  (0) 2012.10.17
strspn 함수 예제  (0) 2012.09.20
strcmp 함수 예제  (0) 2012.08.17
strchr 함수 예제  (0) 2012.08.14
strdup 함수 예제  (0) 2012.08.14
getutxent 함수 예제  (0) 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 함수 예제  (0) 2012.09.20
strcmp 함수 예제  (0) 2012.08.17
strchr 함수 예제  (0) 2012.08.14
strdup 함수 예제  (0) 2012.08.14
getutxent 함수 예제  (0) 2012.08.13
strtok 함수 예제  (0) 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 함수 예제  (0) 2012.08.17
strchr 함수 예제  (0) 2012.08.14
strdup 함수 예제  (0) 2012.08.14
getutxent 함수 예제  (0) 2012.08.13
strtok 함수 예제  (0) 2012.08.06
writev 함수 예제  (0) 2012.07.31

+ Recent posts