디시인사이드 갤러리

갤러리 이슈박스, 최근방문 갤러리

갤러리 본문 영역

C언어 문자열 조작 함수 소스코드

☆단비☆갤로그로 이동합니다. 2024.06.30 11:27:34
조회 117 추천 0 댓글 5


/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 2; tab-width: 2 -*- */
/*
 * c-str.h
 * This file is part of Clair.
 *
 * Copyright (C) 2020-2024 Hodong Kim <hodong@nimfsoft.art>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
#ifndef __C_STR_H__
#define __C_STR_H__

#include "c-macros.h"
#include <stdbool.h>
#include <stddef.h>
#include <uchar.h>
#include <sys/types.h>

#ifdef __cplusplus
#define restrict __restrict__
#endif

C_BEGIN_DECLS

char     *c_strdup          (const char *str);
char     *c_strndup         (const char *str, size_t len);

char     *c_str_strip       (const char *str);
bool      c_str_chomp       (char *str);
bool      c_str_contains_c  (const char *str, char c);
bool      c_str_contains_s  (const char *str, char *s);
bool      c_str_equal       (const char *a,   const char *b);
/* terminated with nullptr */
char     *c_str_join        (const char *str, ...);
bool      c_str_starts_with (const char *str, const char *prefix);
bool      c_str_ends_with   (const char *str, const char *suffix);
char     *c_str_rep         (const char *s, const char *s1, const char *s2);
char    **c_str_split       (const char *str, char delim);
char     *c_str_sprintf     (const char * restrict format, ...);

char    **c_strv_dup        (char **strv);
void      c_strv_free       (char **strv);
unsigned  c_strv_len        (char **strv);
bool      c_strv_contains   (const char **strv, const char *str);
char*     c_strv_join       (const char** strv, const char* separator);

size_t    c_utf8_strlen     (const char *utf8);
size_t    c_utf8_strnlen    (const char *utf8, size_t max_n_bytes);
void      c_utf8_strncpy    (char * restrict dst,
                             const char * restrict src,
                             size_t n_chars);
char     *c_utf8_prev_char  (const char *utf8);
char     *c_utf8_next_char  (const char *utf8);
char     *c_utf8_offset_to_pointer (const char *utf8, size_t offset_in_chars);
char     *c_char32_to_utf8  (const char32_t *char32, int n_char32s);
int       c_char32_to_utf8_buf (char32_t* char32, char* buf, int n_char32s);
char32_t* c_utf8_to_char32  (const char* utf8);
int       c_utf8_collate    (const char* restrict s1,
                             const char* restrict s2);

typedef struct _CString  CString;
struct _CString {
  char*  str;
  size_t len;
  size_t capa;
  bool   free_str;
};

CString* c_string_new       (const char* str, bool free_str);
char*    c_string_free      (CString* string);
void     c_string_append    (CString* string, const char* str);
void     c_string_append_c  (CString* string, char c);
void     c_string_assign    (CString* string, const char* str);
void     c_string_assign_n  (CString* string, const char* str, size_t n);
void     c_string_insert_c  (CString* string, ssize_t pos, char c);
void     c_string_erase     (CString* string, ssize_t pos, ssize_t len);
void     c_string_insert    (CString* string, ssize_t pos, const char* str);
void     c_string_overwrite (CString* string, size_t  pos, const char* str);

C_END_DECLS

#endif /* __C_STR_H__ */





/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 2; tab-width: 2 -*- */
/*
 * c-str.c
 * This file is part of Clair.
 *
 * Copyright (C) 2020-2024 Hodong Kim <hodong@nimfsoft.art>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
#include "c-str.h"
#include "c-mem.h"
#include "c-array.h"
#include "c-log.h"
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>

#define C_STRING_MIN_CAPA  16

char *c_str_strip (const char *str)
{
  if (!str)
    return NULL;

  while (*str && isspace (*str))
    str++;

  char *new_str = c_strdup (str);

  c_str_chomp (new_str);

  return new_str;
}

bool c_str_chomp (char *str)
{
  char *p;
  bool  retval = false;

  p = str + strlen (str);

  while (p > str)
  {
    p--;

    if (*p == '\t' ||
        *p == '\n' ||
        *p == '\v' ||
        *p == '\f' ||
        *p == '\r' ||
        *p == ' ')
    {
      *p = 0;
      retval = true;
    }
    else
    {
      break;
    }
  }

  return retval;
}

bool c_str_contains_c (const char *str, char c)
{
  for (const char *p = str; *p; p++)
    if (*p == c)
      return true;

  return false;
}

bool c_str_contains_s (const char *str, char *s)
{
  if (!*s)
    return false;

  return strstr (str, s);
}

/* Returns a newly allocated string.
 * example:
 * linkpath = c_str_join (autostart_dir, "/nimf.desktop", nullptr);
 * Free it with free() */
char* c_str_join (const char *str, ...)
{
  va_list ap;
  size_t  offset = 0;
  char*   result = NULL;

  va_start (ap, str);

  for (const char* s = str; s != nullptr; s = va_arg (ap, const char*))
  {
    size_t len = strlen (s);
    result = c_realloc (result, offset + len + 1);
    memcpy (result + offset, s, len);
    offset = offset + len;
  }

  va_end (ap);

  if (result)
    result[offset] = '\0';

  return result;
}

char* c_str_sprintf (const char* restrict format, ...)
{
  char*   result;
  int     len;
  va_list ap;

  va_start (ap, format);
  len = vsnprintf (NULL, 0, format, ap);
  va_end (ap);

  result = c_malloc (len + 1);

  va_start (ap, format);
  vsprintf (result, format, ap);
  va_end   (ap);

  return result;
}

bool c_str_equal (const char *a, const char *b)
{
  if (!a)
  {
    a = "";
    c_log_warning ("The left argument is NULL.");
  }

  if (!b)
  {
    b = "";
    c_log_warning ("The right argument is NULL.");
  }

  return strcmp (a, b) == 0;
}

bool c_str_starts_with (const char *str, const char *prefix)
{
  while (*prefix)
  {
    if (*str != *prefix)
      return false;

    str++;
    prefix++;
  }

  return true;
}

bool c_str_ends_with (const char *str, const char *suffix)
{
  size_t len1 = strlen (str);
  size_t len2 = strlen (suffix);

  if (len1 < len2)
    return false;

  return !strncmp (str + len1 - len2, suffix, len2);
}

char *c_strdup (const char *str)
{
  void *mem = strdup (str);

  if (mem)
    return mem;

  perror (__PRETTY_FUNCTION__);
  abort ();
}

char *c_strndup (const char *str, size_t len)
{
  void *mem = strndup (str, len);

  if (mem)
    return mem;

  perror (__PRETTY_FUNCTION__);
  abort ();
}

char **c_str_split (const char *str, char c)
{
  CArray *array;
  const char *p;
  const char *mark;

  array = c_array_new (NULL, false);
  p = str;

  while (1)
  {
    mark = strchr (p, c);

    if (mark)
    {
      c_array_add (array, c_strndup (p, mark - p));
      p = mark + 1;
    }
    else
    {
      c_array_add (array, c_strdup (p));
      break;
    }
  }

  c_array_add (array, NULL);

  return (char **) c_array_free (array);
}

static char* c_str_resize_capa (char* str, size_t* capa, size_t req_len)
{
  size_t old_capa = *capa;

  while (req_len > *capa)
    *capa *= 2;

  while (req_len + C_STRING_MIN_CAPA < *capa / 4)
    *capa = *capa / 2;

  if (*capa != old_capa)
    str = c_realloc (str, *capa);

  return str;
}

char* c_str_rep (const char* s, const char* s1, const char* s2)
{
  char*  str;
  char*  p;
  size_t capa = C_STRING_MIN_CAPA;
  size_t str_len = 0;
  size_t s1_len = strlen (s1);
  size_t s2_len = strlen (s2);

  str = c_malloc (capa);

  while ((p = strstr (s, s1)))
  {
    size_t diff = p - s;

    if (diff)
    {
      str = c_str_resize_capa (str, &capa, str_len + diff + 1);
      /* Copy the front part. */
      memcpy (str + str_len, s, diff);
      str_len = str_len + diff;
    }

    /* Insert the middle part. */
    str = c_str_resize_capa (str, &capa, str_len + s2_len + 1);
    memcpy (str + str_len, s2, s2_len);
    str_len = str_len + s2_len;

    s = p + s1_len;
  }

  /* Copy the back part. */
  size_t s_len = strlen (s);
  str = c_str_resize_capa (str, &capa, str_len + s_len + 1);
  memcpy (str + str_len, s, s_len);
  str_len = str_len + s_len;

  str[str_len] = '\0';
  str = c_realloc (str, str_len + 1);

  return str;
}

char **c_strv_dup (char **strv)
{
  if (strv == NULL)
    return NULL;

  CArray *array = c_array_new (NULL, false);

  for (int i = 0; strv[i]; i++)
    c_array_add (array, c_strdup (strv[i]));

  c_array_add (array, NULL);

  return (char **) c_array_free (array);
}

void c_strv_free (char **strv)
{
  if (strv == NULL)
    return;

  for (int i = 0; strv[i]; i++)
    free (strv[i]);

  free (strv);
}

unsigned c_strv_len (char **strv)
{
  unsigned i = 0;
  while (strv[i]) i++;
  return i;
}

bool c_strv_contains (const char **strv, const char *str)
{
  for (int i = 0; strv[i]; i++)
    if (c_str_equal (strv[i], str))
      return true;

  return false;
}

char* c_strv_join (const char** strv, const char* separator)
{
  CString* string = c_string_new ("", false);

  for (int i = 0; strv[i]; i++)
  {
    if (i && separator)
      c_string_append (string, separator);

    c_string_append (string, strv[i]);
  }

  return c_string_free (string);
}

size_t c_utf8_strlen (const char *utf8)
{
  size_t len = 0;

  while (*utf8)
  {
    if ((*utf8 & 0b11000000) != 0b10000000)
      len++;

    utf8++;
  }

  return len;
}

size_t c_utf8_strnlen (const char *utf8, size_t max_n_bytes)
{
  size_t len = 0;
  const char *p = utf8;

  while (*p && p - utf8 < max_n_bytes)
  {
    if ((*p & 0b11000000) != 0b10000000)
      len++;

    p++;
  }

  return len;
}

void c_utf8_strncpy (char * restrict dst,
                     const char * restrict src,
                     size_t n_chars)
{
  if (!n_chars)
    return;

  while (*src && n_chars)
  {
    *dst = *src;

    dst++;
    src++;

    if ((*src & 0b11000000) != 0b10000000)
      n_chars--;
  }

  *dst = 0;
}

char *c_utf8_prev_char (const char *utf8)
{
  if (!utf8)
    return NULL;

  do {
    utf8--;
  } while ((*utf8 & 0b11000000) == 0b10000000);

  return (char *) utf8;
}

char *c_utf8_next_char (const char *utf8)
{
  if (!utf8)
    return NULL;

  while (*utf8)
  {
    utf8++;

    if ((*utf8 & 0b11000000) != 0b10000000)
      break;
  }

  if (*utf8)
    return (char *) utf8;

  return NULL;
}

char *c_utf8_offset_to_pointer (const char *utf8, size_t offset_in_chars)
{
  while (*utf8 && offset_in_chars > 0)
  {
    utf8++;
    if ((*utf8 & 0b11000000) != 0b10000000)
      offset_in_chars--;
  }

  return (char *) utf8;
}

char32_t *c_utf8_to_char32 (const char *utf8)
{
  if (!utf8)
    return NULL;

  size_t len  = 0;
  size_t capa = 8;
  char32_t *c32 = c_malloc (capa * sizeof (char32_t));

  while (*utf8)
  {
    if (capa < len + 5)
    {
      capa *= 2;
      c32 = c_realloc (c32, capa * sizeof (char32_t));
    }

    if ((*utf8 & 0b10000000) == 0)
    {
      c32[len++] = *utf8++;
    }
    else
    {
      if ((*utf8 & 0b11110000) == 0b11110000)
      {
        c32[len]    = (*utf8++ & 0b00000111) << 18;
        c32[len]   |= (*utf8++ & 0b00111111) << 12;
        c32[len]   |= (*utf8++ & 0b00111111) << 6;
        c32[len++] |= (*utf8++ & 0b00111111);
      }
      else if ((*utf8 & 0b11100000) == 0b11100000)
      {
        c32[len]    = (*utf8++ & 0b00001111) << 12;
        c32[len]   |= (*utf8++ & 0b00111111) << 6;
        c32[len++] |= (*utf8++ & 0b00111111);
      }
      else if ((*utf8 & 0b11000000) == 0b11000000)
      {
        c32[len]    = (*utf8++ & 0b00011111) << 6;
        c32[len++] |= (*utf8++ & 0b00111111);
      }
    }
  }

  c32 = c_realloc (c32, (len + 1) * sizeof (char32_t));
  c32[len] = 0;

  return c32;
}

int c_char32_strcmp (const char32_t * restrict a, const char32_t * restrict b)
{
  while (*a)
  {
    if (*a != *b)
      break;

    a++;
    b++;
  }

  return *a - *b;
}

int c_utf8_collate (const char * restrict s1, const char * restrict s2)
{
  char32_t *a, *b;

  a = c_utf8_to_char32 (s1);
  b = c_utf8_to_char32 (s2);

  int retval = c_char32_strcmp (a, b);

  free (a);
  free (b);

  return retval;
}

static int c_1char32_to_utf8_buf (char32_t char32, char* buf)
{
  int len = 0;

  if (char32 == 0)
  {
    /* do nothing */
  }
  else if (char32 < 0x0080)
  { /* 1-byte */
    buf[len++] = char32;
  }
  else if (char32 < 0x0800)
  { /* 2-byte */
    buf[len++] = 0b11000000 | (char32 >> 6);
    buf[len++] = 0b10000000 | (char32 & 0b00111111);
  }
  else if (char32 < 0x10000)
  { /* 3-byte */
    buf[len++] = 0b11100000 | (char32 >> 12);
    buf[len++] = 0b10000000 | (char32 >>  6 & 0b00111111);
    buf[len++] = 0b10000000 | (char32       & 0b00111111);
  }
  else if (char32 < 0x110000)
  { /* 4-byte */
    buf[len++] = 0b11110000 | (char32 >> 18);
    buf[len++] = 0b10000000 | (char32 >> 12 & 0b00111111);
    buf[len++] = 0b10000000 | (char32 >>  6 & 0b00111111);
    buf[len++] = 0b10000000 | (char32       & 0b00111111);
  }
  else
  {
    c_log_warning ("Cannot convert 0x%x to UTF-8.", char32);
    len += c_1char32_to_utf8_buf (0xfffd, buf);
  }

  buf[len] = 0;

  return len;
}

int c_char32_to_utf8_buf (char32_t* char32, char* buf, int n_char32s)
{
  if (!char32)
    return 0;

  int len = 0;

  for (int i = 0; (n_char32s < 0 || i < n_char32s) && char32[i]; i++)
    len += c_1char32_to_utf8_buf (char32[i], buf + len);

  buf[len] = '\0';

  return len;
}

char *c_char32_to_utf8 (const char32_t *char32, int n_char32s)
{
  if (!char32)
    return NULL;

  char *utf8;
  int   len  = 0;
  int   capa = 8;

  utf8 = c_malloc (capa * sizeof (char));

  for (int i = 0; (n_char32s < 0 || i < n_char32s) && char32[i]; i++)
  {
    if (capa < len + 5)
    {
      capa *= 2;
      utf8 = c_realloc (utf8, capa * sizeof (char));
    }

    len += c_1char32_to_utf8_buf (char32[i], utf8 + len);
  }

  utf8[len] = '\0';

  return c_realloc (utf8, len + 1);
}

CString* c_string_new (const char* str, bool free_str)
{
  CString* string = c_malloc (sizeof (CString));

  string->capa     = C_STRING_MIN_CAPA;
  string->str      = c_malloc (string->capa);
  string->len      = 0;
  string->free_str = free_str;

  c_string_assign (string, str);

  return string;
}

char *c_string_free (CString *string)
{
  if (!string)
    return NULL;

  char *str;

  string->str = c_realloc (string->str, string->len + 1);
  str = string->str;

  if (string->free_str)
  {
    free (str);
    str = NULL;
  }

  free (string);

  return str;
}

static void c_string_resize_capa (CString *string, size_t req_len)
{
  size_t old_capa = string->capa;

  while (req_len > string->capa)
    string->capa *= 2;

  while (req_len + C_STRING_MIN_CAPA < string->capa / 4)
    string->capa = string->capa / 2;

  if (string->capa != old_capa)
    string->str = c_realloc (string->str, string->capa);
}

void c_string_append (CString *string, const char *str)
{
  size_t len = strlen (str);

  if (len > 0)
  {
    c_string_resize_capa (string, string->len + len + 1);
    memcpy (string->str + string->len, str, len + 1);
    string->len += len;
  }
}

void c_string_append_c (CString *string, char c)
{
  string->len++;
  c_string_resize_capa (string, string->len + 1);
  string->str[string->len - 1] = c;
  string->str[string->len] = 0;
}

void c_string_assign (CString *string, const char *str)
{
  string->len = strlen (str);
  c_string_resize_capa (string, string->len + 1);
  memcpy (string->str, str, string->len + 1);
}

void c_string_assign_n (CString* string, const char* str, size_t n)
{
  c_string_resize_capa (string, n + 1);
  memcpy (string->str, str, n);
  string->str[n] = '\0';
}

void c_string_insert_c (CString *string, ssize_t pos, char c)
{
  /* save */
  uint8_t *save = c_malloc (string->len - pos);
  memcpy (save, string->str + pos, string->len - pos);
  /* realloc */
  string->len += 1;
  c_string_resize_capa (string, string->len + 1);
  /* copy */
  memcpy (string->str + pos, &c, 1);
  memcpy (string->str + pos + 1, save, string->len - 1 - pos);
  string->str[string->len] = 0;

  free (save);
}

void c_string_erase (CString *string, ssize_t pos, ssize_t len)
{
  if (len == 0)
    return;

  if (pos > string->len)
  {
    c_log_warning ("pos  >  string->len");
    return;
  }

  if (len == -1)
  {
    string->len = pos;
    c_string_resize_capa (string, string->len + 1);
    string->str[string->len] = 0;
    return;
  }

  memmove (string->str + pos,
           string->str + pos + len,
           string->len - pos - len);
  string->len -= len;
  c_string_resize_capa (string, string->len + 1);
  string->str[string->len] = 0;
}

void c_string_insert (CString *string, ssize_t pos, const char *str)
{
  /* save */
  uint8_t *save = c_malloc (string->len - pos);
  memcpy (save, string->str + pos, string->len - pos);
  /* realloc */
  size_t len = strlen (str);
  string->len += len;
  c_string_resize_capa (string, string->len + 1);
  /* copy */
  memcpy (string->str + pos, str, len);
  memcpy (string->str + pos + len, save, string->len - len - pos);
  string->str[string->len] = 0;

  free (save);
}

void c_string_overwrite (CString *string, size_t pos, const char *str)
{
  size_t len = strlen (str);

  if (len > string->len - pos)
  {
    string->len = len + pos;
    c_string_resize_capa (string, string->len + 1);
  }

  memcpy (string->str + pos, str, len);
  string->str[string->len] = 0;
}

추천 비추천

0

고정닉 0

0

댓글 영역

전체 댓글 0
등록순정렬 기준선택
본문 보기

하단 갤러리 리스트 영역

왼쪽 컨텐츠 영역

갤러리 리스트 영역

갤러리 리스트
번호 제목 글쓴이 작성일 조회 추천
설문 외모와 달리 술 일절 못 마셔 가장 의외인 스타는? 운영자 24/07/01 - -
2720854 쉐스파-수퍼높아 발명도둑잡기갤로그로 이동합니다. 07.02 66 0
2720853 [유레카] 금리 오르면 대통령 지지율은 떨어진다 / 정남구 발명도둑잡기갤로그로 이동합니다. 07.02 21 0
2720852 [포르코의 뷰] 금리와 선거 발명도둑잡기갤로그로 이동합니다. 07.02 19 0
2720851 시소닉 a120 power분해 도리스아(220.74) 07.02 37 0
2720850 gpt한테 칭찬들어서 자랑한다 [1] 프갤러(14.39) 07.02 88 0
2720849 주일 미군, 미성년자 상대로...日 정부 태도에 더 '분노' [1] 발명도둑잡기갤로그로 이동합니다. 07.02 36 0
2720848 ‘윤 대통령 탄핵 청원’ 60만 돌파···1만명 ‘접속 대기’도 발명도둑잡기갤로그로 이동합니다. 07.02 43 0
2720847 컴공형님들 살려주십쇼 제발 [5] 프갤러(221.139) 07.02 133 0
2720846 쿠팡 대리점, 숨진 택배기사 유족에 “저라면 산재 신청 안 한다” 발명도둑잡기갤로그로 이동합니다. 07.02 43 0
2720845 보통 초급 벗어날려면 몇개월? 몇년걸림? [2] 프갤러(27.119) 07.02 79 0
2720842 '사망9명' 시청역 인근서 인도에 차량 돌진‥이 시각 현장 발명도둑잡기갤로그로 이동합니다. 07.02 56 0
2720841 윤석열이 머 잘못했다고 탄핵이래? ㅇㅅㅇ [1] ㅇㅅㅇ(106.102) 07.02 37 0
2720840 박스 줍는 노인 입갤이요 ㅇㅅㅇ ㅇㅅㅇ(106.102) 07.02 24 0
2720838 23살 경험 많겠지? 어디까지 했을까? ㅇㅇ(223.39) 07.02 78 0
2720837 다극체제보다 각국의 자주화가 낫다 발명도둑잡기갤로그로 이동합니다. 07.02 19 0
2720835 신석기 시대의 가상일기 발명도둑잡기갤로그로 이동합니다. 07.02 49 0
2720832 깻? ♥냥덩Pay♥갤로그로 이동합니다. 07.02 47 0
2720828 코딩이 재밌는 사람 특징 ㅇㅇ갤로그로 이동합니다. 07.02 95 0
2720827 윤석열 탄핵소추안 청원자수 실시간 집계 발명도둑잡기갤로그로 이동합니다. 07.02 22 0
2720825 지방의회 '관광지' 일색 해외출장‥"의원은 놀아도 나가 놀아야" 발명도둑잡기갤로그로 이동합니다. 07.02 25 0
2720823 공항 '단골'된 의장님‥외유 '끝판왕' 지방의회 발명도둑잡기갤로그로 이동합니다. 07.02 19 0
2720820 ’꽃테크·외유성 출장' 이태인 동대문구의장 선출 규탄 성명 및 기자회견 발명도둑잡기갤로그로 이동합니다. 07.02 39 0
2720818 4년제 나오면 그래도... [3] 프갤러(125.244) 07.02 103 0
2720816 "당연히 리필제품이 더 싼 줄 알았는데…" 황당한 가격표 발명도둑잡기갤로그로 이동합니다. 07.02 25 0
2720815 건실한 솔루션 있는 회사 vs 사이즈 큰 웹에이전시 [1] 프갤러(118.235) 07.02 39 0
2720814 오늘의 예술 오브제: 애인이나 지인에게 화석을 선물 발명도둑잡기갤로그로 이동합니다. 07.02 24 0
2720813 콘크리트 반지로 공개청혼한 中엔지니어…누리꾼 '갑론을박' 발명도둑잡기갤로그로 이동합니다. 07.02 33 0
2720811 '납치'되어 군에 끌려간 탈춤을 사랑한 한양대생 발명도둑잡기갤로그로 이동합니다. 07.02 37 0
2720810 유니스왑 만드는 무료강의 공유 고도전도사갤로그로 이동합니다. 07.02 33 0
2720808 여기 조현병 갤러리임?? [6] ㅇㅇ갤로그로 이동합니다. 07.02 106 1
2720807 로자룩셈부르크 반동 관리자에게 곧 검열삭제 당할 프랑스 총선 글 발명도둑잡기갤로그로 이동합니다. 07.02 48 0
2720806 요즘 분위기가 구로쪽에 3천대로 취업해도 감지덕지 상황이야? [1] 프갤러(14.39) 07.02 122 0
2720804 나는 코딩이 싫다. 그래도 해내려고 한다. [6] ㅇㅇ(118.235) 07.02 110 1
2720802 디씨앱 안써봤는데 무조건 웹뷰겠지?? [3] 프갤러(223.38) 07.02 78 0
2720801 리액트네이티브로 풀스택 앱 만드는 무료강의 공유 [5] 고도전도사갤로그로 이동합니다. 07.01 62 1
2720800 리액트네이티브 너무 좆같다 [5] 프갤러(223.38) 07.01 103 0
2720799 내가 몰라서 묻는데 우분투 쓰면 온라인 쇼핑몰 결제 됨? [5] 프갤러(14.39) 07.01 57 0
2720798 개발자라면 [4] 프갤러(223.38) 07.01 98 0
2720797 전공 비전공이 중요한게 아님 [1] ㅇㅇ(114.30) 07.01 80 1
2720796 솔직히 IT는 대기업 갈 필요 없다고 하지만 큰회사 가고싶다 프갤러(112.150) 07.01 63 0
2720794 SAP 독학 가능하냐?? [3] ㄴㅁㄻ(211.234) 07.01 46 0
2720793 프론트엔드 국비출신 6년차 현실적인 연봉 [7] 프갤러(117.111) 07.01 186 1
2720792 솔까 비전공이면 키비갤로그로 이동합니다. 07.01 38 0
2720791 밑에 30대 신입 웹개발 하려는 게2야... code1350(211.234) 07.01 115 1
2720790 스위스 산중호수 스케이트 발명도둑잡기갤로그로 이동합니다. 07.01 19 0
2720788 경력직도 지금 취업 한파 인듯 ert(211.234) 07.01 65 0
2720787 일단 올림 프갤러(175.119) 07.01 40 0
2720786 파이썬도 객체지향언어임?? [1] ㅇㅇ8갤로그로 이동합니다. 07.01 90 0
2720785 오늘의 소설, 영화 실마리: 팔레스타인, 우크라이나 전쟁 중 동성애 발명도둑잡기갤로그로 이동합니다. 07.01 18 0
2720784 오늘의 음악 기획 실마리: 미 네이비실 자살 부른 폭발음 들려주는 노래 발명도둑잡기갤로그로 이동합니다. 07.01 18 0
갤러리 내부 검색
제목+내용게시물 정렬 옵션

오른쪽 컨텐츠 영역

실시간 베스트

1/8

뉴스

디시미디어

디시이슈

1/2