블로그 이미지
Every unexpected event is a path to learning for you.

카테고리

분류 전체보기 (2326)N
Unity3D (570)N
Programming (472)
Unreal (4)
Gamebryo (56)
Tip & Tech (185)
협업 (34)
3DS Max (3)
Game (12)
Utility (116)
Etc (92)
Link (31)
Portfolio (19)
Subject (90)
iOS,OSX (38)
Android (13)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (1)
Memories (19)
Interest (37)
Thinking (36)
한글 (26)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (19)
Exercise (3)
나만의 맛집 (2)
냥이 (9)
육아 (9)
Total1,345,484
Today256
Yesterday332
Statistics Graph

달력

« » 2019.12
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        

공지사항

태그목록

# 문자열 포맷 코드
%s 문자열 (String)
%c 문자 한개 (character)
%d 정수 (Integer)
%f 부동소수 (floating-point)
%o 8진수
%x 16진수
%% Literal % (문자 '%s' 자체)

 


# 자주 사용되는 슬라이싱 예 - 문자열 자르기
>>> a = "20110406Clean"
>>> date = a[:8]
>>> weahter = a[8:]
>>> date
'20110406'
>>> weather
'Clean'

 


# 2개 이상의 값을 치환 - 문자열 포매팅(Formatting)
>>> number = 10
>>> day = "three"
>>> print "I eat %d apples. so I was sick for %s days." % (number, day)
I eat 10 apples. so I was sick for three days.

 


# 문자 갯수 세기(count)
>>> a = "hobby"
>>> a.count('b')
2

 


# 문자 위치 알려주기1(find)
>>> a = "Python is best choice"
>>> a.find('b')   // 존재하지 않으면 -1 반환
10

 

 

# 문자 위치 알려구지2(index)
>>> a = "Life is too short"
>>> a.index('t')
8

 


# 문자열 삽입(join)
>>> a = ","
>>> a.join('abcd') // 문자열의 각각의 문자사이에 변수 a의 값을 삽입
'a,b,c,d'

 


# 왼쪽 공백 지우기(lstrip)
>>> a = " hi"
>>> a.lstrip()
'hi'

 

 

# 오른쪽 공백 지우기(rstrip)
>>> a = "hi "
>>> a.rstrip()
'hi'

 

 

# 양쪽 공백 지우기(strip)
>>> a = " hi "
>>> a.strip()
'hi'

 


# 문자열 바꾸기(replace)
>>> a = "Life is too short"
>>> a.replace("Life", "Your leg")
'Your leg is too short'

 


# 문자열 나누기 (split) - 결과는 list에 저장됨
>>> a = "Life is too short"
>>> a.split()
['Life', 'is', 'too', 'short']

>>> a = "a:b:c:d"
>>> a.split(':')
['a', 'b', 'c', 'd']



[출처] 파이썬 팁) 문자열 다루기|작성자 msBang

Posted by blueasa

댓글을 달아 주세요

[서론]

  이전에 W.O.W 접속유지 프로그램을 만든적은 있지만 그때는 WOW 캡션이 정해져 있었고, 키입력만으로(방향키를 사용했음) 접속유지가 됐기때문에 단순한 키입력 메시지 전달만 하면 끝이었다. 

  다만.. W.O.W 에서 SendMessage를 먹어버려서 PostMessage로 처리했었다.

  (W.O.W 접속유지 프로그램 링크:http://blueasa.tistory.com/527)


  이번에는 서로(현재는 C# -> C++ 만 되는거 보고 정리함.. 나중에 업뎃 할지도..) SendMessage를 보내서 뭔가 일을 꾸밀(?) 수 있게 해보고 싶은마음에 시작.. 물론 양쪽 프로그램은 내가 직접 만든다는 가정하에..

  세상에 선구자는 많으니 역시나..자료를 찾기 시작.. 이전에 간단하나마 만든 것도 있고..

  말재주는 없으니 본론으로 들어가서 그냥 소스 정리..


[사용된 WinAPI 함수 및 중요 키워드]

FindWindow, SendMessage, WM_COPYDATA


[Send : C#]



[Source]

    public class MessageHelper
    {
        [DllImport("User32.dll")]
        private static extern int RegisterWindowMessage(string lpString);

        [DllImport("User32.dll", EntryPoint = "FindWindow")]
        public static extern Int32 FindWindow(String lpClassName, String lpWindowName);

        //For use with WM_COPYDATA and COPYDATASTRUCT
        [DllImport("User32.dll", CharSet = CharSet.Auto, SetLastError = false, EntryPoint = "SendMessage")]
        public static extern int SendMessage(int hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam);

        //For use with WM_COPYDATA and COPYDATASTRUCT
        [DllImport("User32.dll", CharSet = CharSet.Auto, SetLastError = false, EntryPoint = "PostMessage")]
        public static extern int PostMessage(int hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam);

        //For use with WM_COPYDATA and COPYDATASTRUCT*
        [DllImport("user32.dll", CharSet = CharSet.Auto, EntryPoint = "SendMessage")]
        private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

        [DllImport("User32.dll", CharSet = CharSet.Auto, EntryPoint = "SendMessage")]
        public static extern int SendMessage(int hWnd, int Msg, int wParam, int lParam);

        [DllImport("User32.dll", CharSet = CharSet.Auto, EntryPoint = "PostMessage")]
        public static extern int PostMessage(int hWnd, int Msg, int wParam, int lParam);

        [DllImport("User32.dll", EntryPoint = "SetForegroundWindow")]
        public static extern bool SetForegroundWindow(int hWnd);

        public const int WM_USER = 0x400;
        public const int WM_SENDER = WM_USER + 4444;
        public const int WM_COPYDATA = 0x4A;

        //Used for WM_COPYDATA for string messages
        //[StructLayout(LayoutKind.Sequential)] 
        public struct COPYDATASTRUCT
        {
            public int dwData;
            public int cbData;
            //[MarshalAs(UnmanagedType.LPStr)]
            public IntPtr lpData;
        }

        public bool BringAppToFront(int hWnd)
        {
            return SetForegroundWindow(hWnd);
        }

        public int SendWindowsStringMessage(int hWnd, int wParam, string command)
        {
            int result = 0;

            if (hWnd != 0)
            {
                byte[] sarr = System.Text.Encoding.Default.GetBytes(command);
                int len = sarr.Length;

                COPYDATASTRUCT cds = new COPYDATASTRUCT();
                //cds.dwData = (IntPtr)100;
                cds.dwData = 0;
                cds.cbData = len + 1;
                //cds.cbData = Marshal.SizeOf(cds);
                cds.lpData = Marshal.StringToHGlobalAnsi(command);
                //cds.lpData = Marshal.StringToCoTaskMemAnsi(command);

                result = SendMessage(hWnd, WM_COPYDATA, wParam, ref cds);
            }

            return result;
        }

        public int SendWindowsMessage(int hWnd, int Msg, int wParam, int lParam)
        {
            int result = 0;

            if (hWnd != 0)
            {
                result = SendMessage(hWnd, Msg, wParam, lParam);
            }

            return result;
        }

        public int GetWindowID(string className, string windowName)
        {
            return FindWindow(className, windowName);
        }
    }





[Use]


int hWnd = messageHelper.GetWindowID(null, windowCaption);
messageHelper.SendWindowsStringMessage(hWnd, 0, String);



[Receive : C++]


[Source]


WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{  
    switch ( msg )   
    {  
    case WM_COPYDATA:  
        {  
            //Used for WM_COPYDATA for string messages  
            struct COPYDATASTRUCT  
            {  
                int dwData;  
                int cbData;  
                PVOID lpData;  
            };  
  
            COPYDATASTRUCT* cp = (COPYDATASTRUCT*)lParam;  
  
            if( NULL != cp )  
            {  
                String strCommand = "";  
                char szCommand[256] = {0,};  
                  
                memcpy( szCommand, cp->lpData, cp->cbData );  
                  
                if(NULL != szCommand)  
                {  
					/// ToDo  
					/// 여기서 받은 문자열로 할 일 하면 됨.  
					/// dwData는 여기선 의미가 없긴한데 enum이나 int 그대로 써서  
					/// switch문 등으로 분기시켜서 여러가지 다양한 처리를 하려고
					/// 처음 소스 짠사람이 만든 것 같다.  
					/// 다른 일도 분류해서 처리하려면 사용하자.  
                }  
            }  
        }  
        break;  
    }  
}  




[주의]

WM_COPYDATA 는 PostMessage로 날릴 수 없다고 한다. SendMessage를 사용하자.

(상대쪽에서 받기 전에 이쪽에서 메모리 해제 되있으면 AV뜨기때문에..)

참고 링크 : http://lunapiece.net/?mid=Tips&listStyle=webzine&document_srl=3780&sort_index=readed_count&order_type=desc


P.s. 마음대로 되지 않고 삽질도 많이해서 여기저기 쓰이지 않는 주석이 남아있긴 하지만.. 삽질기념(?) 그냥 냅두기..

       하도 검색하고 다녀서 참조한 곳을 다 찾기엔 좀 걸리거나 빼먹을 수 도 있을 것 같다. 출처를 찾으러 가야지..



[참조]

http://boycook.wordpress.com/2008/07/29/c-win32-messaging-with-sendmessage-and-wm_copydata/

http://kofmania.tistory.com/45

http://xarfox.tistory.com/45

http://jacking.tistory.com/134

http://www.hoons.kr/board.aspx?Name=qacshap&Mode=2&BoardIdx=10465&Key=&Value=

http://lunapiece.net/?mid=Tips&listStyle=webzine&document_srl=3780&sort_index=readed_count&order_type=desc

- 그 외 못 적은 곳은.. 죄송합니다..;;



Posted by blueasa

댓글을 달아 주세요

문자열이 지정한 숫자 형식의 유효한 표현인지 확인하려면 모든 기본 숫자 형식에서 구현되며 DateTime 및 IPAddress 같은 형식에서도 구현되는 정적 TryParse 메서드를 사용합니다. 다음 예제에서는 "108"이 유효한 int인지 확인하는 방법을 보여 줍니다.

  int i = 0; 
  string s = "108";
  bool result = int.TryParse(s, out i); //i now = 108

문자열에 비숫자 문자가 포함되어 있는 경우 또는 숫자 값이 지정한 특정 형식에 비해 너무 크거나 너무 작은 경우 TryParse는 false를 반환하고 out 매개 변수를 0으로 설정합니다. 그렇지 않으면 true를 반환하고 out 매개 변수를 문자열의 숫자 값으로 설정합니다.

참고참고

문자열은 숫자만 포함할 수 있으며 사용할 TryParse 메서드 형식에 아직 유효하지 않을 수 있습니다. 예를 들어 "256"은 byte에 대해서는 유효한 값이 아니지만int에 대해서는 유효한 값입니다. 이때 98.6"은 int에 대해 유효한 값이 아니지만 decimal에 대해서는 유효한 값입니다.

다음 예제에서는 longbyte 및 decimal 값의 문자열 표현을 사용하여 TryParse를 사용하는 방법을 보여 줍니다.

string numString = "1287543"; //"1287543.0" will return false for a long
long number1 = 0;
bool canConvert = long.TryParse(numString, out number1);
if (canConvert == true)
  Console.WriteLine("number1 now = {0}", number1);
else
  Console.WriteLine("numString is not a valid long");

byte number2 = 0;
numString = "255"; // A value of 256 will return false
canConvert = byte.TryParse(numString, out number2);
if (canConvert == true)
  Console.WriteLine("number2 now = {0}", number2);
else
  Console.WriteLine("numString is not a valid byte");

decimal number3 = 0;
numString = "27.3"; //"27" is also a valid decimal
canConvert = decimal.TryParse(numString, out number3);
if (canConvert == true)
  Console.WriteLine("number3 now = {0}", number3);
else
  Console.WriteLine("number3 is not a valid decimal");            


또한 기본 숫자 형식에서는 문자열이 유효한 숫자가 아닌 경우 예외를 throw하는 정적 메서드 Parse를 구현합니다. 숫자가 유효하지 않은 경우 false를 반환하기 때문에 일반적으로 TryParse를 사용하는 것이 더 효과적입니다.

TryParse 또는 Parse를 사용하여 텍스트 상자와 콤보 상자 등의 컨트롤로부터 항상 사용자 입력의 유효성을 검사합니다.



출처 :  http://msdn.microsoft.com/ko-kr/library/bb384043.aspx
Posted by blueasa

댓글을 달아 주세요

C# 문자열은 string 키워드를 사용하여 선언된 문자의 배열입니다. 문자열 리터럴은 다음 예제에서처럼 따옴표를 사용하여 선언됩니다.

string s = "Hello, World!";

다음과 같이 부분 문자열을 추출하고 문자열을 연결할 수 있습니다.

string s1 = "orange";
string s2 = "red";

s1 += s2;
System.Console.WriteLine(s1);  // outputs "orangered"

s1 = s1.Substring(2, 5);
System.Console.WriteLine(s1);  // outputs "anger"

문자열 개체는 한 번 만들어지면 변경할 수 없는 "변경 불가능" 개체입니다. 문자열에 대해 동작하는 메서드는 실제로 새 문자열 개체를 반환합니다. 이전 예제에서 s1과 s2의 내용이 결합되어 단일 문자열이 만들어질 때, "orange"와 "red"를 포함하는 두 문자열은 모두 변경되지 않습니다. += 연산자는 결합된 내용을 포함하는 새 문자열을 만듭니다. 결과적으로 s1도 다른 문자열을 참조하게 됩니다. "orange" 만 포함하는 문자열은 여전히 존재하지만, s1이 결합되는 시점에서 더 이상 참조되지 않습니다.

Note참고

문자열에 대한 참조를 만들 때는 주의해야 합니다. 문자열에 대한 참조를 만든 다음 해당 문자열을 "수정"할 경우 해당 참조는 문자열을 수정할 때 만든 새 개체가 아니라 원래 개체를 계속해서 가리킵니다. 다음 코드에서는 이를 보여 줍니다.

string s1 = "Hello";
string s2 = s1;
s1 += " and goodbye.";
Console.WriteLine(s2); //outputs "Hello"

문자열을 수정하면 새 문자열 개체가 만들어지므로 대량의 연결 작업이나 기타 관련된 문자열 조작 작업을 수행할 경우에는 성능상의 이유로 다음과 같이 StringBuilder 클래스를 사용해야 합니다.

System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.Append("one ");
sb.Append("two ");
sb.Append("three");
string str = sb.ToString();

StringBuilder 클래스에 대해서는 "Stringbuilder 사용" 단원에서 자세히 설명합니다.

문자열 작업

이스케이프 문자

"\n"(줄 바꿈) 및 "\t"(탭) 등의 이스케이프 문자를 문자열에 포함할 수 있습니다. 예를 들어, 다음 줄은

string hello = "Hello\nWorld!";

다음 줄과 동일합니다.

Hello

World!

백슬래시를 포함하려면 앞에 백슬래시가 하나 더 있어야 합니다. 예를 들어, 다음 문자열은

string filePath = "\\\\My Documents\\";

다음 문자열과 동일합니다.

\\My Documents\

@ 기호

@ 기호를 사용하면 문자열 생성자가 이스케이프 문자와 줄 바꿈을 무시하도록 할 수 있습니다. 따라서 다음 두 개의 문자열은 동일합니다.

string p1 = "\\\\My Documents\\My Files\\";
string p2 = @"\\My Documents\My Files\";

ToString()

Object에서 파생된 모든 개체와 마찬가지로 문자열에서는 값을 문자열로 변환하는 ToString 메서드를 제공합니다. 이 메서드를 사용하면 다음과 같이 숫자 값을 문자열로 변환할 수 있습니다.

int year = 1999;
string msg = "Eve was born in " + year.ToString();
System.Console.WriteLine(msg);  // outputs "Eve was born in 1999"

개별 문자 액세스

SubString()Replace(),Split() 및 Trim() 등의 메서드를 사용하여 문자열에 포함된 개별 문자에 액세스할 수 있습니다.

string s3 = "Visual C# Express";

System.Console.WriteLine(s3.Substring(7, 2));         // outputs "C#"
System.Console.WriteLine(s3.Replace("C#", "Basic"));  // outputs "Visual Basic Express"

또한 다음과 같이 문자를 문자 배열에 복사할 수 있습니다.

string s4 = "Hello, World";
char[] arr = s4.ToCharArray(0, s4.Length);

foreach (char c in arr)
{
    System.Console.Write(c);  // outputs "Hello, World"
}

다음과 같이 인덱스를 사용하여 문자열의 개별 문자에 액세스할 수 있습니다.

string s5 = "Printing backwards";

for (int i = 0; i < s5.Length; i++)
{
    System.Console.Write(s5[s5.Length - i - 1]);  // outputs "sdrawkcab gnitnirP"
}

대/소문자 바꾸기

문자열의 문자를 대문자 또는 소문자로 변경하려면 다음과 같이 ToUpper() 또는 ToLower()를 사용합니다.

string s6 = "Battle of Hastings, 1066";

System.Console.WriteLine(s6.ToUpper());  // outputs "BATTLE OF HASTINGS 1066"
System.Console.WriteLine(s6.ToLower());  // outputs "battle of hastings 1066"

비교

두 문자열을 비교하는 가장 간단한 방법은 대/소문자 구분 비교를 수행하는 == 및 != 연산자를 사용하는 것입니다.

string color1 = "red";
string color2 = "green";
string color3 = "red";

if (color1 == color3)
{
    System.Console.WriteLine("Equal");
}
if (color1 != color2)
{
    System.Console.WriteLine("Not equal");
}

또한 문자열 개체에는 한 문자열이 다른 문자열보다 작은지(<) 또는 큰지(>)에 따라 정수 값을 반환하는CompareTo() 메서드가 있습니다. 문자열을 비교할 때는 유니코드 값을 사용하며, 소문자 값이 대문자 값보다 작습니다.

string s7 = "ABC";
string s8 = "abc";

if (s7.CompareTo(s8) > 0)
{
    System.Console.WriteLine("Greater-than");
}
else
{
    System.Console.WriteLine("Less-than");
}

다른 문자열 내에서 문자열을 검색하려면 IndexOf()를 사용합니다. IndexOf()는 검색 문자열을 찾지 못한 경우 -1을 반환하고, 검색 문자열을 찾은 경우에는 이 문자열이 처음 나타나는 위치의 인덱스(0부터 시작)를 반환합니다.

string s9 = "Battle of Hastings, 1066";

System.Console.WriteLine(s9.IndexOf("Hastings"));  // outputs 10
System.Console.WriteLine(s9.IndexOf("1967"));      // outputs -1

문자열을 부분 문자열로 분할

문장을 개별 단어로 분할하는 등 문자열을 부분 문자열로 변환하는 것은 일반적인 프로그래밍 작업입니다.Split() 메서드는 공백 문자 등의 구분 기호 char 배열을 받아 부분 문자열의 배열을 반환합니다. 다음과 같이foreach를 사용하여 이 배열에 액세스할 수 있습니다.

char[] delimit = new char[] { ' ' };
string s10 = "The cat sat on the mat.";
foreach (string substr in s10.Split(delimit))
{
    System.Console.WriteLine(substr);
}

이 코드는 다음과 같이 각 단어를 별도의 줄에 출력합니다.

The

cat

sat

on

the

mat.

Null 문자열 및 빈 문자열

빈 문자열은 문자가 들어 있지 않은 System.String 개체의 인스턴스입니다. 빈 문자열은 다양한 프로그래밍 시나리오에서 빈 텍스트 필드를 나타내는 데 매우 일반적으로 사용됩니다. 빈 문자열은 유효한 System.String개체이므로 빈 문자열에서 메서드를 호출할 수 있습니다. 빈 문자열은 다음과 같이 초기화됩니다.

string s = "";

이와 반대로, null 문자열은 System.String 개체의 인스턴스를 참조하지 않으며 null 문자열에서 메서드를 호출하려고 하면 항상 NullReferenceException이 발생합니다. 그러나 다른 문자열과의 연결 및 비교 연산에서는 null 문자열을 사용할 수 있습니다. 다음 예제에서는 null 문자열을 참조할 때 예외가 throw되는 경우와 그렇지 않은 경우를 보여 줍니다.

string str = "hello";
string nullStr = null;
string emptyStr = "";

string tempStr  = str + nullStr; // tempStr = "hello"
bool b = (emptyStr == nullStr);// b = false;
emptyStr + nullStr = ""; // creates a new empty string
int I  = nullStr.Length; // throws NullReferenceException

StringBuilder 사용

StringBuilder 클래스는 프로그램에서 수행할 문자열 조작 작업이 많을 경우 성능을 향상시켜 주는 문자열 버퍼를 만듭니다. 또한 StringBuilder 문자열을 사용하면 개별 문자를 다시 할당할 수 있습니다. ���러한 기능은 기본 제공 데이터 형식에서는 지원하지 않습니다. 예를 들어 다음 코드에서는 새 문자열을 만들지 않고 문자열의 내용을 변경합니다.

System.Text.StringBuilder sb = new System.Text.StringBuilder("Rat: the ideal pet");
sb[0] = 'C';
System.Console.WriteLine(sb.ToString());
System.Console.ReadLine();

이 예제에서는 StringBuilder 개체를 사용하여 숫자 형식의 집합에서 문자열을 만듭니다.

class TestStringBuilder
{
    static void Main()
    {
        System.Text.StringBuilder sb = new System.Text.StringBuilder();

        // Create a string composed of numbers 0 - 9
        for (int i = 0; i < 10; i++)
        {
            sb.Append(i.ToString());
        }
        System.Console.WriteLine(sb);  // displays 0123456789

        // Copy one character of the string (not possible with a System.String)
        sb[0] = sb[9];

        System.Console.WriteLine(sb);  // displays 9123456789
    }
}

자세한 내용

C# 프로그래머 참조:

참고 항목







Posted by blueasa

댓글을 달아 주세요