반응형

안녕하세요.

구글 애즈를 사용해서 게임 앱을 홍보해보았는데, 그 내용을 적어보려고 합니다.

일단 게임을 만들고 보니, 아무도 다운로드하지 않고 주변 지인들에게 홍보해야 겨우 다운로드 수가 조금씩 증가하기 시작했습니다.

검색을 통해 어떻게 게임을 홍보하는지 알아보았는데, 인터넷 커뮤니티(페이스북, 네이버 카페, 게임관련 사이트)나 오늘 다룰 구글 애즈로 홍보하는 방법이 있었습니다.

다음 유튜브 영상에서 확인했습니다.

 

일단 커뮤니티에서 홍보하려면 좀 시간을 두고 활동하면서 해야할 것 같아서, 그나마 빠르게 홍보할 수 있는 구글 애즈를 사용해보기로 했습니다.

마침 프로모션으로 3만원을 사용하면 10만 원 상당의 광고 크레디트를 제공해준다고 해서 일단 3만 원을 충전했습니다.

구글 애즈에 등록하기 위해서 이곳저곳 검색을 해서 확인했었는데, 쉽게 설명해주는 곳은 찾지 못했고, 공부를 많이 해야 할 것 같습니다. 

그래서 경험이라고 생각하고 간단하게 캠페인을 만들었습니다.

타겟 CPA는 100원, 타겟 국가는 아무래도 게임 자체가 영어를 지원하고, 광고단가가 저렴할 것이라고 예상해서 필리핀으로 설정하였습니다.

하루에 10,000원정도 사용할 수 있도록 하고, 2일 6시간 정도 홍보를 하였습니다.

일단 제가 좀 오해한게 타겟 CPA 100원으로 설정하면 앱 설치할 때마다 100원을 받는 게 아니라, 홍보 후 클릭단가에 따라 요금을 지불하는 것 같습니다.

클릭단가는 클릭할때 비용이고, 설치할지 안 할지는 단가에 영향을 받지 않는 것 같아 보였습니다.

그러니까 홍보이미지나 앱 설명을 잘해놓아야 클릭 후 사용자가 설치를 할 수 있을 것 같습니다.

일단 제가 만든 게임은 틀린그림찾기 게임인데, 필리핀에서 클릭단가는 10원 정도였고, 시간 지나니까 8원 9원 정도로 떨어지기도 했는데 최종적으로 10원 정도였습니다.

18,000원 정도 사용했으며, 노출은 9만 5천, 클릭수는 1천8백 정도에 게임 다운로드는 70 정도 올라갔습니다.

총 통계 자료를 보니, 1번 설치될 때 250원 정도 사용되는 것 같습니다.

이건 게임이나 홍보영상이나 홍보 이미지에 따라 다르니 참고만 하시면 될 것 같습니다.

아무래도 무료인 커뮤니티 홍보라 고해도 커뮤니티에 글 올리고, 홍보글 만드는 것도 시간을 써야 하는 작업이니까 설치단가는 그나마 저렴한 편이었던 거 같습니다.

설치 후 애드몹에서 광고 수익을 확인해보았습니다.

하지만..  광고 수익은 0.02달러였습니다.

단순 계산으로 1달러당 1천 원으로 봤을 때 20원였습니다.

광고의 효과는 거의 없었다고 볼 수 있었습니다.

설치 후 거의 재설치도 없는 것 같고, 홍보 끝난 후 거의 접속하는 유저가 없었습니다.

조금 더 많이 광고를 해서 일정 수준 이상 다운로드 수가 증가한다면 더욱 광고수익을 크겠지만, 게임 자체가 너무 단순해서 유저의 재유입을 기대할 수 없었기 때문에 조금 더 콘텐츠를 보충해서 재광 고를 해야겠습니다.

 

 

반응형
반응형

안녕하세요.

오늘은 오브젝트를 따라다니는 HP UI를 만들어 보도록 하겠습니다.

 

 

오브젝트 생성 및 위치 설정

1. 메인 카메라 위치 설정

2. Cube 오브젝트(움직일 오브젝트) 생성 및 위치는 0, 0, 0으로 설정하고 Material을 추가하여 큐브색을 변경합니다.

3. Slider 오브젝트(HP바) 생성 및 설정

1) Handle Silde Area는 비활성화

2) 배경 및 채울색 설정

 

 

스크립트 추가

Cube에 스크립트를 추가합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
 
public class Mover : MonoBehaviour
{
    private GameObject m_goHpBar;
    private float m_fSpeed = 5.0f;
    void Start()
    {
        m_goHpBar = GameObject.Find("Canvas/Slider");
    }
 
    void Update()
    {
        // 테스트를 위한 키보드 이동 시작
        float fHorizontal = Input.GetAxis("Horizontal");
        float fVertical = Input.GetAxis("Vertical");
 
        transform.Translate(Vector3.right * Time.deltaTime * m_fSpeed * fHorizontal, Space.World);
        transform.Translate(Vector3.up * Time.deltaTime * m_fSpeed * fVertical, Space.World);
        // 테스트를 위한 키보드 이동 끝
 
 
        // 오브젝트에 따른 HP Bar 위치 이동
        m_goHpBar.transform.position = Camera.main.WorldToScreenPoint(transform.position + new Vector3(00.8f, 0));
    }
}
 
cs

 

 

 

반응형
반응형

안녕하세요.

저녁식사를 멀 먹을까 하다가, 바람도 강하게 불고 약간 쌀쌀한 날씨가 느껴져서, 

오랜만에 이수역 5번 출구에 있는 담소 소사골 순대국 식당에 방문하게 되었습니다.

앉자마다 일반순대국 2개를 시켰습니다.

담소 소사골 순대육개장에서는 여러 가지 메뉴가 있었습니다.

식사메뉴에는 육개장(7,900)이 신메뉴로 되어있고, 순대국은 일반 순대국(6,700), 소사골 돈순대국(6,900), 소사골 우순대국(7,100) 이렇게 3종류가 있었고, 우렁 얼큰 순두부(6,700) 이 있었습니다.

그리고 3,800원을 추가하면 정식메뉴로 순대와 편육이 나오는 메뉴가 있었고, 담소불고기(전골)(9,800)도 있었습니다.

순대국은 여기 말고도 다른 매장에서 3가지 모두 먹어봤는데, 저는 일반 순대국이 가장 무난했던 거 같습니다.

그리고 매운 것을 잘 못 먹어서 우렁 얼큰 순두부는 입맛에 맛지 않았습니다.

육개장은 다음에 한번 먹어 봐야겠습니다.

순대국이 오기 전에 섞박지(깍두기)와 무채 김치를 그릇에 담았습니다.

약간 많이 익은 박지(깍두기)와 무채 김치라서 덜 익은 김치 종류를 좋아하는 제 입맛에는 맞지 않았습니다.

양념은 들깨가루, 새우젓, 다진 양념, 자른 고추가 있었습니다.

 

잠시 기다린 후 순대국이 나왔습니다.

 

 

저는 매운걸 안 좋아하기 때문에 다진 양념을 거의 빼고 먹었는데도 이미 간이 다되어있어서, 새우젓같은 양념을 넣지 않고 먹었는데, 맛있었습니다.

김치는 익은 김치가 제 취향에 안 맞아서 별로 였습니다.

가격은 6,700이면 적당한 가격인 것 같습니다.(예전엔 더 싼 가격이었는데, 올랐네요.)

전체적으로 만족합니다.

다음에 방문할 때에는 육개장을 한번 먹어봐야겠습니다.

 

연락처 : 02-522-1821

주소 : 서울 서초구 서초대로 12

영업시간 : 매일 00:00 - 24:00 (일요일 야간 휴무)

반응형
반응형

안녕하세요

오늘은 유니티에서 진동을 울리는 방법에 대해 알아보도록 하겠습니다.

퍼즐게임에서 퍼즐을 잘못찾았거나 여러가지 경고를 띄울 때 주로 진동을 울리는 경우가 많이 있습니다.

이럴때 사용하는 진동을 유니티에서도 호출할 수 있습니다.

 

진동 울리는 함수

Handheld.Vibrate();

진동이 울려야 할 위치에 위의 함수를 호출하면 진동이 1초간 울립니다.

 

진동 세부설정

Handheld.Vibrate() 함수를 이용하면, 울리는 시간을 설정할 수 없고 1초간 진동이 울리는 것만 가능합니다.

1초말고 진동울리는 시간과 울리는 패턴 설정할 수 있습니다.

안드로이드 자바 클래스를 사용합니다.

사용하려면 진동권한이 필요합니다.

진동권한 추가를 위해서 매니페스트 수정이 필요합니다.

C:\Program Files\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Apk

이 폴더에서 AndroidManifest.xml파일을 해당 프로젝트 폴더의 Asset\Plugins\Android\에 넣습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.unity3d.player"
    xmlns:tools="http://schemas.android.com/tools"
    android:installLocation="preferExternal">
    <supports-screens
        android:smallScreens="true"
        android:normalScreens="true"
        android:largeScreens="true"
        android:xlargeScreens="true"
        android:anyDensity="true"/>
 
    <application
        android:theme="@style/UnityThemeSelector"
        android:icon="@mipmap/app_icon"
        android:label="@string/app_name">
        <activity android:name="com.unity3d.player.UnityPlayerActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
        </activity>
    </application>
    <uses-permission android:name="android.permission.VIBRATE" />
</manifest>
 
 
cs

VIBRATE권한을 맨 밑에 </application>와 </manifest>사이에 넣으면 됩니다.

1
2
<uses-permission android:name="android.permission.VIBRATE" />
 
 
cs

 

다음 클래스를 추가한 후 사용하면 됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
using System.Collections;
using UnityEngine;
 
public static class Vibration
{
#if UNITY_ANDROID && !UNITY_EDITOR
    public static AndroidJavaClass AndroidPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
    public static AndroidJavaObject AndroidcurrentActivity = AndroidPlayer.GetStatic<AndroidJavaObject>("currentActivity");
    public static AndroidJavaObject AndroidVibrator = AndroidcurrentActivity.Call<AndroidJavaObject>("getSystemService""vibrator");
#endif
    public static void Vibrate()
    {
#if UNITY_ANDROID && !UNITY_EDITOR
        AndroidVibrator.Call("vibrate");
#else
        Handheld.Vibrate();
#endif
    }
 
    public static void Vibrate(long milliseconds)
    {
#if UNITY_ANDROID && !UNITY_EDITOR
        AndroidVibrator.Call("vibrate", milliseconds);
#else
        Handheld.Vibrate();
#endif
    }
    public static void Vibrate(long[] pattern, int repeat)
    {
 
 
#if UNITY_ANDROID && !UNITY_EDITOR
        AndroidVibrator.Call("vibrate", pattern, repeat);
#else
        Handheld.Vibrate();
#endif
    }
 
    public static void Cancel()
    {
#if UNITY_ANDROID && !UNITY_EDITOR
            AndroidVibrator.Call("cancel");
#endif
    }
 
}
 
cs

 

실제 사용 예제

위 스크립트를 Assets폴더에 추가를 합니다.

빈오브젝트를 생성해서 버튼 이벤트에 사용할 스크립트를 추가합니다.

ButtonEvent 스크립트를 다음과 같이 작성합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class ButtonEvent : MonoBehaviour
{
    public void OnClick1()
    {
        Vibration.Vibrate((long)5000);
    }
 
    public void OnClick2()
    {
        long[] pattern = new long[4];
        pattern[0= 1000;
        pattern[1= 200;
        pattern[2= 1000;
        pattern[3= 200;
 
 
        Vibration.Vibrate(pattern, 1);
    }
 
    public void OnClick3()
    {
        long[] pattern = new long[4];
        pattern[0= 1000;
        pattern[1= 5000;
        pattern[2= 2000;
        pattern[3= 1000;
 
 
        Vibration.Vibrate(pattern, -1);
    }
 
    public void OnClick4()
    {
        Vibration.Cancel();
    }
}
 
 
cs

 

1. OnClick1() 함수는 5초동안 진동을 울립니다.

2. OnClick2() 함수는 1초쉬고 0.2초 울리고, 1초 쉬고, 0.2초 울린 후 1초에 한번씩 1초 진동을 반복합니다.

3. OnClick3() 함수는 1초쉬고 5초 울리고, 2초 쉬고, 1초 울린 후 반복되지 않습니다.

4. OnClick4() 함수는 진동 울리는 도중에 진동을 취소합니다.

그 후 버튼을 다음과 같이 4개 추가해서 추가합니다.

버튼에 OnClick1~onClick4를 다음과 같이 넣습니다.

Button에 OnClick1을 넣습니다.

Button (1)에 OnClick2을 넣습니다.

Button (2)에 OnClick3을 넣습니다.

Button (3)에 OnClick4을 넣습니다.

버튼을 누를 때마다 해당되는 이벤트가 실행되는 것을 확인할 수 있습니다.

그리고 검색하다가 Android 8.0(API 레벨 26)이상에서는 다르게 작업을 해야한다고 작업을 해야한다고 찾았는데, 갤럭시 S8(안드로이드 9.0)에서 테스트 했을 때 진동이 안울렸습니다.

혹시나 특정 최신 휴대폰에서 진동이 울리지 않는다면, 다음 웹페이지를 참조하시는 것도 좋을 것 같습니다.

https://gist.github.com/munkbusiness/9e0a7d41bb9c0eb229fd8f2313941564

 

Vibration for Unity3d with Android native Call that supports both the new vibrationEffectClass and the old simple vibrate, with

Vibration for Unity3d with Android native Call that supports both the new vibrationEffectClass and the old simple vibrate, with fallback to Handlheld.Vibrate(). - Vibration.cs

gist.github.com

안드로이드의 vibrate함수 사용은 다음 웹페이지에서 확인할 수 있습니다.

https://developer.android.com/reference/android/os/Vibrator#vibrate(long[],%20int)

 

Vibrator  |  Android 개발자  |  Android Developers

Vibrator public abstract class Vibrator extends Object java.lang.Object    ↳ android.os.Vibrator Class that operates the vibrator on the device. If your process exits, any vibration you started will stop. Summary Public methods abstract void cancel() Turn

developer.android.com

틀린 부분이나 제가 잘못 올린부분은 댓글을 남겨주시면 수정하도록 하겠습니다.

 

반응형
반응형

안녕하세요.

오늘은 강남역에 위치한 이자카야 나무에 대해 적어보겠습니다.

이자카야는 술집인데, 왜 맛집으로 적었은 이유는 여기 누룽지탕이 너무 맛있엇기 때문입니다.

"나무"도 프렌차이드라서 여러군데 많이 있는 것 같습니다.

제가 방문한 곳은 강남 2호점이였습니다.

강남역 4번 출구쪽에 있었습니다.

 

1차로 술한잔먹고 머먹을까하다가 방문하게 되었습니다.

홀은 사진을 못찍엇는데, 술집이니까.. 많이 넓고 지하에 있었습니다.

홀 모습은 다음 페이지에서 확인하실 수 있습니다.

http://www.namulove.co.kr/bbs/content.php?co_id=branch_gangnam2

 

강남2호점 | 이자카야 나무

 

www.namulove.co.kr

메뉴는 다음과 같았습니다.

 

익숙하지 않은 이름의 메뉴들이 많이 있네요.

쇠고기 타다끼(24,500), 철판치즈불닭(24,500), 문어초회(24,000), 참치 타다끼(23,000), 차슈모리(21,500), 깐풍기(21,000), 관자버터야끼(21,000). 매운해물 볶음면(21,000), 차돌숙주볶음(19,500), 오꼬노미야끼(19,000), 에그함박(18,500), 크림치즈불닭(24,500), 크림해물떡볶이(25,000), 명란크림우동(21,000), 명란계란말이(18,500), 해물떡볶이(19,500), 참치육회(19,000), 아끼소바(19,500), 스팸계란후라이(13,000), 타코와사비(11,000), 고구마스틱(11,000), 마구로낫또(13,500), 낫또(7,500)

왕세우튀김(28,000), 에비덴뿌라(24,500), 문어튀김(19,000), 도리가라야게(17,000), 모둠고로케(17,000), 이까게소(15,000), 보리새우깡(13,000), 카카후라이(계절)(17,000), 숯불꼬치 5종(16,500), 숯불꼬치 7종(21,500), 숯불꼬치 9종(25,500),메로소금구이(23,500), 메로간장구이(24,000), 시사모구이(16,500), 반건조오징어구이(12,000), 사천나가사끼 짬뽕나베(26,500), 나가사끼 짬뽕나베(25,500), 요세나베(28,000), 수제비짬뽕탕(25,000), 해물누룽지탕(25,000), 오뎅나베(21,500)

 

여러 술(사케)들이 잔득 있었습니다.

 

누룽지탕에 사실 별로 든게 없는거같았는데, 먹어보니 국물이 정말 맛있었습니다.

소주를 조금 먹어서 먼가 입맛이 무덤덤한 상태였는데도 불구하고 얼큰하고 시원한 맛에 소주도 잘넘어갔습니다.

술안주에도 좋고, 따로 먹어도 맛있을 것 같습니다.

추천합니다.

 

영업시간 : 매일 오후 4:00 ~ 익일 오전 5:00

주소 : 서울특별시 강남구 강남대로78길 8

연락처 : 02-558-6787

 

반응형
반응형

폐점했습니다.

같은 위치에 포몬스(Pho Mons)가 개점했습니다.

 

 

안녕하세요.

얼마 전에 내방역 근처에 있는 새롭게 오픈한 담미온에 갔습니다.

원래 군자역에 있는 담미온을 자주 갔었는데, 마침 내방역에도 담미온이 있는 것을 보고 방문하게 되었습니다.

 

 

일단 입구에서 메뉴를 보고 들어갔습니다.

따뜻한 순대국밥이나 수육국밥을 먹고 싶었습니다.

일단... 주머니 사정이 넉넉한 편은 아니기 때문에 가격을 확인해보았습니다.

7,000원 정도네요.

 

망설이지 않고 식당으로 들어갔습니다.

새로 개업한 가게이기 때문에 깔끔해 보였습니다.

새 의자, 새 식탁. 모든 것이 새 거였습니다.

그리고 제법 가게가 넓었습니다.

 

 

김치나 고추 등을 리필할 수 있는 추가 반찬 셀프바도 있었습니다.

담미온에 대한 설명도 적혀있었습니다.

진하고 느끼하지 않은 맛이라니.. 왠지 침 나오는 설명입니다.

좌석이 많아서 단체손님도 넉넉하게 식사할 수 있을 것 같았습니다.

 

우선 저희는 순대국밥과 수육국밥은 시켰습니다.

시킨 후 바로 밑반찬이 나왔습니다.

깍두기 하고, 양파, 부추가 나왔습니다.

 

 

 

순대국밥이나 수육국밥 말고 다른 메뉴들은 다음과 같았습니다.

수육 정식(12,000), 순대 정식(12,000), 보쌈정식(10,000), 뼈해장국(8,000), 얼큰 국밥(8,000, 특 9,000), 부대찌개 수육국밥(8,000, 특 9,000), 김치찌개 수육국밥(8,000), 순두부 수육국밥(8,000), 나가사끼 수육국밥(8,000), 수육 곰탕(8,000), 고기덮밥[데리야끼, 매운맛](8,000), 감자만두(3,000), 고기 주는 냉면(7,000, 특 8,000), 보쌈(35,000), 마늘보쌈(40,000), 담미온 모둠(45,000), 착한 보쌈(20,000), 감자탕(중 30,000, 대 40,000), 순대곱창전골(중 25,000, 대 35,000), 얼큰 술국(15,000), 볼 껍데기(15,000), 순대볶음(중 25,000, 대 35,000), 토종순대(소 6,000, 대 10,000), 편육(소 6,000, 대 10,000), 어리굴젓 추가(5,000)

 

잠시 기다린 후 바로 순대국밥과 수육국밥이 나왔습니다.

 

 

 

 

순대국밥과 수육국밥 모두 먹어보았는데, 사골국물로 나왔고, 순대국밥의 순대는 제가 좋아하는 아바이 순대라 좋았습니다.

오랜만에 국밥이라서 더 맛있게 먹었고, 깍두기나 김치도 잘 익어서 맛있게 먹었습니다.

가격도 7,000원이라서 적당한 가격인 거 같습니다.

다음에도 또 방문할 것 같습니다.

 

주     소 : 서울 서초구 방배로 179 1층 담미온

전     화 : 02-596-6848

영업시간 : 매일 00:00~24:00 일요일 야간 휴무

 

 

반응형
반응형

안녕하세요.

 

오늘은 for문을 이용해서 다양한 형태로 별찍기를 해보겠습니다.

 

for문을 이해하는데 도움이 될 것 같아서 올려봅니다.

 

5개씩 출력되게 별찍기

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
void main()
{
    int i = 0, j = 0;
 
    for ( i = 0; i < 5; i++ )
    {
        for ( j = 0; j < 5; j++ )
            printf("*");
        printf("\n");
    }
}
cs

 

별이 순차적으로 커지게 별찍기

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
void main()
{
    int i = 0, j = 0;
 
    for ( i = 0; i < 5; i++ )
    {
        for ( j = 0; j <= i; j++ )
            printf("*");
        printf("\n");
    }
}
cs

 

순차적으로 작아지게 별찍기

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
void main()
{
    int i = 0, j = 0;
 
    for ( i = 0; i < 5; i++ )
    {
        for ( j = 0; j < 5-i; j++ )
            printf("*");
        printf("\n");
    }
}
cs

 

공백추가해서 별찍기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
void main()
{
    int i = 0, j = 0, k = 0;
 
    for ( i = 0; i < 5; i++ )
    {
        for ( k = 0; k < i; k++ )
        {
            printf(" ");
        }
        for ( j = 0; j < 5-i; j++ )
            printf("*");
        printf("\n");
    }
}
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
void main()
{
    int i = 0, j = 0, k = 0;
 
    for (i = 0; i < 5; i++)
    {
        for (k = 1; k < 5-i; k++)
        {
            printf(" ");
        }
        for (j = 0; j < i+1; j++)
            printf("*");
        printf("\n");
    }
}
 
cs

 

역삼각형으로 별찍기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
void main()
{
    int i = 0, j = 0, k = 0;
 
    for ( i = 0; i < 5; i+=2 )
    {
        for ( k = 0; k < i; k+=2 )
        {
            printf(" ");
        }
        for ( j = 0; j < 5-i; j++ )
            printf("*");
        printf("\n");
    }
}
 
cs

 

모래시계모양으로 별찍기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>
void main()
{
    int i = 0, j = 0, k = 0;
 
    for ( i = 0; i < 5; i+=2 )
    {
        for ( k = 0; k < i; k+=2 )
        {
            printf(" ");
        }
        for ( j = 0; j < 5-i; j++ )
            printf("*");
        printf("\n");
    }
 
    for ( i = 3; i > 0; i-=2 )
    {
        for ( k = 1; k < i; k+=2 )
        {
            printf(" ");
        }
        for ( j = 0; j <= 5-i; j++ )
            printf("*");
        printf("\n");
    }
}
 
cs

 

입력에 따른 모래시계 만들기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <stdio.h>
void main()
{
    int i = 0, j = 0, k = 0;
    int nNum = 0;
 
    printf("size(odd number:1,3,5,7..) : ");
    scanf("%d"&nNum);
 
    if( nNum % 2 == 0 )
    {
        printf("error : even number\n");
        return;
    }
 
    for ( i = 0; i < nNum; i+=2 )
    {
        for ( k = 0; k < i; k+=2 )
        {
            printf(" ");
        }
        for ( j = 0; j < nNum-i; j++ )
            printf("*");
        printf("\n");
    }
 
    for ( i = nNum-2; i > 0; i-=2 )
    {
        for ( k = 1; k < i; k+=2 )
        {
            printf(" ");
        }
        for ( j = 0; j <= nNum-i; j++ )
            printf("*");
        printf("\n");
    }
}
 
cs

 

나비(리본)모양으로 별찍기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <stdio.h>
void main()
{
    int i = 0, j = 0, k = 0, l = 0, m = 0;
 
    for (i = 0; i < 5; i ++)
    {
        for (j = 0; j <= i; j ++)
             printf("*");
        for (k = 1; k < 5 - i; k++)
            printf(" ");
        for (l = 1; l < 5 - i; l++)
            printf(" ");
        for (m = 0; m <= i; m++)
            printf("*");
        printf("\n");
    }
 
    for (i = 1; i < 5; i++)
    {
        for (j = 0; j < 5 - i; j++)
            printf("*");
        for (k = 1; k <= i; k++)
            printf(" ");
        for (l = 1; l <= i; l++)
            printf(" ");
        for (m = 0; m < 5 - i; m++)
            printf("*");
 
        printf("\n");
    }
}
 
cs
반응형
반응형

안녕하세요.

배열처럼 사용할 변수를 미리 넉넉하게 할당해두고, 사용할 수도 있지만, 

메모리를 얼마나 사용할지 모르는 상황에 있을 때, 미리 너무 많이 선언에 놓으면 메모리 낭비가 일어날 수 도 있습니다.

이럴 때 동적으로 메모리를 할당하여 사용할 수 도 있습니다.

malloc

함수 원형
void* malloc(size_t _Size);

헤더 파일
stdlib.h

리턴값
void* 형은 어떤 타입으로도 변화되므로, 포인터 값만 가진 변수정도로 이해하면 좋을 것 같습니다.
리턴 받은 포인터로 필요한 타입( 예:pCh = (char*)malloc(sizeof(char)*5); )으로 캐스팅한 후 사용하면 됩니다.


설명
필요한 크기를 동적으로 할당하여 사용합니다.

데이터 크기에 맞춰서 할당해줘야 하므로 
"(데이터타입*)malloc(sizeof(데이터타입)*할당크기);"형식으로 할당합니다.

할당 메모리는 반드시 free함수를 통해 메모리 해제를 해야합니다.

 

free


함수 원형
void malloc(void* _Block);

헤더 파일
stdlib.h

리턴값
리턴값은 없습니다.

설명
malloc함수로 동적한 메모리를 해제할 떄 사용합니다.

 

예제

1. malloc과 free 사용 예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <stdlib.h>
 
void main()
{
    int* pPoint;
    pPoint = (int*)malloc(sizeof(int)*5);
 
    pPoint[0= 25;
    pPoint[1= 45;
    pPoint[2= 50;
    pPoint[3= 70;
    pPoint[4= 99;
    
    int i = 0;
    for ( i = 0; i < 5; i++ )
        printf("pPoint[%d] : %d\n", i, pPoint[i]);
 
    free(pPoint);
}
 
cs

결과값

설명

malloc함수를 이용해 int형으로 5개를 할당하였습니다.

배열과 같은 형식을 대괄호로 접근 가능합니다.

free함수를 통해 할당해제를 해야합니다.

 

2. 할당할 사이즈를 입력받아 동적할당하는 예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
 
void main()
{
    int* pPoint;
 
    int nCount = 0;
 
    printf("malloc size ?? ");
    scanf("%d"&nCount);
 
    pPoint = (int*)malloc(sizeof(int* nCount);
 
    int i = 0;
    for (i = 0; i < nCount; i++)
    {
        printf("input pPoint[%d] : ", i);
        scanf("%d"&pPoint[i]);
    }
 
    for (i = 0; i < nCount; i++)
        printf("Output pPoint[%d] : %d\n", i, pPoint[i]);
 
    free(pPoint);
}
 
cs

결과값

설명

scanf함수를 통해 동적할당 개수를 입력 받은 후 개수 만큼 입력 받은 후 출력을 해줍니다.

반응형
반응형

안녕하세요.

C언어에서 특정 문자열를 검색하는 함수인 strstr에 대해 알아보겠습니다.

 

strstr


함수 원형
char* strstr(const char *_Str, const char *_SubStr);

헤더 파일
string.h

리턴값
_SubStr문자열과 같은 값을 가진 _Str문자열의 포인트값을 리턴해줍니다.
_Str에 _SubStr와 동일한 문자열이 없다면, NULL을 리턴합니다.

설명
문자열의 첫번째 문자부터 마지막 문자까지 검색을 해서 같은 문자열을 찾은 후 처음 찾은 포인터를 리턴합니다.
만약에 찾을 대상 문자열에 같은 값을 가진 문자열이 여러개 있어도 처음 찾은 포인터만 리턴하게 됩니다.


예제

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
#include <string.h>
 
void main()
{
    char arrString[20= "Hello World";
    
    char* pCh1 = strstr(arrString, "llo");
    char* pCh2 = strstr(arrString, "rle");
 
    printf("strstr(arrString, ""llo"") : %s\n", pCh1);
    printf("strstr(arrString, ""rle"") : %s\n", pCh2);
}
 
cs

결과값

문자열 배열 arrString("Hello World")에서

8번째 줄 코드(char* pCh1 = strstr(arrString, "llo");)에서는 "llo"문자열을

strstr함수를 통해 찾는데, "Hello World"의 세번째 문자부터 다섯번째 문자가

동일한 문자열이 된다.

그러므로 리턴값은 세번째 문자 포인터값을 가지게 되므로 "llo World"가 출력이 됩니다.

 

9줄 코드(char* pCh2 = strstr(arrString, "rle");)에서는

"rle"문자열을 "Hello World"문자열에서 찾는데, 비슷하게 맞는 문자열은 있지만, 

정확하 동일한 문자열을 찾을 수 없습니다. 

그러므로 null이 리턴되게 됩니다.

 

반응형
반응형

안녕하세요.

오늘은 C언어에서 문자를 검색하는 함수인 strchr 함수에 대해 알아보도록 하겠습니다.

strchr

함수 원형
char* strchr(const char *_Str, int _Val);

헤더 파일
string.h

리턴값
_Val와 같은 값을 가진 _Str문자열의 포인트값을 리턴해줍니다.
_Str에 _Val와 같은 값이 없다면 NULL을 리턴합니다.


설명
문자열의 첫번째 문자부터 마지막 문자까지 검색을 해서 처음 찾은 포인터를 리턴합니다.
만약에 찾을 대상 문자열에 같은 값을 가진 문자가 여러개 있어도 처음 찾은 포인터만 리턴하게 됩니다.


예제

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
#include <string.h>
 
void main()
{
    char arrString[20= "Hello World";
    char *pCh1 = strchr(arrString, 'o');
    char *pCh2 = strchr(arrString, 'a');
 
    printf("strchr(arrString, 'W') : %s\n", pCh1);
    printf("strchr(arrString, 'a') : %s\n", pCh2);
}
 
cs

코드분석

7번째 줄에서(char *pCh1 = strchr(arrString, 'o');)는 arrString[20] 문자열 "Hello world"값 중 'o'를 찾게되면 "Hello World"의 다섯번째 문자를 포인터를 리턴하게 됩니다.

그로인해서 pCh1은 다섯번째 문자의 포인터값을 받아서 출력을 하게되면 다섯번째 문자부터 '\0'이전 값까지 출력이 됩니다.

 

8번째 줄에서(char *pCh2 = strchr(arrString, 'a');)는 arrString[20]값중 'a'를 가진 값이 없기 때문에 NULL값을 리턴하게 됩니다.

 

간단한 응용

간단하게 문자열에 특정 문자가 몇개가 있는지 확인하는 프로그램을 만들어보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <string.h>
 
void main()
{
    char arrString[20= "Hello World";
    int nCount = 0;
    char* pCh = arrString;
 
    while (pCh)
    {
        pCh = strchr(pCh, 'o');
        if (pCh)
        {
            pCh++;
            nCount++;
        }
    }
 
    printf("find count : %d", nCount);
}
 
cs

코드분석

8번째 줄(char* pCh = arrString;)에서 arrString의 시작 주소를 포인터인 pCh로 저장합니다.

12번째 줄(pCh = strchr(pCh, 'o');)에서 strchr함수를 이용해서 'o'문자 찾습니다.

찾은 후 그 위치를 pCh에 저장합니다.

그리고 찾은 위치의 포인터에 1을 더해서 다음 포인터를 저장합니다.

찾았기 때문에 nCount를 1증가시킵니다.

 while문에 pCh값이 null이 아니기 때문에 반복문으로 다시 한번 더 strchr함수를 이용해서 'o'를 찾습니다.

찾은 후 다시 pCh에 값을 저장합니다.

pCh와 nCount를 1씩 증가시킨 후 다시 while문으로 반복하여 'o'문자 찾습니다.

이제 더이상 'o'문자가 없기 때문에 strchr함수에서 null을 리턴하게 되면서 while문을 빠져나오게 됩니다.

반응형
반응형

안녕하세요.

오늘은 C언어에서 문자열의 길이를 알아내는 함수인 strlen 함수에 대해 알아보도록 하겠습니다.

 

strlen

함수 원형
size_t strcat(const char *_Str);

헤더 파일
string.h

리턴값
_Str문자열의 길이가 리턴됩니다.

설명
문자열의 길이가 리턴됩니다.
문자열의 크기로 혼동될 수 있는데, 길이 입니다.
문자열의 데이터 중 '\0'값 이전값까지 문자열 길이를 리턴합니다.

예제

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
#include <string.h>
 
void main()
{
    char arrString1[10= "Hello";
    char arrString2[10= "Worl\0d!!";
    
    printf("arrString1 len : %d\n", strlen(arrString1));
    printf("arrString2 len : %d\n", strlen(arrString2));
}
 
cs

 

 

 

strlen는 해당 문자열의 크기가 아니라 길이를 리턴합니다.

arrString1[10]은 크기가 10이지만 길이는 "Hello"이렇게 5문자가 됩니다.

간혹 혼란이 많이 생기는 부분입니다.

참고로 문자열 배열의 크기를 알아내는 함수는 sizeof()입니다.

 

arrString2 문자열의 경우에는 "worl\0d!!\0"을 데이터로 갖고 있습니다.

strlen함수를 이용하여 길이를 확인하면 4가 리턴됩니다.

함수자체내에서 문자를 하나씩 '\0'(NULL)값을 체크하면서 카운트를 한 후

'\0'일 경우에는 해당 카운트를 리턴해주는 것으로 보입니다.

 

strlen 응용

 strcat함수와 같이 응용하는 코드를 한번 만들어보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#define _CRT_SECURE_NO_WARNINGS        // vs2017 이후 버전은 strcat함수 실행시 보안 에러발생으로 인해 추가합니다.
#include <stdio.h>
#include <string.h>
 
void main()
{
    char arrString1[20= "Hello";
    char arrString2[20= "";
 
    scanf("%s", arrString2);
    while (getchar() != '\n');
 
    int nLength = strlen(arrString1) + strlen(arrString2) ;
 
    if (sizeof(arrString1) > nLength)
    {
        strcat(arrString1, arrString2);
        printf("arrString1 : %s\n", arrString1);
    }
    else
    {
        printf("Error over size \n");
    }
}
cs

"12345678901234" 입력 시 다음과 같이 출력이 됩니다.

arrString1을 크기가 20으로 되어있어서, "Hello"(5)와 "12345678901234"(14)를 합치더라도 크기가 넘치지 않습니다.

다음 "123456789012345" 입력 시에는 다음과 같이 출력되게 됩니다.

"Hello"(5)와 "123456789012345"(15)이므로 '\0'까지 포함하게되면 크기가 넘치므로,

else문의 "Error over size"를 호출하게 됩니다.

반응형
반응형

안녕하세요.

오늘은 C언어에서 문자열을 붙이는 함수인 strcat와 strncat 함수에 대해 알아보도록 하겠습니다.

strcat

함수 원형
char* strcat(char *_Destination, const char *_Source);

헤더 파일
string.h

리턴값
_Destination의 포인터값이 리턴됩니다.

설명
특정 문자열을 붙입니다.
첫번째 매개변수인 _Destination문자열에 두번째 매개변수인 _Source문자열을 넣습니다.
두 문자열을 합친 크기가 _Destination의 크기보다 작아야합니다.

예제

1
2
3
4
5
6
7
8
9
10
11
12
#define _CRT_SECURE_NO_WARNINGS        // vs2017 이후 버전은 strcat함수 실행시 보안 에러발생으로 인해 추가합니다.
#include <stdio.h>
#include <string.h>
void main()
{
    char arrString1[20= "Hello";
    char arrString2[20= "World!!";
 
    strcat(arrString1, arrString2);
 
    printf("%s\n", arrString1);
}
 
cs

arrString1의 \0(NULL)값 위치에 arrString2가 붙게됩니다.

 

strncat

함수 원형
int strncmp( char *_Destination, const char *_Source, size_t count);

헤더 파일
string.h

리턴값
_Destination의 포인터값이 리턴됩니다.

설명
특정 문자열을 특정 크기만큼 붙입니다.
첫번째 매개변수인 _Destination문자열에 두번째 매개변수인 _Source문자열 count만큼 붙입니다.
count는 _Destination의 크기보다 같거나 작아야합니다.

예제

1
2
3
4
5
6
7
8
9
10
11
12
#define _CRT_SECURE_NO_WARNINGS        // vs2017 이후 버전은 strncat함수 실행시 보안 에러발생으로 인해 추가합니다.
#include <stdio.h>
#include <string.h>
 
void main()
{
    char arrString1[20= "Hello";
    char arrString2[20= "World!!";
 
    strncat(arrString1, arrString2, 5);
    printf("%s\n", arrString1);
}
 
cs

arrString1의 \0(NULL)값 위치에 arrString2의 문자를 5개(world)까지 붙여 넣습니다.

그리고 끝에는 \0(NULL)값이 붙습니다.

 

반응형
반응형

안녕하세요.

오늘은 문자열을 숫자로 변경하는 함수에 대해 알아보도록 하겠습니다.

atoi, atol

함수 원형
int atoi(const char* _String);
int atol(const char* _String);

헤더 파일
stdlib.h

설명
문자열(char*)을 정수(int)로 변환하기 위해 사용됩니다.

리턴값
_String 문자열을 정수로 리턴됩니다.

정수로 변환될 수 없는 문자인 경우에는 0이 리턴됩니다. ex) "AA"
정수 + 정수로 변환될 수 없는 문자일 경우 정수로 리턴됩니다.(ex) "78a" -> 78, "78.2"->78
_String값이 정수최대값 보다 크면, INT_MAX값(2147483647)을 리턴해주고 정수최소(-2147483648)값보다 작으면, INT_MIN값을 리턴합니다.

 

예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <stdlib.h>>
 
void main()
{
    int nReturn1 = atoi("78");
    int nReturn2 = atoi("78a");
    int nReturn3 = atoi("a78");
    int nReturn4 = atoi("AA");
    int nReturn5 = atoi("123456789012345678");
    int nReturn6 = atoi("-123456789012345678");
 
    printf("atoi(""78"") return value : %d\n", nReturn1);
    printf("atoi(""78a"") return value : %d\n", nReturn2);
    printf("atoi(""a78"") return value : %d\n", nReturn3);
    printf("atoi(""AA"") return value : %d\n", nReturn4);
    printf("atoi(""123456789012345678"") return value : %d\n", nReturn5);
    printf("atoi(""-123456789012345678"") return value : %d\n", nReturn6);
}
 
cs

결과값

 

atof

함수 원형
double atof(const char* _String);

헤더 파일
stdlib.h

설명
문자열(char*)을 실수(double)로 변환하기 위해 사용됩니다.

리턴값
_String 문자열을 실수로 리턴됩니다.

실수로 변환될 수 없는 문자인 경우에는 0.0이 리턴됩니다. ex) "AA"
실수 + 실수로 변환될 수 없는 문자일 경우 정수로 리턴됩니다. ex)"78.5a"
부동소수점e,E로 표현 가능합니다. ex) "1232323E20"

예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <stdlib.h>>
 
void main()
{
    double dbReturn1 = atof("78.5");
    double dbReturn2 = atof("78.5a");
    double dbReturn3 = atof("a78");
    double dbReturn4 = atof("AA");
    double dbReturn5 = atof("1232323E20");
 
 
    printf("atoi(""78"") return value : %lf\n", dbReturn1);
    printf("atoi(""78a"") return value : %lf\n", dbReturn2);
    printf("atoi(""a78"") return value : %lf\n", dbReturn3);
    printf("atoi(""AA"") return value : %lf\n", dbReturn4);
    printf("atoi(""123456789012345678"") return value : %E\n", dbReturn5);
}
 
cs

 

결과값

반응형
반응형

안녕하세요.

오늘은 C언어에서 문자열을 비교할 수 있는 함수인 strcmp와 strncmp 함수에 대해 알아보도록 하겠습니다.

strcmp

함수 원형
int strcmp( const char *string1, const char *string2);

헤더 파일
string.h

설명
두 문자열을 비교합니다.
string1과 string2 두 문자열을 비교합니다.

리턴값
리턴값이 -1 일 때 -> 두 문자열을 비교하여, 틀린 첫번째 문자가 string1이 더 작을 때 -1을 리턴합니다.
리턴값이 0 일 때 -> 두 문자열이 같습니다.
리턴값이 1 일 때 -> 두 문자열을 비교하여, 틀린 첫번째 문자가 string1이 더 클 때 1을 리턴합니다.

예제

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <string.h>
 
void main()
{
    char arrString1[20= "world!!";
    char arrString2[20= "worlc!!";
    char arrString3[20= "worlf!!";
    char arrString4[20= "world!!";
 
    int nReturn1 = strcmp(arrString1, arrString2);
    int nReturn2 = strcmp(arrString1, arrString3);
    int nReturn3 = strcmp(arrString1, arrString4);
 
    
    printf("strcmp(%s, %s) return : %d\n", arrString1, arrString2, nReturn1);
    printf("strcmp(%s, %s) return : %d\n", arrString1, arrString3, nReturn2);
    printf("strcmp(%s, %s) return : %d\n", arrString1, arrString4, nReturn3);
}
 
cs

 

10번째 줄은 "world!!"와 "worlc!!"를 비교합니다. "worl"까지는 같다가 'd'와 'c'가 다른데

'd'가 'c'가 아스키코드상의 10진수 상수로 봤을 때에는 68과 67이기 때문에 d가 더 큽니다.

매개변수 string1과 string2중에 string1이 더 크면 1이 리턴되기 때문에 strcmp(arrString1, arrString2)에서는 1이 리턴됩니다.

 

 

11번째 줄은 "world!!"와 "worlf!!"를 비교합니다. 여기도 "worl"까지는 같다가 'd'와 'f'가 다릅니다.

'd'와 'f'는 아스키코드상의 10진수 상수로 봤을 때, 68과 70이기 때문에 d가 작습니다.

매개변수 string1과 string2중에 string1이 더 작으면 -1이 리턴되기 때문에 strcmp(arrString1, arrString3)는 -1이 리턴됩니다.

 

 

12번째 줄은 두 값이 같기 때문에 0이 리턴됩니다.

 

 

strncmp

함수 원형
int strncmp( const char *string1, const char *string2, size_t count);

헤더 파일
string.h

설명
지정한 사이즈 만큼 두 문자열을 비교합니다.
string1과 string2 두 문자열을 count만큼 비교합니다.

리턴값
리턴값이 -1 일 때 -> 두 문자열을 count까지 비교하여, 틀린 첫번째 문자가 string1이 더 작을 때 -1을 리턴합니다.
리턴값이 0 일 때 -> 두 문자열이 count까지의 문자열이 같습니다.
리턴값이 1 일 때 -> 두 문자열을 count까지 비교하여, 틀린 첫번째 문자가 string1이 더 클 때 1을 리턴합니다.

예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <string.h>
 
void main()
{
    char arrString1[20= "world!!";
    char arrString2[20= "worlc!!";
    char arrString3[20= "worlf!!";
    char arrString4[20= "worldd!!";
 
    int nReturn1 = strncmp(arrString1, arrString2, 5);
    int nReturn2 = strncmp(arrString1, arrString3, 5);
    int nReturn3 = strncmp(arrString1, arrString4, 5);
 
 
    printf("strncmp(%s, %s, 5) return : %d\n", arrString1, arrString2, nReturn1);
    printf("strncmp(%s, %s, 5) return : %d\n", arrString1, arrString3, nReturn2);
    printf("strncmp(%s, %s, 5) return : %d\n", arrString1, arrString4, nReturn3);
}
 
cs

11번째 줄(strncmp(arrString1, arrString2, 5))에서는 "world!!"와 "worlc!!"의 5개 문자까지 비교합니다.

그러므로 "!!"는 빠지고 "world"와 "worlc"만 비교하게 됩니다.

"worl"까지는 서로 같기 때문에 "d"와 "c"로 리턴 값이 결정되는데, 아스키 코드로 봤을 때는 'd'가 더 큰 값을 가집니다.

매개변수 string1과 string2중 string1의 값이 더크면 1을 리턴하게 되는데, 

strncmp(arrString1, arrString2, 5)에서는 arrString1값이 더 크기 때문에 1을 리턴하게 됩니다.

12번째 줄에서는 "world!!"와 "worlf!!"의 5개 문자까지 비교합니다.

그러므로 "!!"는 빠지고 "world"와 "worlf"만 비교하게 됩니다.

"worl"까지는 서로 같기 때문에 "d"와 "f"로 리턴 값이 결정되는데, 아스키 코드로 봤을 때는 'd'가 더 작은 값을 가집니다.

매개변수 string1과 string2중 string1의 값이 더 작으면 -1을 리턴하게 되는데, 

strncmp(arrString1, arrString3, 5)에서는 arrString1값이 더 작기 때문에 -1을 리턴하게 됩니다.

13번째 줄에서는 "world!!"와 "worldd!!"의 5개 문자까지 비교합니다.

문자열 전체로 봤을 때는 다른 문자열이지만, 5개 문자까지만 비교하기 때문에, 각각 "!!"와 "d!!"는 비교 대상에서 제외가 됩니다.

그러므로 둘은 똑같이 문자열로 비교되어 strncmp(arrString1, arrString4, 5)은 0이 리턴됩니다.

반응형
반응형

안녕하세요.

오늘은 문자열을 복사하는 함수인 strcpy와 strncpy에 대해 알아보도록 하겠습니다.

 

strcpy

함수 원형 
char * strcpy (char *_Dest, const char *_Source);


헤더 파일
string.h


설명  
문자열을 복사를 합니다. 
복사할 문자열(_Source) 변수 크기는 복사될 문자열(_Dest) 변수보다 작거나 같아야 합니다.(종료 null문자 포함)

복사할 문자열(_Source)의 '\0'까지 복사됩니다.


반환 값
_Dest 포인터 값이 반환됩니다.

예제

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
#include <string.h>
 
void main()
{
    char arrString[20= "Hello world!!";
    char arrDestString[20= "TEST";
    strcpy(arrDestString, arrString);
 
    printf("arrString : %s\n", arrString);
    printf("arrDestString : %s\n", arrDestString);
}
 
cs

 

다음과 같이 널까지 그대로 스트링 복사가 됩니다.

 

strncpy

함수 원형 
char * strncpy (char *_Dest, const char *_Source, size_t _Count);

헤더 파일
string.h

설명  
문자열을 _Count만큼 복사를 합니다. 
지정한 크기만큼만 복사합니다.

_Count크기는 _Dest의 데이터 크기보다 작거나 같아야합니다.

반환 값
_Dest 포인터 값이 반환됩니다.

예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
#include <string.h>
 
void main()
{
    char arrString[20= "Hello world!!";
    char arrDestString[20= "TEST";
    
    strncpy(arrDestString, arrString, 2);
 
    printf("arrString : %s\n", arrString);
    printf("arrDestString : %s\n", arrDestString);
}
 
 
cs

 

arrString의 앞에 두글자(H,e)만 복사가 되게 됩니다. 

근데 이렇게 하면 문제가 생길 수 있습니다.

만약에 6번쨰줄에 arrDestString가 초기값이 없이, 

char arrDestString[20];

이렇게만 선언되어 있는 상태에서 strncpy가 된다면 어떻게 될까요??

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
 
void main()
{
    char arrString[20= "Hello world!!";
    char arrDestString[20];
 
    strncpy(arrDestString, arrString, 2);
 
    printf("arrString : %s\n", arrString);
    printf("arrDestString : %s\n", arrDestString);
}
 
cs

결과값은 다음과 같이 됩니다.

원하는 결과는 "He"만 복사되어야하는데, "He"가 복사가 되었지만, 먼가 이상한 깨진 글자가 나오고 Hello world!!가 나오네요..

문제는 He를 복사하고 '\0'(null) 문자끝을 나타내는 널이 없기 때문에 출력할 때 이런 문제가 발생하는 겁니다.

다음과 같이 코드를 수정할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
 
void main()
{
    char arrString[20= "Hello world!!";
    char arrDestString[20];
 
    strncpy(arrDestString, arrString, 2);
 
    arrDestString[2= '\0';
 
    printf("arrString : %s\n", arrString);
    printf("arrDestString : %s\n", arrDestString);
}
 
cs

10번줄에 "arrDestString[2= '\0';" 코드를 추가하였습니다.

결과값은 다음과 같이 원하던대로 "He"만 출력되게 됩니다.

반응형

+ Recent posts