태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

일반 C를 사용하여 Token을 하는 경우에는 그냥 strtok를 보통 사용하였습니다.

그러나 C++을 사용하게 될 때 구현하기 귀찮(?)아서 기존의 C 라이브러리 함수를 이용하게 되는데, 개인적으로

가장 자주 사용하는것이 strtok와 atoi입니다.

비주얼 스튜디오 2005 이후에서는 strtok를 이용하면 경고를 출력해줍니다.

이를 무시하고 코딩을 하는 경우가 많았는데........이를 무시하면 정말..무시무시한 디버깅의 세계로 빠져들 수 있으니 항상 조심하셔야합니다.


결론부터 말씀드리자면..strtok 함수는 비주얼 스튜디오 6.0 에서는 정상 작동하나, 그 이후 버전에서는

실행은 되지만 뒤에 쓰레기 값이 박히는 경우가 종종 발생합니다.

이를 대체하기 위해서 strtok_s를 이용하게 됩니다. 사용법은 아래 링크를 타고 가시면 됩니다.

출처 : http://harmonize84.tistory.com/112 

그런데 여기서 한가지 더 문제..strtok_s를 윈도우에서만 존재하는 함수라는 것입니다..

즉, 리눅스에서 같은 소스를 실행하면 에러가 난다는 것입니다.(물론 g++ 컴파일러 사용..)

그래서 다시 strtok로 변경하게 되면..쓰레기 값은 출력되지 않으나..자세히 보면 정상적인 출력이 아닌 경우가 발생합니다.

그래서 여기서 해결 방법은 strtok_r을 이용하는것입니다.

사용법은 man 페이지를 참고하세요 ~_~)~


파일을 통째로 메모리에 올려서 사용하는 경우가 많은데

자바의 경우에는 지난 포스팅(개행 문자의 비밀)과 같은 현상으로 발생합니다.

흔히 말하는 시스템에 따른 개행 문자의 차이 때문인데요.

자바의 경우에는 윈도우에서 주로 사용하는 \n만을 사용하지 않고,

\r\n을 동시에 사용하고 있습니다.

그렇기 때문에 개행문자와 탭을 동시에 split을 하려고 할 때 아래와 같이 쓰면 안됩니다.

String[] result = str.split("[\r\n\t]");


이런 경우에는 \r, \n, \t를 각자 split 하게 됩니다.

그래서 아래와 같이 변경하여 사용하셔야 합니다.

String[] result = str.split("(\r\n)|\t");

덧,
참고로 제가 이용한 파일의 구조는 아래과 같습니다.

숫자1 \t 숫자2
숫자3 \t 숫자4
숫자5 \t 숫자6

이런 경우에 위에서 이용한 split을 이용하면

각 배열에 숫자1, 숫자2, 숫자3, 숫자4, 숫자5, 숫자6 이런식으로 들어가게 됩니다.


예전에 map에서 key값이 아닌 value 값으로 정렬을 많이 했었는데, 항상 vector로 변환한 뒤에 sort 알고리즘을

사용했었습니다.

뭐, 이번에도 변함없이 map을 vector로 변한 한 뒤에 sort 알고리즘을 사용하여서 value로 정렬을 했습니다.

그런데..이게 무슨 일인가요..정렬알고리즘을 썼는데 정렬하지 않았을 때와 같은 내용이 파일에 써지는 것입니다!!

제 머리속이 살짝 복잡해서..이 당시에 생각했었던 알고리즘은 다음과 같습니다......멍청하게..ㅠ_ㅠ

1. map -> 변환 -> vector
2. vector - >sort
3. vector-> 변환 ->map (이게 무슨..개 풀 뜯어먹는 생각인지..)
4. 끝~

결과는 GG....이 걸로 30분을 고민했습니다.

"왜 안돼지..왜 안될까..왜 안될까.."

그러면서 1->2->3->4를 무한 반복해가면서 뭐가 잘못됐는지 계속 생각했습니다.

문득.....

1. map -> 변환 -> vector
2. vector - >sort
3. vector-> 변환 ->map (이게 무슨..개 풀 뜯어먹는 생각인지..)
제 스스로에게 : 지금 장난치냐?!?!?!?!?! 이게 왜 들어가..?!
4. 끝~

하...전 정말 바보인가 봅니다 ㅠ_ㅠ

vector<pair<int, string> > map_sort(map<string, int> &target)
{
    vector<pair<int, string> > vt;
    vector<pair<int, string> >::iterator it_vt;
    map<string, int>::iterator it_map;
    for(it_map  = target.begin(); it_map != target.end(); it_map++)
    {  
        vt.push_back(make_pair(it_map->second,it_map->first));
    }
    sort(vt.rbegin(),vt.rend());
    target.clear();
    /*
    for(it_vt = vt.begin(); it_vt < vt.end(); it_vt++)
    {
        cout<<it_vt->second<<"\t"<<it_vt->first<<endl;
        target[it_vt->second] = it_vt->first;
    }
    */
    return vt;    
}
저 빨간 부분이..바로..그....부분 입니다...하...눈물 나는군요 ㅠ_ㅠ
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#define MAX 25

typedef struct mine{
    int x;
    int y;
    int value;
    int temp;
}mine;

typedef struct me{
    int x;
    int y;
}me;

void print(mine L[])
{
    for(int i=0; i<MAX;i++)
    {
        if(i%5==0)
        {
            printf("\n");
            printf("(%d,%d)=%d\t",L[i].x,L[i].y,L[i].temp);
        }
        else
            printf("(%d,%d)=%d\t",L[i].x,L[i].y,L[i].temp);
    }
}

void clear()
{
    printf("\n\n\n\n\n\n\n\n\n\n");
}

main()
{
    int over =0;
    int map = 25;
    int num = 0;
    srand(time(NULL));
    mine L[MAX];
    me user;
    //맵의 x,y,value,temp를 초기화 한다.
    for(int i=0; i<MAX; i++)
    {
        L[i].value = 0;
        L[i].temp = 0;
        L[i].x = i/5;
        L[i].y = i%5;
    }
    //지뢰심기
    for(int k=0;k<5;k++)
    {
        num = rand() % 25;
        L[num].value=1;
    }
        
    print(L);
    //유저의 좌표 입력
    while(1)
    {
        printf("enter x,y :");
        scanf("%d",&user.x);
        scanf("%d",&user.y);
        //유저의 좌표와 지뢰의 비교
        for(int j=0;j<MAX;j++)
        {
            if(user.x==L[j].x && user.y==L[j].y)
            {
                //지뢰와 일치
                if(L[j].value == 1)
                {
                    printf("bomb!!\n");
                    over =1;
                    break;
                }
                //지뢰와 일치하지 않을때
                else
                {
                    //상단 모서리 일때
                    if(user.x==0)
                    {
                        if(user.y==0)
                        {
                            L[j].temp=L[j+1].value+L[j+5].value+L[j+6].value;
                        }
                        else if(user.y==4)
                        {
                            L[j].temp=L[j+5].value+L[j+4].value+L[j-1].value;
                        }
                        else
                            L[j].temp=L[j-1].value+L[j+1].value+L[j+4].value+L[j+5].value+L[j+6].value;
                        
                    }//하단 모서리 일때
                    else if(user.x==4)
                    {
                        if(user.y==0)
                        {
                            L[j].temp=L[j+1].value+L[j-5].value+L[j-4].value;
                        }
                        else if(user.y==4)
                        {
                            L[j].temp=L[j-5].value+L[j-6].value+L[j-1].value;
                        }
                        else
                            L[j].temp=L[j-1].value+L[j+1].value+L[j-4].value+L[j-5].value+L[j-6].value;
                        
                    }
                    //왼쪽 모서리 일때
                    else if(user.y==0)
                    {                    
                        L[j].temp=L[j+1].value+L[j-5].value+L[j-4].value+L[j+5].value+L[j+6].value;
                    }
                    //오른쪽 모서리 일때
                    else if(user.y==4)
                    {                    
                        L[j].temp=L[j-1].value+L[j-5].value+L[j-6].value+L[j+5].value+L[j+4].value;
                    }
                    //위의경우를 제외한 중심부분일때
                    else
                        L[j].temp=L[j+1].value+L[j-1].value+L[j+5].value+L[j-5].value+L[j+6].value+L[j-4].value+L[j+4].value+L[j-6].value;
                    print(L);
                }
            }
        }
        map=map-1;
        if(map==5){
            break;
        }
        if(over==1){
            break;
        }
    }
}

=========================================================================================
학부 2학년일 때 얘기군요..

그 전 제 블로그에 올려놓긴 했지만서도..일부러 부끄러워서 퍼오지 않았더랬죠 =_=;;

하지만 조금이라도 도움이 될까해서..올려봅니다.

C로만 작성한 지뢰찾기..보시면 아시겠지만 참 허접하네요 -_-;
오늘 오전 내내 전처리 과정때문에 말썽을 좀 많이 피웠습니다..

그래서 좋은 자료 트랙백 해 놓습니다.

ANSI 표준에 따른 C의 전처리문의 종류
 - 파일 처리를 위한 전처리문 : #include
 - 형태 정의를 위한 전처리문 : #define, #undef
 - 조건 처리를 위한 전처리문 : #if, #ifdef, #ifndef, #else, #elif, #endif
 - 에러 처리를 위한 전처리문 : #error
 - 디버깅을 위한 전처리문 : #line 
- 컴파일 옵션 처리를 위한 전처리문 : #pragma