data 변수의 자료형을 list<string> 으로 바꾼 버전

2025. 10. 29. 17:13·C#
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); // 지정 파일경로에 저장한 파일을 저장
        }


    }
}

'C#' 카테고리의 다른 글

객체지향(OOP) / 클래스  (0) 2025.10.31
break문 분석  (0) 2025.10.29
ini 프로그램 (노지피티)  (0) 2025.10.28
반복문 for VS for each 차이  (0) 2025.10.28
ini 프로그램 (gpt 사용)  (0) 2025.10.27
'C#' 카테고리의 다른 글
  • 객체지향(OOP) / 클래스
  • break문 분석
  • ini 프로그램 (노지피티)
  • 반복문 for VS for each 차이
joo_coding
joo_coding
2025.02.18~
  • joo_coding
    주코딩일지
    joo_coding
  • 전체
    오늘
    어제
    • 분류 전체보기 (219)
      • 일지 (19)
      • 계획표 (7)
      • 프로젝트 (6)
      • C언어 (35)
        • 연습장 (12)
      • C++ (3)
      • C# (34)
      • Python (28)
        • 연습장 (11)
      • TCP IP (4)
      • DB (2)
      • ubuntu (1)
      • Git (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    c언어 #vscode #gcc #윈도우 #c언어윈도우 #gcc윈도우 #vscode윈도우 #c #c++
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
joo_coding
data 변수의 자료형을 list<string> 으로 바꾼 버전
상단으로

티스토리툴바