300x250
300x250

studen_data.xlsx  => student_data.json

[
  {
    "id": 5000,
    "name": "길동이",
    "korean": 100,
    "math": 90,
    "english": 80
  },
  {
    "id": 5001,
    "name": "철수",
    "korean": 70,
    "math": 60,
    "english": 50
  },
  {
    "id": 5002,
    "name": "유리",
    "korean": 40,
    "math": 30,
    "english": 20
  },
  {
    "id": 5003,
    "name": "훈이",
    "korean": 10,
    "math": 0,
    "english": 10
  }
]

study_data.xlsx => study_data.json

[
  {
    "id": 200,
    "professor": "수학왕",
    "class_subject": "수학",
    "phone": "010-1234-5678"
  },
  {
    "id": 201,
    "professor": "영어킹",
    "class_subject": "영어",
    "phone": "010-9876-5432"
  },
  {
    "id": 202,
    "professor": "국어왕",
    "class_subject": "국어",
    "phone": "010-2222-3333"
  },
  {
    "id": 203,
    "professor": "코딩왕",
    "class_subject": "프로그래밍",
    "phone": "010-1111-2222"
  }
]

user_data.xlsx => user_data.json

[
  {
    "id": 1000,
    "name": "길동이",
    "weight": 40.3,
    "age": 8
  },
  {
    "id": 1001,
    "name": "철수",
    "weight": 41.3,
    "age": 9
  },
  {
    "id": 1002,
    "name": "유리",
    "weight": 43.5,
    "age": 10
  },
  {
    "id": 1003,
    "name": "훈이",
    "weight": 45.7,
    "age": 6
  }
]

 

위와같은 엑셀 데이터(xlsx) 파일을 json화 해서 C# 프로젝트에서 적용하는 방법을 정리 해봤어요.

데이터 파일을 json화를 했다면 (프로젝트에 도구 => NuGet 패키지 관리자(N) => 솔루션용 Nuget 패키지 관리)로 들어가줍니다.

 

 

들어가서 찾아보기탭을 누른다음 검색창에 newtonsoft.json을 검색한후에 우측에 현재 프로젝트를 선택하고 설치를 눌러줘요.

 

설치가 완료되면 솔루션 탐색기에서 참조 버튼을 눌렀을때 Newtonsoft.Json이 추가가 되있다면 준비는 끝난거에요.

 

저는 student_data.json과 매칭되는 클래스파일을 선언 해준 다음 데이터들을 관리해줄 싱글톤 클래스를 싱글톤으로 선언 해줬어요.

 

StudentData.cs

namespace SLG_CS_JsonExample
{   
    public class StudentData
    {        
        public int id;        
        public string name;        
        public int korean;        
        public int math;        
        public int english;
    }
}

 

DataManager.cs

using Newtonsoft.Json;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace SLG_CS_JsonExample
{
    public sealed class DataManager
    {
        // 외부에서 접근 읽기 상태로만 접근할 수 있어 데이터 수정을 막고 데이터를 읽기만 할 수 있는 싱글톤 DataManager 선언
        public static readonly DataManager instance = new DataManager();

        // 딕셔너리로 데이터관리
        private Dictionary<int, StudentData> dicStudents = new Dictionary<int, StudentData>();

        private DataManager()
        {
        }

        // student_data.json 데이터를 불러와서 딕셔너리에 값을 저장하는 메소드
        public void LoadStudentDatas()
        {
            string json = File.ReadAllText("./student_data.json");
            // 역직렬화  : 문자열 -> 객체 
            StudentData[] studentDatas = JsonConvert.DeserializeObject<StudentData[]>(json);

            // 내부 람다의 의미는 배열에 담긴 객체의 속성중 키를 어떤것으로 할것인가?
            this.dicStudents = studentDatas.ToDictionary(x => x.id);    
        }

        // dicStudents에서 id값으로 데이터를 검색한 후 해당하는 데이터를 가져오는 메소드
        public StudentData GetStudentData(int id)
        {
            return this.dicStudents[id];
        }

        // dicStudents에 딕셔너리를 통째로 가져옴으로써 전체 데이터를 받아오는 메소드
        public Dictionary<int, StudentData> GetStudentDatas()
        {
            return this.dicStudents;
        }
    }
}

이렇게 해놓은 다음

 

DataTest.cs

using System;
using System.Collections.Generic;

namespace SLG_CS_JsonExample
{
    public class DataTest
    {
        public DataTest()
        {
            // json데이터를 불러와서 딕셔너리에 저장
            DataManager.instance.LoadStudentDatas();

            // 딕셔너리에 저장된 StudentData데이터딕셔너리를 통째로 DataManager 인스턴스에 접근하여 받아오기
            Dictionary<int, StudentData> studentDatas = DataManager.instance.GetStudentDatas();

            foreach (var studentData in studentDatas)
            {
                var id = studentData.Value.id;
                var name = studentData.Value.name;
                var korean = studentData.Value.korean;
                var math = studentData.Value.math;
                var english = studentData.Value.english;
                Console.WriteLine("id : {0}, name : {1}, korean : {2}, math : {3}, english : {4}", id, name, korean, math, english);
            }
            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine("Search Data id : 5002");
            // 딕셔너리에 특정 데이터만 검색하여 접근하기
            StudentData searchData = DataManager.instance.GetStudentData(5002);

            Console.WriteLine("id : {0}, name : {1}, korean : {2}, math : {3}, english : {4}", 
                searchData.id, searchData.name, searchData.korean, searchData.math, searchData.english);
        }
    }
}

 

이런 식으로 사용할 수 있어요.

근데 이런 방식으로 하면 데이터파일이 증가할때마다

 

private Dictionary<int, StudentData> dicStudents = new Dictionary<int, StudentData>();

변수와 LoadStudentDatas(), GetStudentData(int id), GetStudentDatas() 메소드를 매번 정의 해줘야 해요.

모든 경우엔 할 수 없지만, 위에서 3개의 데이터엔 id라는 공통 필드가 있어요. 이 경우엔 이필드를 이용하여 일반화를 하면 좀 더 쉽게 데이터를 관리 할 수 있어요.

 

먼저 id값을 갖는 부모 클래스변수를 선언 해줘요.

RawData.cs

namespace SLG_CS_JsonExample
{
    public class RawData
    {
        public int id;
    }
}

그리고 데이터 클래스변수들은 이 클래스를 상속받아요.

StudentData.cs

namespace SLG_CS_JsonExample
{    
    public class UserData : RawData
    {            
        public string name;        
        public float weight;        
        public int age;
    }
}

Study.cs

namespace SLG_CS_JsonExample
{    
    public class StudyData : RawData
    {         
        public string professor;        
        public string class_subject;        
        public string phone;
    }
}

UserData.cs

namespace SLG_CS_JsonExample
{    
    public class UserData : RawData
    {            
        public string name;        
        public float weight;        
        public int age;
    }
}

이렇게 클래스들을 작성을 해준후 DataManager 에서 json데이터를 불러와서 저장하고 제가 직접 사용할수 있는 코드를 새로 작성해주면 되요.

DataManager.cs

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace SLG_CS_JsonExample
{
    public sealed class DataManager
    {
        // 외부에서 접근 읽기 상태로만 접근할 수 있어 데이터 수정을 막고 데이터를 읽기만 할 수 있는 싱글톤 DataManager 선언
        public static readonly DataManager instance = new DataManager();

        // 딕셔너리로 데이터관리
        private Dictionary<int, RawData> dicDatas = new Dictionary<int, RawData>();

        private DataManager()
        {
        }

        // json 데이터를 불러와서 딕셔너리에 저장하는 메소드
        public void LoadData<T>(string path) where T : RawData
        {
            var json = File.ReadAllText(path);
            T[] arr = JsonConvert.DeserializeObject<T[]>(json);
            arr.ToDictionary(x => x.id).ToList().ForEach(x => dicDatas.Add(x.Key, x.Value));
        }

        // id 값으로 딕셔너리에서 검색하는 메소드
        public T GetData<T>(int id) where T : RawData
        {
            var collection = this.dicDatas.Values.Where(x => x.GetType().Equals(typeof(T)));
            return (T)collection.ToList().Find(x => x.id == id);
        }

        // 특정 데이터 그룹을 검색하고싶을대 해당 데이터 타입을 호출하면 해당 데이터타입 객체만 반환한다.
        // ex(GetDatas<Student>()) = 딕셔너리에 저장된 데이터들중 Student타입을 가진 객체들만 반환
        public IEnumerable<T> GetDatas<T>() where T : RawData
        {
            IEnumerable<RawData> col = this.dicDatas.Values.Where(x => x.GetType().Equals(typeof(T)));
            return col.Select(x => (T)Convert.ChangeType(x, typeof(T)));
        }
    }
}

 

아래는 DataManager를 실제 사용하여 데이터를 불러오는 예제에요.

DataTest.cs

using System;
using System.Linq;
using System.Collections.Generic;

namespace SLG_CS_JsonExample
{
    public class DataTest
    {
        public DataTest()
        {
            // json데이터를 불러와서 딕셔너리에 저장
            DataManager.instance.LoadData<StudentData>("./student_data.json");
            DataManager.instance.LoadData<StudyData>("./study_data.json");
            DataManager.instance.LoadData<UserData>("./user_data.json");

            // 딕셔너리에 저장된 StudentData데이터딕셔너리를 통째로 DataManager 인스턴스에 접근하여 받아오기
            IEnumerable<StudentData> studentDatas = DataManager.instance.GetDatas<StudentData>();
            List<StudentData> studentDataList = studentDatas.ToList();
            Console.WriteLine("=============studentDataList=============");
            foreach (var studentData in studentDataList)
            {
                var id = studentData.id;
                var name = studentData.name;
                var korean = studentData.korean;
                var math = studentData.math;
                var english = studentData.english;
                Console.WriteLine("id : {0}, name : {1}, korean : {2}, math : {3}, english : {4}", id, name, korean, math, english);
            }

            // 딕셔너리에 저장된 StudyData데이터딕셔너리를 통째로 DataManager 인스턴스에 접근하여 받아오기
            IEnumerable<StudyData> studyDatas = DataManager.instance.GetDatas<StudyData>();
            List<StudyData> studyDataList = studyDatas.ToList();
            Console.WriteLine("=============studyDataList=============");
            foreach (var studyData in studyDataList)
            {
                var id = studyData.id;
                var professor = studyData.professor;
                var class_subject = studyData.class_subject;
                var phone = studyData.phone;
                Console.WriteLine("id : {0}, professor : {1}, class_subject : {2}, phone : {3}", id, professor, class_subject, phone);
            }

            // 딕셔너리에 저장된 UserData데이터딕셔너리를 통째로 DataManager 인스턴스에 접근하여 받아오기
            IEnumerable<UserData> userDatas = DataManager.instance.GetDatas<UserData>();
            List<UserData> userDataList = userDatas.ToList();
            Console.WriteLine("=============userDataList=============");
            foreach (var userData in userDataList)
            {
                var id = userData.id;
                var name = userData.name;
                var weight = userData.weight;
                var age = userData.age;
                Console.WriteLine("id : {0}, name : {1}, weight : {2}, age : {3}", id, name, weight, age);
            }
            Console.WriteLine();
            Console.WriteLine("Search Data id : 5002");
            // 딕셔너리에 특정 데이터만 검색하여 접근하기
            StudentData searchData = DataManager.instance.GetData<StudentData>(5002);

            Console.WriteLine("id : {0}, name : {1}, korean : {2}, math : {3}, english : {4}", 
                searchData.id, searchData.name, searchData.korean, searchData.math, searchData.english);
        }
    }
}

300x250
300x250

알고리즘 문제 풀이입니다.

1. 제목

- 백준 10828 스택

- BOJ 10828 스택


2. 문제설명

평범하게 스택을 구현하는 문제 입니다.


3. 풀이과정

사실 C++ STL 라이브러리에 stack이 이미 구현이 되어 있는데 그대로 쓰면 너무 양심에 찔려서 매우 유사한 vector로 구현 해봤습니다.


4. 함수설명

vector에 사실 size와 empty가 다 구현이 되어 있어서 저는 그냥 사용만 했습니다.

vector.size() // 벡터에 원소수 출력합니다.

vector.empty() // 벡터에 원소가 없으면 1 출력 있으면 0 출력합니다.

vector.push_back() // 벡터에 맨 끝에 원소 삽입합니다

vector.back() // 벡터에 맨 마지막 값 가리킴, 스택의 탑과 유사합니다.

vector.pop() // 벡터 맨 마지막값 삭제합니다.


5. 코드

#include <iostream>
#include <string>
#include <vector>

using namespace std;

int main()
{
	vector <int> vec_stack;
	int length;

	cin >> length;

	for (int i = 0; i < length; i++)
	{
		string command;
		cin >> command;

		if (command == "push")
		{
			int num;
			cin >> num;
			vec_stack.push_back(num);
		}
		else if (command == "pop")
		{
			if (vec_stack.empty())
			{
				cout << "-1" << endl;
			}
			else
			{
				cout << vec_stack.back() << endl;
				vec_stack.pop_back();
			}
		}
		else if (command == "size")
		{
			cout << vec_stack.size() << endl;
		}
		else if (command == "empty")
		{
			cout << vec_stack.empty() << endl;
		}
		else if (command == "top")
		{
			if (vec_stack.empty())
			{
				cout << "-1" << endl;
			}
			else
			{
				cout << vec_stack.back() << endl;
			}			
		}
		else
		{
			cout << "ERROR" << endl;
		}

	}
}

 

출처 : www.acmicpc.net/problem/10828

감사합니다.

300x250
300x250

알고리즘 문제를 풀다보면 vector에 값을 2개씩 넣고싶을때가 생기는데여 map을 써도 되겠지만 벡터가 좀더 친숙할 때가 있더라구여

#include <iostream>
#include <vector>

using namespace std;

int main()
{
	vector <pair<int, int>> vec;

	int num1, num2;
	int cnt;
	cin >> cnt;
	for (int i = 0; i < cnt; i++)
	{
		cin >> num1;
		cin >> num2;
		vec.push_back(make_pair(num1, num2));
	}

	for (int i = 0; i < cnt; i++)
	{
		cout << "vec[" << i << "].first : " << vec[i].first << endl;
		cout << "vec[" << i << "].second : " << vec[i].second << endl;
	}
}

 

300x250
300x250

    class productDTO
    {

        private string name;

 

        public string GetName()
        {
            return name;
        }
        public void SetName(string name)
        {
            this.name = name;
        }

    }


        private void button1_Click(object sender, EventArgs e)
        {
            productDTO productDTO = new productDTO();

            productDTO.SetName("컴퓨터");

            MessageBox.Show(productDTO.GetName());


        }
    

 

 

평소에난 get, set을 이렇게 사용 했는데 C# 에서는 좀더 편하게 사용이 가능했다.

 

    class productDTO 
    {

        private string name;

 

        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                name = value;
            }
        }

    }

 

        private void button1_Click(object sender, EventArgs e) 
        { 
            productDTO productDTO = new productDTO(); 

 

            productDTO.Name = "컴퓨터";
            MessageBox.Show(productDTO.Name);
        } 

 

 

 

300x250
300x250

1. 중복된 값 제거하고 출력

SELECT DISTINCT [컬럼명]

FROM [테이블명];

 

예) SELECT DISTINCT DEPTNO

FROM EMP;

 

2. 원하는 조건 출력하기

SELECT [컬럼명]

FROM [테이블명]

WHERE [조건];

 

예)

SELECT *

FROM EMP

WHERE SAL = 800;

 

SELECT *

FROM EMP

WHERE JOB ='영업직';

문자 조회할 때는 영어 대소문자를 구분하고 작은따옴표를 사용한다.

 

SELECT *

FROM EMP

WHERE hiredate ='80/12/17';

날짜 조회하기

 

3. 기본 산술 연산자 사용하기

위데이터 에서 연봉 구하기

 

SELECT NAME,PAY, PAY*12

FROM MYEMP

 

4. 다양한 연산자

연산자 종류

설명

=

비교 대상에서 같은 조건을 검색

!=, <>

비교 대상에서 같지 않은 조건을 검색

>

비교 대상에서 큰 조건을 검색

>=

비교 대상에서 크거나 같은 조건을 검색

<

비교 대상에서 작은 조건을 검색

<=

비교 대상에서 작거나 같은 조건을 검색

BETWEEN a AND b

A와 B사이에 있는 범위 값을 모두 검색

IN(a,b,c)

A이거나 B이거나 C인 조건을 검색

LIKE

특정 패턴을 가지고 있는 조건을 검색

IS NULL/IS NOT NULL

NULL 값을 검색 / NULL이 아닌 값을 검색

A AND B

A 조건과 B 조건을 모두 만족하는 값만 검색

A OR B

A 조건이나 B 조건 중 한 가지라도 만족하는 값을 검색

NOT A

A가 아닌 조건을 검색

 

- BETWEEN 연산자로 PAY가 20000000 ~ 30000000 사이인 사람들의 이름과 PAY를 검색해보자.

SELECT NAME, PAY

FROM MYEMP

WHERE PAY BETWEEN 20000000 AND 30000000;

 

같은 결과로 AND 연산자로도 검색이 가능하다.

SELECT NAME, PAY

FROM MYEMP

WHERE PAY >= 20000000

AND PAY <= 30000000;

 

특정 구간의 값을 검색할 때 가급적 AND 연산자를 권장한다고 한다.

 

예)

- IN 연산자로 PAY가 20000000 이거나 30000000인 사람 찾기

SELECT NAME, PAY

FROM MYEMP

WHERE PAY IN(20000000,30000000);

 

예)

- LIKE 연산자로 이름이 'D'로 시작하는사람을 검색해보자.

SELECT NAME

FROM MYEMP

WHERE NAME LIKE 'D%';

 

5. 정렬하기 - ORDER BY

 

- 한글 : 가, 나, 다 ...

- 영어 : A, B, C ...

- 숫자 : 1, 2, 3 ...

- 날짜 : 오래된 날짜부터 최근 날짜로 정렬

 

예) PAY순으로 오름차순 정렬

SELECT * FROM MYEMP

ORDER BY PAY ASC;

 

예) PAY순으로 내림차순 정렬

SELECT * FROM MYEMP

ORDER BY PAY DESC;

300x250
300x250

내프로그램 으로 카카오톡 메시지를 보낼일이 있어 찾아보니 다음과 같은 코드가 있었다.

 

        [System.Runtime.InteropServices.DllImport("User32", EntryPoint = "FindWindow")] 
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 

        [System.Runtime.InteropServices.DllImport("User32", EntryPoint = "FindWindowEx")] 
        public static extern IntPtr FindWindowEx(IntPtr hWnd1, IntPtr hWnd2, string lpsz1, string lpsz2); 

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

        [DllImport("user32.dll")] 
        public static extern uint PostMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);

 

        private void sendMsg(string msg) 
        { 
            IntPtr hd01 = kakaoFindWindow(null, "대화방제목"); 
            if (hd01 != IntPtr.Zero) 
            { 

                IntPtr hd03 = kakaoFindWindowEx(hd01, IntPtr.Zero, "RichEdit20W", ""); 

                SendMessage(hd03, 0x000c, 0, msg); 
                PostMessage(hd03, 0x0100, 0xD, 0x1C001); 
            } 
        }

 

이렇게 하면 전송은 되지만 문제가 하나 있었다.

 

처음에는 잘보내지는데 대화방을 최소화 했다가 다시 열면 전송이 이상하게 되는 것이다.

정확한 이유를 알아보기는 귀찮아서.. 꼼수를 썼다.

 

 

        [System.Runtime.InteropServices.DllImport("User32", EntryPoint = "FindWindow")]
        private static extern IntPtr kakaoFindWindow(string lpClassName, string lpWindowName);

        [System.Runtime.InteropServices.DllImport("User32", EntryPoint = "FindWindowEx")]
        public static extern IntPtr kakaoFindWindowEx(IntPtr hWnd1, IntPtr hWnd2, string lpsz1, string lpsz2);

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

        [DllImport("user32.dll")]
        public static extern uint PostMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);

 

        private void sendMsg(string msg)
        {
            IntPtr hd01 = kakaoFindWindow(null, "대화방제목");
            if (hd01 != IntPtr.Zero)
            {

                IntPtr hd03 = kakaoFindWindowEx(hd01, IntPtr.Zero, "RichEdit20W", "");

                SendMessage(hd03, 0x000c, 0, msg);
                PostMessage(hd03, 0x0100, 0xD, 0x1C001);
                Thread.Sleep(100);
                PostMessage(hd03, 0x0100, 0xD, 0x1C001);
            }
        }

 

PostMessage(hd03, 0x0100, 0xD, 0x1C001);  // 이부분이 엔터 메시지 인거같다.

 

 

postmessage를 바로 쓰면 입력이 안되길래 sleep으로 딜레이를 살짝줬더니 잘된다.

 

잡담을 하자면 난 카카오톡메시지 보내는 프로그램만 만들거가 아니기 때문에 FindWindow를 여러번 사용해야 하는데 

        [System.Runtime.InteropServices.DllImport("User32", EntryPoint = "FindWindow")] 
        private static extern IntPtr "변수명"(string lpClassName, string lpWindowName); 

빨간색 부분을 바꿔서 사용 가능한거 같다. 이런식으로 여러개의 findwindow를 사용할수 있을듯.

300x250
300x250

실험용으로 만든 계정을 삭제할려고 했는데 삭제가 안된다.

오류코드는 ORA-28014: 관리 사용자를 삭제할 수 없습니다.

검색 해보니까

alter session set "_oracle_script"=true;

를 입력하고 삭제하면 된다고한다.

잘된다.

300x250
300x250

여러개의 컬럼을 마치 하나의 컬럼인 것처럼 연결해서 출력해야 하는 경우가 있다. 이때 사용할 수 있는 연산자가 연결 연산자이다.

위 데이터에서 이름, 직업, 급여만 보고싶다면 다음과 같이 입력하면 된다.

SELECTG ENAME, JOB, SAL

FROM EMP;

이때 3개의 컬럼 데이터를 1개의 컬럼처럼 보이게 쓰는게 연결 연산자이다.

SELECT ENAME || '/' || JOB || '/' || SAL "이름/직업/급여/"

FROM EMP;

|| 파이프 연산자2개를 이어서 쓰는거같은데

재밌는 기능 인거같다.

300x250
300x250

 

@경로\\[파일이름]

예) @c:\\temp\\test_data.sql

300x250
300x250

유저 생성중 [ORA-65096 : 공통 사용자 또는 롤 이름이 부적합합니다.] 이런 오류가 뜨는 경우가 있어요.

찾아보니 오라클12c로 넘어 오면서 계정이름 앞에 c## 을 붙여줘야 가능하다고 하네요.

예)CREATE USER c##SCOTT IDENTIFIED BY TIGER;

이거 귀찮으신 분들은

ALTER SESSION SET"_ORACLE_SCRIPT"=true;

하면 c##안붙여도 됩니다.

300x250
300x250

1. 오라클 유저 만들기

CREATE USER [유저이름]

IDENTIFIED BY [비밀번호];

예) create user scott identified by tiger;

2. 유저에 권한 주기

GRANT CONNECT, RESOURCE, DBA TO [유저이름]; // (모든 권한 주기)

예) GRANT CONNECT, RESOURCE, DBA TO SCOTT;

3. 유저 삭제하기

DROP USER [유저이름] CASCADE;

예) DROP USER SCOTT CASCADE;

4.유저 비밀번호 바꾸기

ALTER USER [유저이름] IDENTIFIED BY [새비밀번호];

300x250
300x250