using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO; // 파일스트림
using System.Windows.Forms; // OpenFileDialog
using System.Runtime; // Trim
namespace IniProgram
{
public partial class Test : Form
{
// < 변수 모음 >
string filePath; // 파일경로 (다양한 함수에서 써야하니 전역으로 둔다)
int lineCount; // 파일이 총 몇줄인지 카운트
// 파싱한걸 담을 변수들
string allFile; // 데이터를 전체 담을 배열
//string[] data = new string[];
List<string> data = new List<string>(); // 한줄씩 담을 배열
char section; // 섹션을 저장하는 변수
char key; // 키를 저장하는 변수
char value; // 값을 저장하는 변수
List<char> sections; // char형 리스트 배열 (동적할당)
List<char> keys;
List<char> values;
string stringSection = " ";
string stringKey = " ";
string stringValue = " ";
string mainValue = " "; // 유저가 고른 Value
public Test()
{
InitializeComponent();
}
public class Ini
{
private string _section = " ";
public int _key;
private string _value = " ";
}
// [ 1. 파일열기 ] //////////////////////////////////////////////////////////////////////////
private void btn_open_Click(object sender, EventArgs e)
{
// sender = 이벤트를 보내는 객체
// e = 이벤트 핸들러가 사용하는 파라미터
// 이벤트 핸들러를 추가하는 가장 간단한 방식 = 더블클릭
OpenFileDialog ofd = new OpenFileDialog(); // 파일 대화상자 객체 생성
if (ofd.ShowDialog() == DialogResult.OK) // ofd가 대화상자를 띄움
{
filePath = ofd.FileName; // 경로를 저장하는 변수에 파일명 저장
//MessageBox.Show("선택한 파일: " + filePath);
}
// [파일읽기]
allFile = File.ReadAllText(filePath); // 변수에 파일내용 다 넣기
lineCount = File.ReadAllLines(filePath).Length; // 파일이 몇줄인지
Console.WriteLine($"줄수:" + lineCount); // for문 돌릴 때 필요함
tb_allFile.Text = allFile; // ui 표시
pasingFile(filePath, allFile);// 파일 읽었으니까 이제 파싱
}
// [ 2. 파싱하기 ] //////////////////////////////////////////////////////////////////////////
private void pasingFile(string filePath, string allFile)
{
Console.WriteLine($"(전)allFile=" + '\n' + allFile); // 현재 담은 데이터 찍어보기 (뭐들어있나)
// 인스턴스 생성 (메모리 할당)
sections = new List<char>();
keys = new List<char>();
values = new List<char>();
// 본격 파싱 조건문
for (int i=0; i<lineCount; i++) // 줄수만큼 반복 (한줄한줄 읽기)
{
allFile.Replace("\n", ""); // 개행 제거
allFile.Trim(); // 문자열 앞뒤 공백 제거
allFile.Trim('\n'); // 개행 제거
//Console.WriteLine($"allFile 수정 후: " + allFile);
string[] disk = allFile.Split('\n'); //한줄씩 배열에 저장(인덱스로 꺼내쓰기)
for (i=0; i<disk.Length+1; i++)
{
data.Add(disk[i]);
}
data[i].Trim(); // 한줄씩 앞뒤 공백 제거
data[i].Replace(" ", " "); // 한줄씩 개행있으면 제거
if (string.IsNullOrWhiteSpace(data[i])) // 빈줄 제거 시도
{
continue;
}
// (1). 섹션 파싱
if (data[i][0] == '[') // [ 로 시작하는 줄이면 섹션임
{
section = data[i][1]; // 섹션의 경우 [0],[1],[2] 중 [1]만 추출
Console.WriteLine("추출한 섹션값: " + section);
sections.Add(section); // 섹션 리스트에 추가
}
else
{
// (2). 키,값 파싱
//if (data[i][1] == '=' && data[i][0] != ' ') // 가운데에 = 이 있고, 첫번째가 공백이 아님
if (data[i][1] == '=') // 가운데에 = 이 있음
{
key = data[i][0]; // = 앞에가 키
keys.Add(key);
value = data[i][2]; // = 뒤에가 값
values.Add(value);
Console.WriteLine("추출한 키/값: " + key + '/' + value);
}
}
}
// char형 리스트를 string으로 변환
stringSection = string.Join("", sections);
stringKey = string.Join("", keys);
stringValue = string.Join("", values);
//tb_section.Text = stringSection;
// 굳이 ui에 각각 띄울 필요 없을 것 같음
// 이제 그냥 원하는 값으로 수정하면 될거같음
}
// [ 3. 수정하기 ] //////////////////////////////////////////////////////////////////////////
// 1.섹션을 입력한다.
// 2.키를 입력한다.
// 3.유효하면 밸류값이 나온다.
// 4.밸류값을 수정한다.
// 5.성공하면 성공했다고 메세지박스
// ~~~ 섹션 입력창에 값이 들어왔을 때 ~~~
private void tb_section_TextChanged(object sender, EventArgs e)
{
string userInputSection = tb_section.Text; // 유저가 검색한 섹션값 저장
string userInputKey = tb_key.Text;
string userInputValue = tb_value.Text;
verifySection(userInputSection); // 1. 섹션 검사
tb_key_TextChanged(sender, e); // 2. 키 검사
}
private void verifySection(string userInputSection) // Value 수정 전, 섹션&키 유효한지 검사하는 함수
{
if (stringSection.Contains(userInputSection) != true) // 섹션 거르기
{
MessageBox.Show("해당 섹션은 존재하지 않습니다.");
}
}
// ~~~ 키 입력창에 값이 들어왔을 때 ~~~
private void tb_key_TextChanged(object sender, EventArgs e)
{
tb_value.Clear();
string userInputSection = tb_section.Text;
string userInputKey = tb_key.Text;
Console.WriteLine($"key 입력 들어옴({tb_key.Text})");
verifyKey(userInputKey);
showValue(userInputSection, userInputKey);
}
private void verifyKey(string userInputKey)
{
if (stringKey.Contains(userInputKey) != true) // 키 거르기
{
MessageBox.Show("해당 Key는 존재하지 않습니다.");
}
}
// 유저가 입력한 섹션&key로 value 찾기
private void showValue(string userInputSection, string userInputKey)
{
// 존재한다면? 밸류값 띄우기
// A 섹션의 1번 Key의 값은 a 이다.
// 키의 인덱스와 같은 인덱스를 가진 밸류값을 찾으면 됨
// 아 근데 이거 어떤 섹션인지 어떻게 구분하지?
// 클래스를 만들어야하나?
// 일단 유저가 입력한 섹션의 인덱스번호에 +1,+2,+3을 해서 찾자
// ini 데이터를 한줄씩 담은 배열 = data
// 유저가 입력한 섹션이 data에서 몇번째 인덱스인지 찾자
Console.WriteLine($"showValue 들어왔나?");
int userSectionIndex = 0;
int userKeyIndex = 0;
char userValue = ' '; // 나중에 수정하려면 저장해둬야하니 변수 생성
// Value를 찾으려면 특정 인덱스를 찾아야하니 for문..
// [섹션의 인덱스 찾기]
for (int i = 0; i < data.Count+1; i++)
{
if (data[i].Contains(userInputSection)) // i번 데이터에 유저가 입력한 세션이 들어있는지?
{
userSectionIndex = i; // 인덱스번호 저장
Console.WriteLine($"섹션 인덱스: {userSectionIndex}");
break; // 저장 후 바로 탈출
}
}
Console.WriteLine($"유저 인풋 키: {userInputKey}");
// [키의 인덱스]
// 섹션 인덱스보다 1~3이 더 큰 범위에 유저가 입력한 key가 있는지?
for (int i = userSectionIndex+1; i < userSectionIndex+4; i++) // 섹션 다음으로 3쌍의 키/값이 있음
{
string mainKey = data[i][0].ToString(); // i번 데이터의 0번째 글자 = key
if (mainKey == userInputKey) // 섹션과 같은 인덱스의 key와 유저가 입력한 key가 같으면
{
userKeyIndex = i;
Console.WriteLine($"Key 인덱스: {userKeyIndex}");
userValue = data[i][2];
Console.WriteLine($"해당 Value값: {userValue}");
mainValue = userValue.ToString(); // string화
tb_value.Text = mainValue;
Console.WriteLine($"최종 Value: {mainValue}");
break;
}
break;
}
Console.WriteLine($"탈출했나?");
}
// Value 수정하기..
private void tb_value_TextChanged(object sender, EventArgs e)
{
modifyValue();
}
private void modifyValue() // Value 수정하는 함수
{
for (int i = 0; i < sections.Count; i++)
{
}
}
// 4. 저장하기 //////////////////////////////////////////////////////////////////////////
private void saveFile(string filePath, string allFile)
{
// 특정 요소만 저장하면되니까 for문
File.WriteAllText(filePath, allFile); // 지정 파일경로에 저장한 파일을 저장
}
}
}