출처: http://blog.daum.net/youthdefy0/105

*****************************************************************************************

* Title : 파일 입출력

* Description :

* 문자열, 정수가 무작위로 입력되어 있는 파일에서 종류별로 읽어들이기

* (peek()함수로 한 문자 읽어들여서 종류를 판단하고, 다른 종류의 문자가 입력되면

* putback(char)함수로 스트림에 반환한다.)

//////////////////////////////////////////////////////////////////////////////////////////

[ 파일 입출력 스트림 생성 ] : <fstream> 스트림의 생성자 또는 open()메소드 이용

ifstream fin(const char *fileName, int mode, int access); // 생성자 이용


fstream ; 입/출력용

ifstream ; 입력용

ofstream ; 출력용


* mode (논리합 연산자 '|'로 복수 설정 가능. ios_base::out | ios_base::trunc)

ios_base::app ; 파일의 끝에 추가

ios_base::ate ; 화일의 끝 찾아줌, 입출력 연산은 어디서나 가능

ios_base::in ; 입력용 - ifstream의 기본값

ios_base::out ; 출력용 - ofstream의 기본값

ios_base::binary ; 2진 형식 즉, 문자변환 안 됨

ios_base::trunc ; 동일한 이름을 가진 파일의 내용을 삭제한다.


// 아래 두 flag는 구형 버전에선 지원했으나 지금은 없어졌음

// ios_base::nocreate ; 존재하는 파일 열기 - 없으면 fail

// ios_base::noreplace ; 새로 만들기 - 있으면 fail


[ 문자배열 입출력 스트림 생성 ] : <strstream.h>; 스트림에 연결된 입출력배열은 파일처럼 보인다

strstream sio(char *buf, int size, int mode);

istrstream sin(const char *buf);

ostrstream sout(char *buf, int size, int mode);


[ 2진 입출력 메소드 ]; 파일뿐만 아니라 문자배열 스트림(sin,sout,sio)에서도 사용 가능

fin.get(ch); // 스트림에 ch 입력

fout.put(ch); // 스트림에 ch 출력


// num만큼 또는 식별문자까지(식별문자 스트림에 반환) 입력

fin.get(char *buf, int num, char delim='\n');


// num만큼 또는 식별문자까지(식별문자 제거) 입력

fin.getline(char *buf, int num, char delim='\n');


fin.read(unsigned char *buf, int num); // num만큼 입력

fout.write(unsigned char *buf, int num); // num만큼 출력


fin.peek(); // 스트림에서 문자를 제거하지 않고 다음 문자 얻을 수 있음

fin.putback(ch); // 스트림에서 마지막으로 읽어 온 문자를 그 스트림에 반환


fout.flush(); // 버퍼가 가득 차기 전 출력스트림 방출


fin.gcount(); // 파일로부터 읽어들인 문자 수

sout.pcount(); // 문자배열에 출력한 문자 수


[ 임의 접근 메소드 ]

fin.seekg(streamoff offset, seek_dir org); // 입력포인터 org에서 offset만큼 이동

fout.seekp(streamoff offset, seek_dir org); // 출력포인터 org에서 offset만큼 이동


* origin

ios_base::beg ; 처음

ios_base::cur ; 현재 위치

ios_base::end ; 끝


fin.tellg(); // 입력포인터의 위치 반환 (streampos 형)

fout.tellp(); // 출력포인터의 위치 반환 (streampos 형)


[ 입출력 상태 확인 메소드 ]

스트림.rdstate(); // 정수로 코드화된 에러플래그의 현 상태 반환(에러 1, 아니면0)

스트림.clear(플래그); // 에러플래그 해제(0이면 모두 해제)

스트림.bad();

스트림.eof();

스트림.fail();

스트림.good();

*****************************************************************************************/

#include <iostream>

#include <fstream>

#include <cctype>


using namespace std;


int main()

{

ofstream fout("test.txt");

if (!fout) {

cout << "Can't open file!\n";

exit(1);

}


fout << 123 << "this is a test" << 23 << endl;

fout << "Hello there!" << 99 << "sdf" << endl;


fout.close();


ifstream fin("test.txt");

if (!fin) {

cout << "Can't open file!\n";

exit(1);

}


char szBuffer[256];

char *p;

char ch;

 

do {

p = szBuffer;

ch = fin.peek();

 

if (isdigit(ch)) {

while (isdigit(*p = fin.get())) { p++; }

fin.putback(*p); // 숫자가 아닌 것은 도로 집어 넣는다.

*p = '\0';

cout << "Integer : " << atoi(szBuffer) << endl;

} else if (isalpha(ch)) {

while (isalpha(*p = fin.get())) { p++; }

fin.putback(*p); // 알파벳이 아닌 것은 도로 집어 넣는다.

*p = '\0';

cout << "String : " << szBuffer << endl;

} else { fin.get(); } // 숫자나 알파벳이 아니면 출력하지 않는다.

} while (!fin.eof()); // 이 작업을 파일 끝까지 계속한다.


fin.close();

system("pause");

return 0;

}

 

'프로그래밍 > VC++ 개발 코딩' 카테고리의 다른 글

vector / CArray 사용하기  (0) 2014.01.17
이중포인터 쓰고 지우기  (0) 2014.01.17
Make file for window  (0) 2014.01.17
Big vs Little Endian 설명  (0) 2014.01.17
type casting (cast)  (0) 2014.01.17
[출처] www.codesoft.co.kr (재배포 시에는 출처를 밝히셔야 합니다.)
1. 서론
윈도우즈 프로그램은 대부분 마이크로소프트사의 Visual Studio를 사용한다.
개발이 완료되고, 배포용 release 파일을 만들 때, Visual Studio의 Project 파일을 열고,
release mode로 전체 빌드를 하는 작업이 때로는 무척 번거롭다.
예를 들어, 수많은 exe, dll 파일을 순차적으로 빌드할 필요가 있다면,
하나하나, 빌드하려면, 여간 짜증나는 것이 아니다.
이럴 경우, 도스모드의 배치파일을 요긴하게 사용할 수 있다.
배치파일에서, Visual Studio에서 생성한 Makefile을 순서대로 실행하면 되는 것이다.
2. Makefile export (생성)
가. <Project> -> <Settings> 설정
주의할 점은, Makefile 하나에, debug/release mode 정보가 모두 포함되기 때문에,
debug/release mode 각각의 <Project> -> <Settings> 설정이 누락되지 않아야 한다.
(당연한 얘기지만, 여기서는 배포용 파일을 만들기 위한 Makefile이기 때문에,
debug mode의 설정은 확인하지 않아도 될 것이다.)
나. export
너무 간단하다.
아래 그림과 같이 <Project> -> <Export Makefile...>을 클릭하면,
확장명이 ".mak"인 Makefile이 생성된다.
(예) "CodeBlock.mak"


3. Makefile 실행
도스창을 열고, 해당 폴더 위치에서, 아래와 같이 명령어를 입력한다.
nmake -f CodeBlock.mak CFG="CodeBlock - Win32 Release"

* 참고 (debug mode)
nmake -f CodeBlock.mak CFG="CodeBlock - Win32 Debug"
4. 배치파일에서 실행
위와 같은 방법으로 여러개의 Project에서 각각 Makefile을 생성하고,
배치파일에서 한번에 실행하면 간편하다.
가. mr.bat
(당연한 얘기지만, 파일명은 마음대로 정한다. 단, 확장명은 ".bat")
REM ------------------------------------------------------------------
REM 환경변수 for nmake
REM
REM Platform SDK 를 사용하고 있다면, 아래 환경변수를 배치파일에 추가해야한다.
REM ==> 아래 MSSDKDir을 본인 PC에 맞게 수정한다.
REM ------------------------------------------------------------------
set MSSDKDir=C:\PROGRA~1\MICROS~4
set INCLUDE=%MSSDKDir%\INCLUDE;%INCLUDE%
set LIB=%MSSDKDir%\LIB;%LIB%
REM ------------------------------------------------------------------
REM CodeBlock
REM ------------------------------------------------------------------
cd .\CodeBlockCodeBlock
nmake -f CodeBlock.mak CFG="CodeBlock - Win32 Release"
REM ------------------------------------------------------------------
REM CodeMemoPopup
REM ------------------------------------------------------------------
cd ..\CodeMemoPopup
nmake -f CodeMemoPopup.mak CFG="CodeMemoPopup - Win32 Release"
REM ------------------------------------------------------------------
REM update
REM ------------------------------------------------------------------
cd ..\update
nmake -f update.mak CFG="update - Win32 Release"
REM ------------------------------------------------------------------
REM CodeFileShell
REM ------------------------------------------------------------------
cd ..\CodeFileCodeFileShell
nmake -f CodeFileShell.mak CFG="CodeFileShell - Win32 Release"
REM ------------------------------------------------------------------
REM CodeFile
REM ------------------------------------------------------------------
cd ..\CodeFile
nmake -f codefile.mak CFG="codefile - Win32 Release"
REM ------------------------------------------------------------------
REM 도스창을 닫지 않고 기다린다.
REM ------------------------------------------------------------------
PAUSE

 

'프로그래밍 > VC++ 개발 코딩' 카테고리의 다른 글

이중포인터 쓰고 지우기  (0) 2014.01.17
fstream (ifstream, ofstream)  (0) 2014.01.17
Big vs Little Endian 설명  (0) 2014.01.17
type casting (cast)  (0) 2014.01.17
Enum과 bit연산  (0) 2014.01.17

발췌 : Superstar's New World

엔디안(Endian)이라는 단어 솔직히 컴퓨터 관련 업종에 있다보면 수없이 들어봤음직한 단어이다.
그런데도 갑자기 Endian 이 뭐냐고 물어보면... 뭐라고 해야하나?? -_-;;

간단히 말하면..
Endian이란 녀석.. 메모리란 1차원적인 공간의 데이터를 처리하기 위한 접근 방식이라고 하면 될려나??

일단 컴퓨터를 통해 무엇인가를 하려 한다면 메인 메모리에 접근을 해야만한다. 그런데 이 메인 메모리에 접근하는 데에도 방식이 있단다.
바로 Endian!!
이것이 헷갈리는 이유는 Endian이 하나가 아니고 두개라서(?) ㅋ

먼저 Big Endian 이란 녀석을 보자.

구글에서 검색을 하니 이런 사진이 검색이 되던데.. 설명하기에 좋은 사진인 듯 하다.
한 워드의 데이터가 메인 메모리 공간에 접근할 때, 데이터의 가장 상위 바이트가 메모리의 가장 낮은 주소로 접근하는 방식이다. 물론 데이터의 가장 하위 바이트는 메모리의 가장 큰 주소로 접근할 것이다.
이것이 Big Endian 이란 녀석이다.

Big Endian은 표현되는 순서가 사람이 보는 관점과 동일하다. 그렇기 때문에 디버깅이라든지 다른 작업시 메모리 값을 확인하기가 편하다.
예를 들어 0x12345678 이라는 값이 있다면, 각 메모리 주소에는 0x12, 0x34, 0x56, 0x78 이 들어있게 되는 것이다.

다음은 Little Endian..

Little Endian 은 Big Endian 과 정 반대의 접근 방식이라고 보면 된다.
한 워드의 데이터가 메인 메모리 공간에 접근을 한다면, 데이터의 가장 상위 바이트는 메모리의 가장 상위의 주소로 접근을 하고, 데이터의 가장 하위 바이트는 메모리의 가장 낮은 주소로 접근을 하게 된다.
위에서 예를 든 0x12345678을 Little Endian 식으로 표현을 하면 메모리 주소에는 0x79, 0x56, 0x34, 0x12 가 들어있게 된다.

Little Endian 이든 Big Engian 이든 한 바이트 단위로 접근을 한다면 아무런 문제 없이 사용할 수 있다. 하지만, 그 이상의 단위로 접근을 하게 될 때에 이를 잘못 사용한다면.. 뭐 정상적인 동작을 하지 않을 것이다.

'프로그래밍 > VC++ 개발 코딩' 카테고리의 다른 글

fstream (ifstream, ofstream)  (0) 2014.01.17
Make file for window  (0) 2014.01.17
type casting (cast)  (0) 2014.01.17
Enum과 bit연산  (0) 2014.01.17
[링크스크랩] [C++] stl vector 사용법  (0) 2014.01.17

- const_cast : 상수성을 제거하는데 사용합니다.

const int* pconstint = new int (10);

int *pint = const_cast<int*>(pconstint);

pint = 20;

위와 같이 pint는 상수성이 제거되면서 대상값을 아무 제약없이 변경할 수 있습니다. (포인터 상수만)

 

- dynamic_cast : 상속관계 안에서 포인터나 참조자의 타입을 기본클래스에서 파생클래스로 다운캐스팅과

다중상속에서 기본클래스간의 안전한 타입캐스팅에 사용합니다.

class A {...};

class B : public A { ... }

A *pBase = new A;

A *pParent = new B;

B *pP = new B;

//pParent = pBase;

pParent = dynamic_cast<B*>( pBase );

//pP = pParent;

pP = dynamic_cast<B*>( pParent );

위에서 주석처리 된 부분은 컴파일 에러가 나는 부분입니다.

위와 같이 다이나믹 캐스트는 안전하게 부모 클래스에서 파생클래스로 다운캐스팅을 해줍니다.

 

- static_cast : 가장 기본적인 캐스팅입니다.

실수, 정수, 열거형 등 우리가 기본적으로 사용하는 캐스팅이지만 C언어 형태처럼 만능으로

뭐든지 변환하지는 못하고 약간의 제약사항등이 있습니다.

(예: 서로 다른 타입의 포인터 간의 타입 변환)

 

- reinterpret_cast : 위 3가지 캐스트가 하지 못하는 잡다한 모든 캐스팅을 합니다.

단, 상수형(const) 만은 제거하지 못합니다.

클래스간에 상속관계가 성립되지 않거나 전혀 타입이 다른 어떠한 객체들,,,,,

전혀 상관이 없는 변수간의 타입변환을 수행할 수 있습니다.

 

위의 4가지 캐스팅을 모두 묶은 것이 a = (타입)b; 의 c언어 캐스팅입니다.

그만큼 사용에 제약사항이 없는 대신에 잘못사용해서 실수로 빚어지는 프로그램상의 런타임 에러는

크다는 거지요~~

 

'프로그래밍 > VC++ 개발 코딩' 카테고리의 다른 글

Make file for window  (0) 2014.01.17
Big vs Little Endian 설명  (0) 2014.01.17
Enum과 bit연산  (0) 2014.01.17
[링크스크랩] [C++] stl vector 사용법  (0) 2014.01.17
ActiveX(*.ocx)로 ocx Component 만들기  (0) 2014.01.17

발췌: http://zmeun.tistory.com/137

Enum과 bit 연산

C# 2.0 이하 2009/05/27 23:52

Enum bit 연산

종종 습관적으로, 또는 별 생각 없이 개발을 하는 경우가 있습니다. 제가 바로 그렇습니다. 쿨럭 -_-; 뭐 충분히 그럴 수 있습니다~~. 그렇죠? ^^; 그런데 이런 와중에 잊어버리는 것들이 있습니다. 그리고 그것으로 인해, 생각지 못한 버그가 발생하고.. 또 스스로 자학하고.. .. 이런 별로 상큼하지 못한 일들이 꼬리에 꼬리를 물죠.(세상 사는 게 참…)

이번에는 이런 상황 중에 해당 될 수 있는 내용에 대해 이야기 해 볼까 합니다. 저는 평소에 개발 할 때 enum 타입을 가끔 사용하곤 합니다. 어떤 값들을 구분해서 사용해야 할 때, 그 값들을 명료하게 구분할 수 있고 또 코드를 보기에도 쉬운 장점들이 있죠.

그렇다면 평소에 흔히 사용하는 형태의 아주 간단한 enum 예제 코드를 작성해 보겠습니다.

static void Main(string[] args)

{

CustomerOrder(Beverage.Coffee);

Console.Read();

}

public static void CustomerOrder(Beverage beverage)

{

Console.WriteLine("Customer Ordered Below Menu...");

if (beverage == Beverage.Coffee)

{

Console.WriteLine("Coffee");

}

if (beverage == Beverage.Tea)

{

Console.WriteLine("Tea");

}

if (beverage == Beverage.Juice)

{

Console.WriteLine("Juice");

}

}

public enum Beverage

{

Coffee = 0x1,

Tea,

Juice

}

얼핏 보기에도 아주 편안해 보이는 코드입니다. 흠잡을 때 없이 아주 훌륭하죠? ㅋㅋ Beverage라는 enum 타입을 정의해 놓고, CustomerOrder 메서드에 이 enum 타입을 파라미터로 전달해 해당하는 값을 출력하는 코드입니다.

그런데, 여기에 상황을 조금만 바꿔보죠. CustomerOrder에 전달하는 Beverage라는 enum 타입의 멤버를 하나가 아닌 두 개 이상 전달해야 한다면 어떻게 할까요? ~ 그러니까..다음과 같은 코드가 필요한 경우겠죠.

static void Main(string[] args)

{

CustomerOrder(Beverage.Coffee | Beverage. Tea);

Console.Read();

}

여러분들은 이와 같은 상황에서 어떻게 하시겠습니까? 혹시 오해하시는 분들이 계실지 몰라 말씀 드리면.. 이 코드는 오류가 발생하지 않습니다. 단지.. 이상한 결과가 나올 뿐이지요..

?? 이상한 결과? 그게 뭔데~ 라고 생각하시는 분들분명 계십니다. .. 그런 분들을 위해서.. 결과 화면을 먼저 보여 드리겠습니다.



!!~~ 웅성 웅성.. 하는 소리가 들립니다. ㅋㅋ 물론 뻔한 걸 물어 보는군.. 하는 분들도 많이 계실 것이구요. 분명 코드에서는 Coffee Tea를 주문 했는데.. 막상 나온 건 Juice입니다. 난 시키지도 않았는데 말이죠...그쵸? 이럴 땐 음료를 주문한 손님이나 이 코드를 작성한 개발자나 화나는 건 매 한가지입니다. -_-;;

 

이런 결과가 나오는 이유는 바로 bit 연산 때문입니다. 그래서 오늘은 옛 기억을 되새겨보는 차원에서 bit연산에 대해서 한번 회상해 볼까 합니다.

Bit 연산은 대략 |(or), &(and), ~(not) 이런 연산을 수행하며 각각의 연산은 다음과 같이 처리 됩니다.

x y |

------------------

0 0 0

0 1 1

1 0 1

1 1 1

x y &

------------------

0 0 0

0 1 0

1 0 0

1 1 1

x ~

------------------

0 1

1 0

이것을 앞에서 작성한 코드에 적용해 보면, 결과가 왜 그렇게 나왔는지 바로!! 그 즉시!! 당장!! 이해할 수 있습니다. ~ 한번 보시죠. Beverage라는 enum 타입은 1부터 시작합니다. 그렇게 되면, 그 다음 enum 타입의 멤버는 별도의 다른 상수 값을 지정하지 않을 경우 자연히 1씩 증가한 값을 갖게 되죠.

그럼 Coffee 1, Tea 2가 될 것이고, 이것을 다시 main 메서드 내에서 CustomerOrder 메서드에 파라미터로 전달 할 때 |(or) 연산을 통해서 전달합니다. 그럼 CustomerOrder 메서드에 전달된 Beverage enum 타입의 파라미터는 다음과 같은 bit 연산 과정을 거쳐 결과 값을 갖게 됩니다.


0 1 --> Coffee : 1

1 0 --> Tea : 2

-------

1 1 => Juice : 3

bit 연산에서 볼 수 있듯이 Coffee Tea |(or) 연산 결과는 3이 되고, 3 Beverage enum 타입의 멤버 중 Juice가 갖는 값이 됩니다. 그렇기 때문에 CustomerOrder 메서드의 실행 결과는 Juice가 출력되는 것입니다. (이 시점에서 ~ !!”.. 나오시죠? ^^)

! 그럼 이제 왜 그렇게 되는가는 이해했으니, 그럼 남은 건 어떻게 해야 하는 것인가!.. 겠죠.

그러기 위해서는 Beverage enum 타입 멤버가 갖는 상수의 값을 각각 지정해야 합니다. 왜냐하면 1씩 자동증가 하는 값을 enum의 멤버들이 갖게 되면, 앞으로 발생하게 되는 | 또는 &, ~ 연산이 앞의 예제 코드처럼 의도하지 않은 연산으로 인해 잘못 된 값이 나타날 수 있기 때문입니다. 그래서 저는 이렇게 한번 해 보았습니다. 먼저 각각의 enum 멤버의 값을 겹치지 않는 상수 값으로 초기화 합니다.

public enum Beverage : short

{

Coffee = 0x1,

Tea = 0x2,

Juice = 0x4

}

이렇게 해 두면 Coffee Tea |(or) 연산해도 Juice가 나올 수 없겠죠.(1 | 2하면 3이 되는데, Juice 4의 값을 갖기 때문이죠.)

그 다음에 CustomerOrder 메서드를 약간 수정합니다. 이렇게요…..

public static void CustomerOrder(Beverage beverage)

{

Console.WriteLine("Customer Ordered Below Menu...");

if ((Beverage.Coffee & beverage) == Beverage.Coffee)

{

Console.WriteLine("Coffee!");

}

if ((Beverage.Tea & beverage) == Beverage.Tea)

{

Console.WriteLine("Tea!");

}

if ((Beverage.Juice & beverage) == Beverage.Juice)

{

Console.WriteLine("Juice!");

}

}

if문의 조건 식이 조금 어색하죠? 그럼 왜 그런지 직접 bit 값으로 풀어서 한번 살펴 보겠습니다.

if ((Beverage.Coffee & beverage) == Beverage.Coffee)

1) Beverage.Coffee : 0 0 1

2) beverage : 0 0 1(Coffee) | 0 1 0(Tea) = 0 1 1

3) 0 0 1 & 0 1 1 = 0 0 1 => Coffee

1)번의 Coffeebit 값으로 001이고, 2) beverage Coffee Tea |(or) 연산이기 때문에 이것을 풀어보면 011이 됩니다. 그리고 1)번과 2)번을 다시 &(and) 연산하면 001이 되죠. 그럼 Beverge.Coffee와 같은 값이 되니.. if문의 조건 식은 true가 되어 if문의 블록에 있는 코드는 실행됩니다.

그리고 그 다음 if문도 이와 같은 식으로 한번 풀어 보겠습니다.

if ((Beverage.Tea & beverage) == Beverage.Tea)

1) Beverage.Tea : 0 1 0

2) beverage : 0 0 1(Coffee) | 0 1 0(Tea) = 0 1 1

3) 0 1 0 & 0 1 1 = 0 1 0 => Tea

역시 마찬가지로 1)번은 Beverage.Tea 2의 값을 갖고 있기 때문에, 이를 bit 값으로 풀면 010이 되고 2)번은 위와 마찬가지이므로 1) 2) &(and) 연산하면 결과는 010 Beverage.Tea가 됩니다. 이해 되시죠? (어째 산수 문제 푸는 것 같은..느낌이.. ^^;)

이런 식으로 하면 나머지 하나의 if문도 이해하실 수 있을 겁니다. 그리고 이렇게 작성한 코드를 실행하면 예상과 같이 다음과 같은 결과를 확인할 수 있습니다.


 

이제서야 원하는 결과가 나왔죠? 냐햐햐.. 살짝 보람이 있습니다. ~ 그렇다면여기에서 간단히, 황을 한번 더 살짝 꼬아 보겠습니다. 어떤 상황에서는 앞에서 정의한 enum의 멤버를 모두 체크해야 할 경우도 있을 수 있습니다. 그렇다면 모든 enum 타입의 멤버를 |(or) 연산으로 모두 전달해야 할까요? 그것도 방법이죠. 하지만, 그보다 더 간단한 방법이 있습니다. 바로 이렇게 하는 거죠.

public enum Beverage : short

{

Coffee = 0x1,

Tea = 0x2,

Juice = 0x4,

All = Coffee | Tea | Juice

}

static void Main(string[] args)

{

CustomerOrder(Beverage.All);

Console.Read();

}

어떠세요? ~~ 쉽죠잉~ ㅋㅋㅋ 이렇게 간단히 코드 수정을 통해서 다음과 같은 결과를 얻을 수 있습니다.



간만에 생각해 보는 bit 연산이었습니다. 옛 기억이 새록새록 나시죠? 물론 이런 것이 습관이 되신 분들은 ~ 이런걸 이야기 하냐..”라고 생각하실 수 있겠지만, 사실 요즘은 개발 환경이 너무 좋아서 이런 거 잘 생각 못하고 지내는 일들이 다분히 있습니다. 저 역시 마찬가지 구요. 그래서 한번 remind 차원에서 정리해 보았습니다. 그리고 역시나 글도 길어 졌네요. ^^; 제 경험상으로도 긴 글들은 역시 읽기에 너무 부담이 되죠.. 글은 짧게. 내용은 간단히.. 이런 게 생활화 되야 하는데.. 저는 언제나. 그리 될는지.. ~… -_-;

 

그럼 오늘은 여기까지 해서 마치도록 하겠습니다. 긴 장문 읽으시느라 고생 하셨습니다. 그럼 즐거운 하루 되시기 바랍니다. 감사합니다. ^o^v

 

int값의 STL vector를 받아 배열내의 모든 홀수를 출력하는 C++ 함수 작성

#include "stdio.h"
#include //vector include

void main()
{
std::vector intList;// vector 변수 선언
intList.clear();// 변수 초기화 안해줘도 되지만 변수는 초기화 해주는 습관을...
char szInput[1024] = { 0, };// 입력을 받을 버퍼, 종료 문자를 입력 받기 위해서 문자열로 선언

printf("Input Number(Quit is q) : ");
scanf("%s", szInput);

while(strcmp(szInput, "q") != 0)// q가 들어오면 종료
{
int nNumber = atoi(szInput);// 들어온 문자열을 int로 변환
intList.push_back(nNumber);// vector에 삽입

printf("Input Number(Quit is q) : ");
scanf("%s", szInput);
}

for(int i = 0; i < intList.size(); i++)// vector의 접근은 일반 배열의 접근 방식이 가능하므로
{
int nNumber = intList[i];// 삽입 되어있는 값 얻기
if((nNumber % 2) != 0)// 홀수 인지 판별
printf("%d ", nNumber);
}
intList.clear();// vector의 사용을 마쳤으므로 다시 초기화
printf("\n");
}

(출처 : 'int값의 STL vector를 받아 배열내의 모든 홀수를 출력하는 C++ 함수 작성' - 네이버 지식iN

[출처] stl vector 사용법|작성자 바들바들

// STL vector의 간단한 사용법

// STL에서의 벡터(vector)는 동적 배열이다

// vector를 사용하기 위한 해더파일 인클루드

#include <vector>
using namespace std;

// 선언

// int 타입으로 선언되었기 때문에 4바이트가 메모리에 할당 된 것 처럼 보일 수 있으나

// 실제로는 크기가 0인 즉, 비어있는 배열이 선언된 것이다

vector<int> list;

// list란 동적배열에 데이터 5를 추가함

// push_back 함수의 인자는 반드시 선언된 타입과 같아야한다

// 여기서는 정수(int)타입의 5를 넘겨주었다

list.push_back(5);

// iterator(반복자)를 생성

// iterator는 객체의 포인터형이다

// iterator에 객체의 첫 원소의 주소를 넘겨준다

// iterator 역시 선언한 타입과 반드시 동일한 타입으로 선언해야한다

// list와 동일한 타입의 interator를 생성
vector<int>::iterator i;
// i(interator)에 list의 첫 원소의 주소를 넘겨줌
// i가 list의 마지막 원소의 주소와 같지 않다면 루프
// i(interator) 증가(즉, 다음 list의 주소로 넘어감)

for(i = list.begin(); i != list.end(); i++)
{
// i(interator)가 가르키는 list의 현재 배열 값을 출력
printf("%d\n", *i);
}

// 원소 삭제

vector<int>::iterator i;
for(i = list.begin(); i != list.end(); i++)
{
// i(interator)가 가르키는 list의 현재 배열 값을 지운다

// erase 함수를 사용하여 원소를 삭제할 수 있다

list.erase(i);
}

'프로그래밍 > VC++ 개발 코딩' 카테고리의 다른 글

type casting (cast)  (0) 2014.01.17
Enum과 bit연산  (0) 2014.01.17
ActiveX(*.ocx)로 ocx Component 만들기  (0) 2014.01.17
실제 윈도우 메시지 보내기  (0) 2014.01.17
클래스 초기화 하기  (0) 2014.01.17

ActiveX로 Component를 만들어 보자.

1. New Project -> C++ MFC에서 "MFC ActiveX Control"을 선택한다.

ActiveX 형태가 만들어 지면. 하기와 같이 4군데를 추가한다.

 

====================

Tester.idl

====================

[ uuid(97DDE6EE-3B47-434E-BCC1-01283A6BAFAA),

helpstring("Tester Control의 디스패치 인터페이스")]

dispinterface _DTester

{

properties:

[id(DISPID_CAPTION), helpstring("속성 Caption")] BSTR Caption;

methods:

[id(DISPID_ABOUTBOX)] void AboutBox();

[id(1), helpstring("메서드 함수명1")] BOOL 함수명1(void);

[id(2), helpstring("메서드 함수명2")] BSTR 함수명2(void);

[id(3), helpstring("메서드 함수명3")] int 함수명3(void);

[id(4), helpstring("메서드 함수명4")] void 함수명4(void);

...

};

====================

TesterCtrl.cpp

====================

// 디스패치 맵입니다.

BEGIN_DISPATCH_MAP(CTesterCtrl, COleControl)

DISP_FUNCTION_ID(CTesterCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)

DISP_FUNCTION_ID(CTesterCtrl, "함수명1", dispid함수명1, 함수명1, VT_BOOL, VTS_NONE)

DISP_FUNCTION_ID(CTesterCtrl, "함수명2", dispid함수명2, 함수명2, VT_BSTR, VTS_NONE)

...

END_DISPATCH_MAP()

bool 함수명1(void)

{

}

Void 함수명2(void)

{

}

====================

TesterCtrl.h

====================

// 디스패치와 이벤트 ID입니다

enum{

dispid함수명1 = 1L;

dispid함수명2 = 2L;

,,,

};

Bool 함수명1 (void);

Void 함수명2 (void);

 

'프로그래밍 > VC++ 개발 코딩' 카테고리의 다른 글

Enum과 bit연산  (0) 2014.01.17
[링크스크랩] [C++] stl vector 사용법  (0) 2014.01.17
실제 윈도우 메시지 보내기  (0) 2014.01.17
클래스 초기화 하기  (0) 2014.01.17
매개변수 포인터 전달받기  (0) 2014.01.17

1. 목적: A라는 대상 Utility의 기능들을 B라는 다른 Utility에서

Window Message(SendMessage)를 통해 제어하는 방법과 실험을 실시.

 

2. 구현 - 간략 설명.

A.EXT : SPY++로 Caption Title을 찾아 FindWindow로 핸들을 찾아와,

SendMessage로 해당 핸들에 메세지 및 W/L param를 전송한다.

 

3. 구현 - 코드

A.EXE :

 

A.h 선언

afx_msg long OnReceiveExecuteMsg(WPARAM Wparam, LPARAM LParam);

 

A.cpp

message 선언

ON_MESSAGE(WM_USER_MSG,OnReceiveExecuteMsg)

 

// WM_USER_MSG 0x401
long A::OnReceiveExecuteMsg(WPARAM WParam, LPARAM LParam)
{
switch(WParam)
{
case 0: // B Utility에서 W Param으로 보내오는 데이터가 0인 경우 실행.
OnManStart();
break;
case 1:
OnManClear();
break;
default:
break;
}

return TRUE;
}

 

//////////////////////////////////////////////////////////////////////////////////////////

B.exe : C#으로 작성된 Utility


namespace RemoteExecute
{
public partial class Form1 : Form
{
// #define 정의
const int WM_USER = 0x0400;
const int WM_USER_MSG = WM_USER + 1;
int hwnd = 0;

public class AnotherWindowCtrl
{
[DllImport("user32.dll")]
public static extern int FindWindow(string lpClassName, string lpWindowName);

[DllImport("user32.dll")]
public static extern int SendMessage(int hwnd, int wMsg, int wParam, int lParam);
}

public Form1()
{
InitializeComponent();
}

private void btnStart_Click(object sender, EventArgs e)
{
if(hwnd==0) // 핸들 없으면 찾아서... WindowName은 Spy로 찾아서 기록.

hwnd = AnotherWindowCtrl.FindWindow(null, "System name");
AnotherWindowCtrl.SendMessage(hwnd,WM_USER_MSG, 0, 0);
}

private void btnClear_Click(object sender, EventArgs e)
{
if (hwnd == 0) hwnd = AnotherWindowCtrl.FindWindow(null, "System name");
AnotherWindowCtrl.SendMessage(hwnd, WM_USER_MSG, 1, 0);
}
}
}

 

typedef struct _T_FBMDUTDATA
{
unsigned short xfail[0x800];
unsigned short yfail[0x800];
unsigned short fIO[0x8];

// struct initialize.
_T_FBMDUTDATA()

{

ZeroMemory(this, sizeof(*this));

}


} FBMDUTDATA;

 

클래스 초기화 하기

 

/*
void DoSomething(char *lpstrSource)
{
char *lpstrString;
lpstrString = (char *)malloc(strlen(lpstrSource)+1);
if (lpstrString)
strcpy(lpstrString, lpstrSource);
...
}
*/

+ Recent posts