C 언어에서 fget() 을 활용하여 간단하게 입력을 받는 방법을 기록하려 한다.

 

fget() 은 스트림에서 문자열을 읽어 들이는 함수인데~ sscanf() 와 함께 아래 코드와 같이 사용 할 수 있다.

 

아래 코드는 숫자 두 개를 받아서 간단하게 라인 수를 넣고 그 합을 출력해 주는 코드이다.

 

#include <stdio.h>

 

#define    TEXTLENGTH    2048

 

int    main()

{

char    text[TEXTLENGTH] ;

double    xi, yi ;

int        n=1;

 

while (fgets (text, TEXTLENGTH, stdin) != NULL )

{

if (sscanf (text, "%lf %lf", &xi, &yi ) == 2 )

{

    printf("%d, %lf+%lf=%lf\n",n, xi, yi, xi+yi);

    ++n ;

}

else

{

    fprintf( stderr, "Data Number Error : %s", text ) ;

}

}

return 0 ;

}

 

일단 현재 내 컴퓨터 환경은 윈도우 7, 64 비트이고 mingw 가 설치되어 있다.

 

위 코드의 파일 명은 standardIO.c 인데~ 다음과 같이 CMD 창에서 컴파일 한다.

 

gcc standardIO.c -o standardIO

 

다음으로 입력을 위한 test.txt 파일을 다음과 같이 만들었다. 단순히 탭으로 구분된 숫자 두 개씩 저장한 것이다.

 

아래 명령어로 test.txt 파일의 내용을 standardIO.exe 에 넣어주면~

 

standardIO.exe < test.txt

 

아래와 같은 결과가 나온다.

 

아래와 같이 명령하면~

standardIO.exe < test.txt > result.txt

 

result.txt 파일이 다음과 같이 만들어 지기도 한다.

 

아래 그림과 같이 standardIO.exe 를 실행하고~ cmd 창에 숫자를 넣어서 계산 할 수도 있다. 종료는 Ctrl + C 를 누르면 된다.


C/C++ 코딩 시 변수끼리 값을 바꾸고 싶은 경우들이 있습니다.

 

이를 보통 변수 swap 이라고 하는데

 

a, b 라는 두 변수간에 값을 바꾸기 위해서는 보통 하나의 변수가 더 필요 합니다.

 

temp 라는 하나의 변수를 더 써서 다음과 같이 변경하는 게 일반적이죠. 비트 연산을 하지 않는 실수 타입들은 아래 방식으로 하는 게 맞을 겁니다.

 

temp = a;

a= b;

b= temp;

 

하지만 정수 타입의 경우 비트 연산을 이용하여 temp 라는 추가적인 변수 없이 swap 이 가능 합니다.

 

아래와 같이 Exclusive OR 연산을 세 번 사용하면 변수끼리 값을 바꿀 수 있습니다.

 

#define SWAP(a, b)  a ^= b; b ^= a; a ^= b;

 

위 매크로에 대해 다음과 같이 테스트 해 봤습니다.

 

#include <iostream>

using namespace std;

 

#define SWAP(a, b)  a ^= b; b ^= a; a ^= b;

int main()

{

    int x = 10;

    int y = 5;

    SWAP(x, y)

    cout << "x=" << x << " y= " << y << endl;

    return 0;

}


결과는 다음과 같이 x, y 값이 바뀐 것을 확인 할 수 있습니다.


x=5, y= 10



C/C++ 코딩 시 비트 연산은 굉장히 많이 하지만 자주 실수하는 부분입니다.

 

이런 비트연산들은 임베디드 시스템 설계시 자주 사용하곤 하는데 자주 사용하는 만큼 매크로로 만들어서 사용하면 편리하겠쬬.

 

제가 사용하는 비트연산 매크로는 다음과 같습니다.

 

필요하신 분들은 사용하시길~


윈도우에서 GCC 를 사용하고자 하는 경우 MinGW 를 사용하거나 Cygwin 을 설치하거나 또는 Virtual box 에 리눅스를 설치해서 사용할 수 있다.

 

아래 포스팅에서 TDM-GCC 설치 방법에 대해 소개한 적이 있는데~

  

2013/06/06 - [유틸] - MinGW 64bits 설치


오늘은 MinGW 뿐만 아니라 boost 라이브러리를 사용하고 싶었다.

 

현재 내 PC 환경은 윈도우 7 64비트이다.

 

찾아보니 아래 주소의 MinGW Distro 가 나왔고, x64-native, GCC 4.8.2, Boost 1.55.0 라는 특징을 가지고 있었다.

 

http://nuwen.net/mingw.html

 

또한 C++11 을 default 로 설정해 놓았다고 한다.

 

위 주소에 들어가서 아래 그림의 링크를 클릭해서 다운로드 받는다. 위에 링크된 mingw-11.6.exe 은 git 이 없는 버전이고

 

아래에 있는 mingw-11.6-without-git.exe 은 말 그대로 git 은 빠진 버전이다.

 

나는 git 은 따로 설치를 했었기에 아래에 있는 mingw-11.6-without-git.exe 를 다운로드 받았다.

 

설치는 굉장히 간단한데~ 다운로드 받은 mingw-11.6-without-git.exe 파일을 더블 클릭하고 아래 그림과 같이 path 를 잡아 주면 된다.

 

위 그림과 같이 최상위 폴더를 잡아주면 C:\ 하위에 MinGW 라는 폴더가 생긴다. 그래서 나는 C:\MinGW 에 설치했다.

 

윈도우에서 Codeblocks IDE 에서 boost library 를 사용하여 소문자를 대문자로 변환해 보았다.

 

소문자를 대문자로 변환하는 과정에서 아래 주소에서 확인한 boost 라이브러리의 to_upper() 함수를 사용했다.

 

http://stackoverflow.com/questions/735204/convert-a-string-in-c-to-upper-case

 

Codeblock 셋팅시에 Compiler 를 다음과 같이 방금 설치한 MinGW Distro 에 맞게 설정 해준다.

 

Compiler 의 search directory 역시 아래 그림과 같이 mingw 의 include path(C:\MinGW\include)를 추가해준다.

 

아래와 같이 코딩하고~

 

#include <iostream>

#include <boost\algorithm\string.hpp>

#include <string>

 

using namespace std;

 

int main()

{

 

string str = "Hello World";

 

string newstr = boost::to_upper_copy<string>(str); // 대문자로 변경후 새로운 변수에 저장

 

cout << "before upper : " << str << ",\t to upper : " << newstr << endl;

 

boost::to_upper(str); // // 대문자로 변경후 현재 변수에 저장

 

cout << "Str to upper : " << str << endl;

 

return 0;

}

 

F9 를 눌러서 Build And Run 을 수행해 보면 다음과 같이 정상적으로 동작 한다.



C/C++ 을 사용하여 우리가 흔히 사용하는 ls 또는 dir 명령과 같이 directory 의 파일 또는 폴더의 리스트를 얻고 싶어서 찾아보니

 

아래 주소의 글이 나오더군요. 역시… stackoverflow

 

http://stackoverflow.com/questions/612097/how-can-i-get-a-list-of-files-in-a-directory-using-c-or-c

 

boost 와 같은 매우 좋은 라이브러리를 사용하는 방법도 있지만 첫번째 답변에 dirent.h 파일을 사용하는 방법이 설명 되어 있었습니다.

 

dirent.h 는 C POSIX library 에 포함되어 있으며 MinGW 나 GCC 등에서는 사용할 수 있지만 Visual Studio에서는 사용할 수 없더군요.

 

http://stackoverflow.com/questions/5530933/dirent-h-in-visual-studio-2010-or-2008

 

사실 이런 파일 리스트와 관련한 함수들은 Cross Platform 으로 구성되어야 코딩하기 편한데 각 플랫폼에 따라 다르게 코딩하는 방법을 알아야 된다는 게 귀찮더군요.

 

그런데 역시.. dirent.h 는 Visual Studio 에서 사용할 수 있도록 아래 주소에 API 가 있었습니다.

 

http://www.softagalleria.net/dirent.php

 

또한 첫 번째로 소개했던 주소에 Visual Studio 에서 사용 할 수 있는 dirent.h 의 링크가 있더군요.

 

http://www.softagalleria.net/download/dirent/

 

몇 가지 파일 중 dirent-1.11.zip 파일을 다운로드 받았고~ Codeblock 을 사용하여 빌드 해 봤습니다.

 

필요하신 분들을 위해 dirent-1.11.zip 파일도 올립니다.

  

dirent-1.11.zip


빌드 후에 아래 그림과 같이 dirTest.exe C:\Windows 라고 명령해서 C:\Windows 의 파일리스트를 확인해 봤습니다.

 

잘 되더군요.

프로그래밍을 하다 보면 파일 또는 폴더의 path 를 자주 다루게 됩니다.

 

아래 포스팅에서는 Autohotkey 에서 SplitPath 함수를 사용해서 file path 를 구분하는 방법에 대해 소개한 적이 있는데~

  

2013/11/14 - [programming language/Autohotkey] - Autohotkey SplitPath 를 이용하여 폴더, 파일명, 확장자, 드라이브 구분하기

 

오늘은 C++ 를 사용한 file path 구분 방법에 대해 소개하려 합니다.

 

코드는 굉장히 간단한데요~

 

위 코드와 같이 stringstream 과 getline 함수를 사용하고~

 

C:/Windows/System32/vbscript.dll 라는 path 를 '/' 에 따라 나눠보면~

 

다음과 같은 결과가 나옵니다. 다음 그림에서 보는 바와 같이 C:, Windows, System32, vbscript.dll 로 구분되는 것을 확인 할 수 있습니다.



아래 포스팅에서 소개를 했지만 C++ 의 발전은 정말 눈부신 것 같습니다.

 


2012/08/26 - [컴퓨터일반] - C++11 많이 좋아졌네요.

 


예전에 그리 어렵게 했던 또는 귀찮게 했던 것들이 하나 하나 쉬워지는 모습을 보면서 참…. 세상은 계속 좋아지는구나 라는 생각을 많이 하는데요~

 

오늘은 간단하게 아래 주소에서 소개하는 range based for loops 에 대해 소개 드리려 합니다.

 

http://www.cprogramming.com/c++11/c++11-ranged-for-loop.html

 

아래 포스팅의 cartesian.h 파일에서도 range based for loops 를 사용했는데요~ 참 편리하긴 하더군요.


2014/03/01 - [programming language/C/C++] - C++ Cartesian Product


 

C++ 의 vector 와 같은 container 에 대해 for 문 등을 돌릴 때 iterator 를 이용하던 인덱스를 이용하던 해야 했었는데 간단하게 아래 예와 같이 for 문을 돌릴수가 있습니다… 너무 간단해서 이게 C++ 맞나 하는 생각이 들더군요.

 

vector<int> vec;

vec.push_back( 10 );

vec.push_back( 20 );

 

for (int i : vec )

{

cout << i;

}

 

벡터 내의 값을 바꾸고 싶을 때는 다음과 같이 & 기호를 사용해서 이용하면 되고~

 

for (int& i : vec )

{

i++; // increments the value in the vector

}

 

int 라는 타입 조차 생각해서 써주기 귀찮다 하면 auto 라는 키워드를 사용해서 다음과 같이 작성 할 수 있습니다.

 

for (auto& i : vec )

{

i++; // increments the value in the vector

}

 

위 예들은 C++11에서 추가된 기능이니 만큼 최신의 컴파일러를 사용해야 합니다. 저는 gcc (tdm64-2) 4.8.1 을 사용하고 있고 아래 그림과 같이 codeblock 에서 C++11 Compiler Flag 를 체크 했습니다.





이전 포스팅들에서도 소개한 Cartesian Product 를 C++ 를 사용하여 구성하는 방법에 대해 소개해 드리려 합니다.

  

2013/08/18 - [programming language/MATLAB] - MATLAB 모든 경우의 수 뽑기 Cartesian Product


2013/08/18 - [programming language/powershell] - Powershell 경우의 수 조합 다 구하기(Cartesian Product)

 

아래 주소를 보니 Cartesian Product 와 관련하여 좋은 예제들이 많이 있더군요.

 

http://stackoverflow.com/questions/5279051/how-can-i-create-cartesian-product-of-vector-of-vectors

 

그 중에서 저는 가장 간단해 보이는 anumi 라는 분의 코드를 가져다 사용했습니다.

 

물론 template 형태로 약간 수정만 했습니다.

 

코드를 보다 보니 vector 의 swap 함수를 사용했더군요. Swap 함수는 말 그대로 벡터간에 값을 교환하는 겁니다.

 

Vector 의 Swap 에 대한 설명은 아래 주소 참조바랍니다.

 

http://www.cplusplus.com/reference/vector/vector/swap/

 

요즘 C++ STL 은 정말 좋은 것 같습니다.

 

결과적으로 작성된 cartesian.h 파일은 아래와 같습니다. 

  

cartesian.h


#include <vector>

 

using namespace std;

 

template<typename T>

vector<vector<T>> cart_product (const vector<vector<T>>& v) {

vector<vector<T>> s = {{}};

for (auto& u : v) {

vector<vector<T>> r;

for (auto& x : s) {

for (auto y : u) {

r.push_back(x);

r.back().push_back(y);

}

}

s.swap(r);

}

return s;

}

 

테스트를 위한 main.cpp 파일은 아래와 같이 작성했습니다.

 

#include <iostream>

#include "cartesian.h"

 

using namespace std;

 

int main()

{

    vector<vector<int>> test{{1,2, 56 ,3}, {4,5,6}, {12,32,56}};

    vector<vector<int>> cartprodResult; // result

 

    cartprodResult=cart_product(test); // Cartesian Product

 

    int cnt=0;

 

    for (auto& x : cartprodResult)

    {

        ++cnt;

        cout << cnt << ": \t";

 

        for (auto y : x)

        {

            cout << y << "\t";

        }

        cout << endl;

    }

 

    return 0;

}

 

Cartesian product 를 수행해보면 아래와 같이 결과가 나오는 것을 확인 할 수 있습니다. 간단하죠~ 현재 컴파일러는 gcc (tdm64-2) 4.8.1 이고~ C++11 Compiler Flag를 On 했습니다.



오늘은 간단하게 사용할 수 있는 C++ xml parser 하나 소개해 드리려 합니다.

 

Xml parser 라이브러리의 이름은 pugixml 이고요~

 

아래 주소에서 다운로드 가능합니다.

 

https://code.google.com/p/pugixml/downloads/list

 

다음 그림과 같이 편하실데로~ zip 또는 tar.gz 파일을 다운로드 받으면 됩니다. 저는 현재 최신버전인 1.2 버전의 zip 파일 버전인 pugixml-1.2.zip 을 다운로드 받았습니다.

 

압축을 해제하면 src,scripts,docs,contrib 폴더로 구성되는데요~ 이 중에서 src 폴더가 라이브러리 소스 파일입니다.

 

Xml 을 사용하고자 하는 폴더에 src 폴더의 pugixml.hpp, pugixml.cpp, pugiconfig.hpp 파일들을 추가한 후에 사용하시면 되겠습니다.

 

pugixml-1.2\docs\samples 에는 다양한 예제들이 있는데요~ 저는 xml 파일에 대한 load 부분만 필요해서 load_file.cpp 파일을 사용했습니다.

 

프로젝트에 pugixml.hpp, pugixml.cpp, pugiconfig.hpp, load_file.cpp파일을 추가하고 load_file.cpp 에서 사용하는 tree.xml 파일도 추가 해 줍니다.

 

다음으로 빌드를 하고 실행해 보면~ 다음과 tree.xml파일의 mesh 노드의 name attribute 의 내용인 mesh_root 를 선택적으로 읽어 올 수 있는 것을 확인 할 수 있습니다.

 

라이브러리가 파일만 추가하면 되서 사용하기 쉽고 사용법도 매우 편하네요~

 

속도 등에 대한 테스트는 안 해 봤지만 간단한 용도로 사용하는 제 입장에서는 대 만족이네요.

 

위에 예제로 사용한 codeblock 프로젝트 파일도 추가 합니다.

 


xmltest.zip



  1. Ok Man 2014.06.25 23:58 신고

    컴퓨터 언어 공부는 어렵지 않나요? 저도 공부해보고싶긴한데..

    • 남성 2014.06.26 00:39 신고

      하고 싶은데 어려울까봐 안하시는 건가요? 두려워 말고 시작해 보세요~ 꼭 프로그래머가 되려고 하는게 아니더라도 컴퓨터 언어 공부는 어느정도 필요하다고 봅니다. 요즘은 컴퓨터 교육이 아이들 교과과정에도 포함되고있는 추세죠~ 어차피 컴퓨터는 죽을때 까지 사용하잖아요. 간단한 스크립트 언어부터 시작해 보세요. 삶이 달라지실 거에여~ 블로그 운영에도 도움 되실 거에여~ 윈도우만 사용하신 다면 제 블로그에서도 소개하고 있는 Autohotkey 강추 드립니다.

  2. Ok Man 2014.06.26 02:16 신고

    아 그래요? 블로그 자주 들릴게요 기초적인것부터 차근차근 많이 알려주세요 ^^ 저도 예전부터 컴퓨터 언어에 대해서
    잠시나마 비쥬얼베이직은 배운적이 있지만 제대로 배워본적은 없어서 ㅎㅎ 자주 들릴게요 좋은정보 감사해요!!

    • 남성 2014.06.26 02:41 신고

      실제 그냥 윈도우 사용하는데는 비쥬얼 베이직은 그리 실용적이진 않은데~ Autohotkey 는 정말 실용적이거든요

+ Recent posts