'프로그래밍 언어/C/C++/MFC'에 해당되는 글 4건
[MFC] 폴더 생성 및 파일 생성[MFC] 폴더 생성 및 파일 생성
Posted at 2009. 1. 1. 02:59 | Posted in 프로그래밍 언어/C/C++/MFC1. 폴더 생성
첫번째 인자는 만들 디렉토리 이름, 두 번째 인자는 security 설정인데 패스;
CreateDirectory 함수는 MFC로 프로젝트를 만들면 기본적으로 사용할 수 있는 함수이다.
main/sub 식으로 만들기 위해선 main 디렉토리를 만든 이후 main/sub 디렉토리를 만들어야 한다.
만약 아무 디렉토리도 없는 상태에서 main/sub/subsub 를 만들고자 한다면 다음과 같이 할 수 있다.
CreateFolder(_T("main/sub/subsub"));식으로 호출하면 된다.
while 문에서 / 단위로 끊어 읽으면서 디렉토리를 생성한다.
while 문 안에서 main, main/sub 디렉토리가 생성되며
while 문 밖에서 main/sub/subsub 디렉토리가 생성된다.
여기서 무작정 CreateDirectory를 호출하지 않고 csToken 값에 . 이 있는지를 검사한다.
. 이 포함되어 있다면 파일이므로 CreateDirectory가 아닌 CFile 등의 방법으로 파일을 만들도록 코드를 수정하면
CreateFolder(_T("main/sub/subsub.cpp"));식으로도 사용할 수 있을 것이다
아래 박스 코드를 위 코드의 CreateDirectory(...) 대신 쓰면 된다.
물론, 폴더 이름에 . 을 넣거나 하면 낭패다-_-;
2. 파일 생성
파일이 존재하지 않으면 기본적인 내용을 추가하여 파일을 생성하고, 존재하면 건너뛰는 코드이다.
사실, 파일이 존재하면 그 파일 내용을 지우지 않고 여는 방법은 단순하다.
하지만 파일이 존재하면 아무 일도 하지 않고,
파일이 존재하지 않을 때 파일을 생성 및 기본적인 내용을 추가하려 한다면
modeNoTruncate 로 여는 것으론 해결할 수 없다.
예 >> a.cpp 파일을 생성하는데 파일이 없으면 int main(){ return 0; } 을 넣어 생성하고,
>> 파일이 있다면 아무 일도 수행하지 않으려 하는 경우.
>> 기껏 a.cpp 코딩 다 해 놨는데 이 파일을 위와 같은 초기화 파일로 만들면 슬퍼지니까;;;
CreateDirectory(_T("main"), NULL);
CreateDirectory(_T("main/sub1"), NULL);
CreateDirectory(_T("main/sub1"), NULL);
첫번째 인자는 만들 디렉토리 이름, 두 번째 인자는 security 설정인데 패스;
CreateDirectory 함수는 MFC로 프로젝트를 만들면 기본적으로 사용할 수 있는 함수이다.
main/sub 식으로 만들기 위해선 main 디렉토리를 만든 이후 main/sub 디렉토리를 만들어야 한다.
만약 아무 디렉토리도 없는 상태에서 main/sub/subsub 를 만들고자 한다면 다음과 같이 할 수 있다.
void CreateFolder(CString csPath)
{
// UpdateData(TRUE);
// csPath = m_csTopFolderName + csPath;
CString csPrefix(_T("")), csToken(_T(""));
int nStart = 0, nEnd;
while( (nEnd = csPath.Find('/', nStart)) >= 0)
{
CString csToken = csPath.Mid(nStart, nEnd-nStart);
CreateDirectory(csPrefix + csToken, NULL);
csPrefix += csToken;
csPrefix += _T("/");
nStart = nEnd+1;
}
csToken = csPath.Mid(nStart);
CreateDirectory(csPrefix + csToken, NULL);
}
{
// UpdateData(TRUE);
// csPath = m_csTopFolderName + csPath;
CString csPrefix(_T("")), csToken(_T(""));
int nStart = 0, nEnd;
while( (nEnd = csPath.Find('/', nStart)) >= 0)
{
CString csToken = csPath.Mid(nStart, nEnd-nStart);
CreateDirectory(csPrefix + csToken, NULL);
csPrefix += csToken;
csPrefix += _T("/");
nStart = nEnd+1;
}
csToken = csPath.Mid(nStart);
CreateDirectory(csPrefix + csToken, NULL);
}
CreateFolder(_T("main/sub/subsub"));식으로 호출하면 된다.
while 문에서 / 단위로 끊어 읽으면서 디렉토리를 생성한다.
while 문 안에서 main, main/sub 디렉토리가 생성되며
while 문 밖에서 main/sub/subsub 디렉토리가 생성된다.
여기서 무작정 CreateDirectory를 호출하지 않고 csToken 값에 . 이 있는지를 검사한다.
. 이 포함되어 있다면 파일이므로 CreateDirectory가 아닌 CFile 등의 방법으로 파일을 만들도록 코드를 수정하면
CreateFolder(_T("main/sub/subsub.cpp"));식으로도 사용할 수 있을 것이다
아래 박스 코드를 위 코드의 CreateDirectory(...) 대신 쓰면 된다.
if(csToken.Find('.') >= 0)
CreateFile(csToken, csPrefix);
else
CreateDirectory(csPrefix + csToken, NULL);
CreateFile(csToken, csPrefix);
else
CreateDirectory(csPrefix + csToken, NULL);
물론, 폴더 이름에 . 을 넣거나 하면 낭패다-_-;
2. 파일 생성
파일이 존재하지 않으면 기본적인 내용을 추가하여 파일을 생성하고, 존재하면 건너뛰는 코드이다.
void CreateFile(CString csFileName, CString csPrefix)
{
CFile file;
if(!file.Open(csPrefix + csFileName, CFile::modeRead))
{
file.Open(csPrefix + csFileName, CFile::modeCreate|CFile::modeWrite);
file.Write(~~~~);
}
file.Close();
}
{
CFile file;
if(!file.Open(csPrefix + csFileName, CFile::modeRead))
{
file.Open(csPrefix + csFileName, CFile::modeCreate|CFile::modeWrite);
file.Write(~~~~);
}
file.Close();
}
사실, 파일이 존재하면 그 파일 내용을 지우지 않고 여는 방법은 단순하다.
CFile file(_T("main.cpp"), CFile::modeCreate|CFile::modeNoTruncate);
하지만 파일이 존재하면 아무 일도 하지 않고,
파일이 존재하지 않을 때 파일을 생성 및 기본적인 내용을 추가하려 한다면
modeNoTruncate 로 여는 것으론 해결할 수 없다.
예 >> a.cpp 파일을 생성하는데 파일이 없으면 int main(){ return 0; } 을 넣어 생성하고,
>> 파일이 있다면 아무 일도 수행하지 않으려 하는 경우.
>> 기껏 a.cpp 코딩 다 해 놨는데 이 파일을 위와 같은 초기화 파일로 만들면 슬퍼지니까;;;
C99에서 정의한 변수 선언, 동적배열C99에서 정의한 변수 선언, 동적배열
Posted at 2008. 12. 24. 18:27 | Posted in 프로그래밍 언어/C/C++/MFC소스코드는 다음과 같다.
소스코드가 어려운 건 아니니까 출력결과는 넘어간다.
중요 포인트는
1. 소스 중간에 변수를 선언할 수 있다는 것. ( line 8,10 )
2. 배열 선언 시 그 크기를 변수로 지정해 줄 수 있다는 것 ( line 8 )
툴을 VS6을 써서 C를 배웠다면 저런 건 안 된다고 배웠겠지만;
99년 지정된 표준에서는 됨니다.
근데 VS2005랑 2008에서는 왜 안될까?
에러를 보면 위에 중요 포인트라고 짚은 것 때문에 안 되는 것이다.
컴파일러 옵션에서 뭘 설정해 줘야 할지도 모르겠다.
gcc에선 위의 코드가 잘 돌아간다.
1 #include <stdio.h>
2
3 int main()
4 {
5 int size;
6 printf("숫자입력 : ");
7 scanf("%d", &size);
8 int arr[size];
9 printf("출력해염\n");
10 int i=0;
11 for(i=0; i<size; i++)
12 arr[i] = i;
13 for(i=0; i<size; i++)
14 printf("%d->%d\n", i, arr[i]);
15 return 0;
16 }
2
3 int main()
4 {
5 int size;
6 printf("숫자입력 : ");
7 scanf("%d", &size);
8 int arr[size];
9 printf("출력해염\n");
10 int i=0;
11 for(i=0; i<size; i++)
12 arr[i] = i;
13 for(i=0; i<size; i++)
14 printf("%d->%d\n", i, arr[i]);
15 return 0;
16 }
소스코드가 어려운 건 아니니까 출력결과는 넘어간다.
중요 포인트는
1. 소스 중간에 변수를 선언할 수 있다는 것. ( line 8,10 )
2. 배열 선언 시 그 크기를 변수로 지정해 줄 수 있다는 것 ( line 8 )
툴을 VS6을 써서 C를 배웠다면 저런 건 안 된다고 배웠겠지만;
99년 지정된 표준에서는 됨니다.
근데 VS2005랑 2008에서는 왜 안될까?
에러를 보면 위에 중요 포인트라고 짚은 것 때문에 안 되는 것이다.
컴파일러 옵션에서 뭘 설정해 줘야 할지도 모르겠다.
gcc에선 위의 코드가 잘 돌아간다.
CTime 사용하기CTime 사용하기
Posted at 2008. 11. 28. 01:15 | Posted in 프로그래밍 언어/C/C++/MFC현재 timestamp 얻기
timestamp로부터 연월일시분초 얻기 (월만 얻어본다)
CTime time = CTime::GetCurrentTime();
__int64 timestamp = time.GetTime();
__int64 timestamp = time.GetTime();
timestamp로부터 연월일시분초 얻기 (월만 얻어본다)
CTime time2 = timestamp; // operator=(__int64)
int month = time2.GetMonth(); // +1 같은거 안 해도 된다.
int month = time2.GetMonth(); // +1 같은거 안 해도 된다.
CMap::Lookup 메서드 살펴보기CMap::Lookup 메서드 살펴보기
Posted at 2008. 11. 28. 00:05 | Posted in 프로그래밍 언어/C/C++/MFC먼저 CMap 클래스의 형태는 다음과 같다
template< class KEY, class ARG_KEY, class VALUE, class ARG_VALUE >class CMap
: public CObject
그리고 Lookup 메서드의 형태는 다음과 같다.
BOOL Lookup(
ARG_KEY key,
VALUE& rValue
) const;
Lookup 메서드는 CMap 변수가 key 값이 할당되어 있는지를 찾는 함수이다. 예를 들면
typedef struct Info{
Info(){ i=0; }
int i;
} Info;
CMap<int, int, Info, Info> map;
map.InitHashTable(257); // 왜 하필 257? msdn 예제에서 257 쓰길래;
Info info;
info.i = 10;
map[0] = info;
이후 다음과 같이 Lookup을 사용한다.
Info tmp;
map.Lookup(0, tmp); // return true;
map.Lookup(1, tmp); // return false;
Lookup 함수가 true를 리턴했다면 tmp 변수는 map[0]에 저장된 변수와 같은 값을 갖게 된다.
cout << map[0].i << endl; // 10 출력
cout << tmp.i << endl; // 10 출력
여기서 중요한 점은 map.Lookup(0, tmp); 에서의 tmp 변수와
map[0]에 저장된 값은 같으나 다른 변수이다.
어떤 단어를 써야 할지 모르겠어서 '변수'라고 썼다. 설명이 허접하니 예제를 보자
map.Lookup(0, tmp);
tmp.i = 1;
cout << map[0].i << endl; // 여전히 10 출력
즉, Lookup의 두 번째 파라미터로 들어간 tmp 변수에는 map[0]과 같은 데이터가 들어가 있지만
메모리의 다른 위치에 존재한다는 것이다.
추가. CMap에 포인터를 저장하는 방식이라면 다음과 같이 되겠다.
(조금은 억지로 만든 예제이기 때문에 실제로 이렇게 코딩하면 안 된다;;)
CMap<int, int, Info*, Info*> map;
map.InitHashTable(257);
Info info;
info.i = 10;
map[0] = &info;
Info* tmp;
map.Lookup(0, tmp);
tmp->i = 1;
cout << map[0]->i << endl; // 1 출력
포인터니까 당연히 1이 출력된다. 특이한 거 아니다.
추가. 부분의 예제는 아무 의미 없는 예제다;;
굳이 쓰자면;
class A
{
public:
~A()
{
POSITION pos = m_Map.GetStartPosition();
int key;
Info* value;
while( pos )
{
m_Map.GetNextAssoc(pos, key, value);
delete value;
}
m_Map.RemoveAll(); // 이렇게 removeall 만 한다고 되는게 아니다.
// Method() 에서 동적할당 한 형태이므로 다 남아있다.
// RemoveAll() 하기 전에 하나하나 다 delete 해야 한다.
}
void A()
{
m_Map[0] = new Info;
m_Map[11] = new Info;
}
void Increase()
{
Info* tmp;
m_Map.Lookup(11, tmp);
tmp->i++;
}
private:
CMap<int, int, Info*, Info*> m_Map;
}
그지같은 예제다.
소멸자에 주석으로 달아놓은 문제는 C++에서 new 로 동적할당하고
포인터를 stl 저장소에 넣었을 때 주의점이다.