Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.83/18: Рейтинг темы: голосов - 18, средняя оценка - 4.83
 Аватар для Smolko
0 / 0 / 0
Регистрация: 23.07.2019
Сообщений: 9
.NET 4.x

Имя ini файла в корневой директории

23.07.2019, 16:49. Показов 4055. Ответов 21

Студворк — интернет-сервис помощи студентам
Приветствую.

Для программы конвертирования текстового файла использую ini-файл, в котором пользователь может задать пути и имена входного и выходного текстовых файлов. Предполагается, что ini-файл будет лежать рядом с исполняемым файлом. Для работы с ini-файлом использую класс:

C#
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
    public class INIManager
    {
        //Конструктор, принимающий путь к INI-файлу
        public INIManager(string aPath)
        {
            path = aPath;
        }
 
        //Конструктор без аргументов (путь к INI-файлу нужно будет задать отдельно)
        public INIManager() : this("") { }
 
        //Возвращает значение из INI-файла (по указанным секции и ключу) 
        public string GetPrivateString(string aSection, string aKey)
        {
            //Для получения значения
            StringBuilder buffer = new StringBuilder(SIZE);
 
            //Получить значение в buffer
            GetPrivateString(aSection, aKey, null, buffer, SIZE, path);
 
            //Вернуть полученное значение
            return buffer.ToString();
        }
 
        //Пишет значение в INI-файл (по указанным секции и ключу) 
        public void WritePrivateString(string aSection, string aKey, string aValue)
        {
            //Записать значение в INI-файл
            WritePrivateString(aSection, aKey, aValue, path);
        }
 
        //Возвращает или устанавливает путь к INI файлу
        public string Path { get { return path; } set { path = value; } }
 
        //Поля класса
        private const int SIZE = 1024; //Максимальный размер (для чтения значения из файла)
        private string path = null; //Для хранения пути к INI-файлу
 
        //Импорт функции GetPrivateProfileString (для чтения значений) из библиотеки kernel32.dll
        [DllImport("kernel32.dll", EntryPoint = "GetPrivateProfileString")]
        private static extern int GetPrivateString(string section, string key, string def, StringBuilder buffer, int size, string path);
 
        //Импорт функции WritePrivateProfileString (для записи значений) из библиотеки kernel32.dll
        [DllImport("kernel32.dll", EntryPoint = "WritePrivateProfileString")]
        private static extern int WritePrivateString(string section, string key, string str, string path);
    }
Далее, в коде если использую путь к ini-файлу таким образом:

C#
1
INIManager manager = new INIManager("Config.ini");
Файл программой не обнаруживается.

Работает только если указать весь путь, в данном случае это:
C#
1
INIManager manager = new INIManager(@"C:\Users\Alex Smolko\source\repos\Conv_Digispot_to_PG-3\Conv_Digispot_to_PG-3\bin\Debug\Config.ini");
Пробовал еще сделать так:

C#
1
2
string path = Application.StartupPath + "\\Config.ini";
INIManager manager = new INIManager(path);
Получаю ошибку CS0117 "MediaTypeNames.Application" не содержит определение для "StartupPath". Conv_Digispot_to_PG C:\Users\Alex Smolko\source\repos\Conv_Digispot_to_PG-3\Conv_Digispot_to_PG-3\Program.cs

Как же сделать так, чтобы ini-шка искалась в том же каталоге, где лежит исполняемый файл? Поможите.
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
23.07.2019, 16:49
Ответы с готовыми решениями:

Включение файла из корневой директории
Всем привет. Вопрос простой: подключаю файл: require_once("db_login.php");//файл с регистрационной информацией но если файл...

Создание ini файла в директории программы
Подскажите как создать ini файл в директории программы!!! (Возможно тема заезжаная, но не нашел) Сам ini создаю так! TIniFile...

Как вытащить из ini-файла имя файла?
Кто знает, помогите плз. В макросе под Excel надо вытащить из ini-файла имя файла, чтобы потом его открыть в книгу Excel. Подскажите...

21
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16140 / 11264 / 2888
Регистрация: 21.04.2018
Сообщений: 33,111
Записей в блоге: 2
23.07.2019, 18:52
Цитата Сообщение от Smolko Посмотреть сообщение
Как же сделать так, чтобы ini-шка искалась в том же каталоге, где лежит исполняемый файл?
C#
1
string path =/* Application.StartupPath + "\\*/"Config.ini";
Добавлено через 2 минуты
Прочитайте Узнать путь к исполняемому файлу приложения
0
 Аватар для Smolko
0 / 0 / 0
Регистрация: 23.07.2019
Сообщений: 9
23.07.2019, 19:10  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
C#
1
string path =/* Application.StartupPath + "\\*/"Config.ini";
Добавлено через 2 минуты
Прочитайте Узнать путь к исполняемому файлу приложения
Получаю ошибку
Ошибка CS0117 "MediaTypeNames.Application" не содержит определение для "StartupPath". Digispot_to_PG

И само StartupPath подчеркнуто.
Миниатюры
Имя ini файла в корневой директории  
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16140 / 11264 / 2888
Регистрация: 21.04.2018
Сообщений: 33,111
Записей в блоге: 2
23.07.2019, 19:20
Цитата Сообщение от Smolko Посмотреть сообщение
И само StartupPath подчеркнуто.
Я же показал Вам! Просто укажите имя файла без пути и всё!

И прочитайте тему по моей ссылке.
1
 Аватар для XIST
1961 / 1071 / 148
Регистрация: 01.10.2009
Сообщений: 3,603
Записей в блоге: 1
23.07.2019, 19:50
Лучший ответ Сообщение было отмечено Smolko как решение

Решение

Smolko,
C#
1
string path = AppDomain.CurrentDomain.BaseDirectory + "Config.ini";
1
 Аватар для Smolko
0 / 0 / 0
Регистрация: 23.07.2019
Сообщений: 9
23.07.2019, 20:44  [ТС]
Элд Хасп, Огромное спасибо за помощь, почему-то прямое указание имени файла без пути не работает в методе INIManage (сам класс INIManager я полностью процитировал в изначальном сообщении).

Но сработал метод от XIST из 5-го коммента.

Добавлено через 1 минуту
XIST, да, это сработало! Спасибо. Но я видел где-то, что могут быть исключения, в том случае, если домен будет указан вручную (не дефолтно), но моему (первому, кстати) приложению это, кажется, не грозит.
0
 Аватар для XIST
1961 / 1071 / 148
Регистрация: 01.10.2009
Сообщений: 3,603
Записей в блоге: 1
23.07.2019, 21:04
Цитата Сообщение от Smolko Посмотреть сообщение
Но я видел где-то, что могут быть исключения, в том случае, если домен будет указан вручную (не дефолтно)
тут не скажу, не сталкивался, но тогда MSDN предлагает такой вариант консольный
C#
1
System.IO.Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]) + $"\\Config.ini";
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16140 / 11264 / 2888
Регистрация: 21.04.2018
Сообщений: 33,111
Записей в блоге: 2
23.07.2019, 21:06
Цитата Сообщение от Smolko Посмотреть сообщение
Но я видел где-то, что могут быть исключения
  1. Application.StartupPath
  2. System.IO.Path.GetDirectoryName(System.R eflection.Assembly.GetExecutingAssembly( ).Location)
  3. AppDomain.CurrentDomain.BaseDirectory
  4. System.IO.Directory.GetCurrentDirectory( )
  5. Environment.CurrentDirectory
  6. System.IO.Path.GetDirectoryName(System.R eflection.Assembly.GetExecutingAssembly( ).GetName().CodeBase)
  7. System.IO.Path.GetDirectory(Application. ExecutablePath)

Добавлено через 1 минуту
Какой тип проекта приложения у вас?
0
 Аватар для Smolko
0 / 0 / 0
Регистрация: 23.07.2019
Сообщений: 9
24.07.2019, 08:56  [ТС]
Элд Хасп, консольное приложение.

Добавлено через 8 минут
Элд Хасп wrote:
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Какой тип проекта приложения у вас?
Консольное приложение. Но я повторюсь, что уже работает вот этот способ:

C#
1
string path = AppDomain.CurrentDomain.BaseDirectory + "Config.ini";
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16140 / 11264 / 2888
Регистрация: 21.04.2018
Сообщений: 33,111
Записей в блоге: 2
24.07.2019, 09:32
Цитата Сообщение от Smolko Посмотреть сообщение
Но я повторюсь, что уже работает вот этот способ:
Это я понял.
Хочу разобраться почему не работает просто без пути.
По идее так тоже должно работать.
0
 Аватар для Smolko
0 / 0 / 0
Регистрация: 23.07.2019
Сообщений: 9
24.07.2019, 09:40  [ТС]
Элд Хасп, может быть дело в самом классе? Там такой код

C#
1
2
3
4
5
//Конструктор, принимающий путь к INI-файлу
        public INIManager(string aPath)
        {
            path = aPath;
        }
Добавлено через 1 минуту
А может быть дело в том, что я не умею использовать классы. В отдельном файле мне не получилось его подключить, так что я вставил его прямо в код основной программы.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16140 / 11264 / 2888
Регистрация: 21.04.2018
Сообщений: 33,111
Записей в блоге: 2
24.07.2019, 10:10
Цитата Сообщение от Smolko Посмотреть сообщение
может быть дело в самом классе? Там такой код...
Нет, дело не в этом.
Это может иметь значение только если в решении несколько сборок и они находятся в разных папках.
Поэтому я и поинтересовался типом решения.

Для одной сборки должно работать просто по имени без пути. Вы же прямо из VS запускаете?
Могут быть нюансы, если запускать exe не из папки приложения. Но у вас, как я понял, не такой сценарий.

Если проект небольшой - скиньте сюда его архив. Посмотрю в чём дело.

P.S. Mаленький совет. У вас есть свойство Path. Переменная path используется только для хранения значения этого свойства. Не надо её использовать где-либо за пределами сеттера и геттера этого свойства.
C#
1
2
        //Конструктор, принимающий путь к INI-файлу
        public INIManager(string aPath) => Path = aPath;
Так же излишним выглядит сам этот конструктор с Path. Если это свойство можно менять после создания экземпляра, то зачем этот конструктор? Можно создавать так
C#
1
INIManager manager = new INIManager() {Path = path};
Если же это свойство должно задаваться единожды, то надо из свойства убрать сеттер и использовать автосвойство
C#
1
2
        //Возвращает путь к INI файлу
        public string Path { get ; }
0
 Аватар для Smolko
0 / 0 / 0
Регистрация: 23.07.2019
Сообщений: 9
24.07.2019, 10:41  [ТС]
Элд Хасп, Я только-только начал учить программирование и я половину из того, что вы мне сказали - не понимаю даже. А этот проектик, конвертор текстовых файлов, просто очень нужен был по работе, поэтому я сильно вперед забежал, чтобы сделать его. Полагаю, там жесть полная. Но работает. А инишку я добавил, так как у клиента пути могут не совпадать с расположением исполняемого файла, поэтому я предусмотрел возможность через ини-файл указывать пути. Но возникла проблема с путём к самому Ини-файлу

Класс для работы с ини файлами, как я это понимаю на своем теперяшном уровне, это не готовый класс от Микрософт (читал, что Микрософт не рекомендует работать с ини, а лучше с XML), а кем-то написанный, поэтому он и содержит разные методы, мне пригодился один, в другой раз пригодится другой и т.д. Универсальный класс. Поэтому я его и не трогал, не влазил в него. А просто использовал.

В общем я не хочу никого ничем напрягать, вот лет через пять я подучусь и тогда... Но проект, конечно, прилагаю. Тоже интересно знать, почему без пути не работает.
Вложения
Тип файла: 7z Digispot_to_PG.7z (140.6 Кб, 2 просмотров)
0
Эксперт .NET
 Аватар для Rius
13164 / 7724 / 1679
Регистрация: 25.05.2015
Сообщений: 23,528
Записей в блоге: 14
24.07.2019, 10:57
Без пути это так чтоль
Цитата Сообщение от Smolko Посмотреть сообщение
new INIManager("Config.ini");
?
Потому что он ищет в каталоге C:\Windows .

Добавлено через 4 минуты
GetPrivateProfileString function
Code
1
2
3
4
5
6
7
8
DWORD GetPrivateProfileString(
  LPCTSTR lpAppName,
  LPCTSTR lpKeyName,
  LPCTSTR lpDefault,
  LPTSTR  lpReturnedString,
  DWORD   nSize,
  LPCTSTR lpFileName
);
lpFileName - The name of the initialization file. If this parameter does not contain a full path to the file, the system searches for the file in the Windows directory.

И вообще, если не хотите проблем на пустом месте, всегда указывайте полные пути: Относительное зло
2
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16140 / 11264 / 2888
Регистрация: 21.04.2018
Сообщений: 33,111
Записей в блоге: 2
24.07.2019, 14:05
Цитата Сообщение от Smolko Посмотреть сообщение
Тоже интересно знать, почему без пути не работает.
Разобрался.
Это моя невнимательность! Не прочитал до конца код класса INIManager из начала темы.

Имя файла передаётся в методы GetPrivateString и WritePrivateString. Они находятся в сборке kernel32.dll и относительный путь они будут вычислять относительно места локализации своей сборки.
То есть, как и писал Rius, относительно C:\Windows
0
 Аватар для Smolko
0 / 0 / 0
Регистрация: 23.07.2019
Сообщений: 9
24.07.2019, 14:08  [ТС]
Элд Хасп, круто быть умным, должно быть. Но вот сейчас я хотя бы понимаю, о чем вы написали.

Еще раз спасибо.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16140 / 11264 / 2888
Регистрация: 21.04.2018
Сообщений: 33,111
Записей в блоге: 2
24.07.2019, 14:53
Smolko, немного изменил ваш класс и перенёс его в отдельный проект, как вы, по-моему, и хотели. Этот отдельный проект (или его сборку) можно подключать к любому другому решению.
И обратите внимание как должны выглядеть комментарии. Такие комментарии будут всплывать при наведении.
C#
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
    /// <summary>Класс для чтения/записи INI-файлов</summary>
    public class INIManager
    {
        /// <summary>Конструктор, принимающий путь к INI-файлу</summary>
        /// <param name="path">Имя INI файла полное или относительное</param>
        public INIManager(string path) => FileName = path;
 
        /// <summary>Возвращает значение из INI-файла</summary>
        /// <param name="section">Секция</param>
        /// <param name="key">Ключ</param>
        /// <returns>Значение</returns>
        public string GetPrivateString(string section, string key)
        {
            //Для получения значения
            StringBuilder buffer = new StringBuilder(SIZE);
 
            //Получить значение в buffer
            GetPrivateString(section, key, null, buffer, SIZE, FullPath);
 
            //Вернуть полученное значение
            return buffer.ToString();
        }
 
        /// <summary>Пишет значение в INI-файл</summary>
        /// <param name="section">Секция</param>
        /// <param name="key">Ключ</param>
        /// <param name="value">Значение</param>
        public void WritePrivateString(string section, string key, string value)
        {
            //Записать значение в INI-файл
            WritePrivateString(section, key, value, FullPath);
        }
 
        /// <summary>Возвращает заданное имя INI файла</summary>
        public string FileName { get; }
        /// <summary>Возвращает полное имя INI файла с абсолютным путём</summary>
        public string FullPath => Path.GetFullPath(FileName);
 
        /// <summary>Максимальный размер (для чтения значения из файла)</summary>
        private const int SIZE = 1024;
        /*private string path = null;*/ //Для хранения пути к INI-файлу
 
        /// <summary>Импорт функции GetPrivateProfileString (для чтения значений) из библиотеки kernel32.dll</summary>
        /// <param name="section">Секция</param>
        /// <param name="key">Ключ</param>
        /// <param name="def">Значение по умолчанию</param>
        /// <param name="buffer">Полученное значение</param>
        /// <param name="size">Максимальный размер</param>
        /// <param name="path">Полный путь к INI файлу</param>
        /// <returns></returns>
        [DllImport("kernel32.dll", EntryPoint = "GetPrivateProfileString")]
        private static extern int GetPrivateString(string section, string key, string def, StringBuilder buffer, int size, string path);
 
        /// <summary>Импорт функции WritePrivateProfileString (для записи значений) из библиотеки kernel32.dll</summary>
        /// <param name="section">Секция</param>
        /// <param name="key">Ключ</param>
        /// <param name="str">Значение</param>
        /// <param name="path">Полный путь к INI файлу</param>
        /// <returns></returns>
        [DllImport("kernel32.dll", EntryPoint = "WritePrivateProfileString")]
        private static extern int WritePrivateString(string section, string key, string str, string path);
    }
Использование
C#
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
    class Program
    {
 
        [STAThread]
        static void Main(string[] args)
        {
            string line;
            try
            {
                //Создание объекта для работы с ini-файлом
                string inipath = "Config.ini";
                INIManager manager = new INIManager(inipath);
 
                //Получаем значение из секции main по ключу inputfile
                string inputfile = manager.GetPrivateString("main", "inputfile");
 
                //Получаем значение из секции main по ключу outputfile
                string outputfile = manager.GetPrivateString("main", "outputfile");
 
                // Организовываем потоки чтения из входного файла и записи в конечный файл.
                using (StreamReader file =
                         new System.IO.StreamReader(inputfile))
                using (StreamWriter file2 =
                        new StreamWriter(outputfile, false))
                {
                    //Начинаем читать с первой строки текста
                    line = file.ReadLine();
                    //Продолжаем читать пока не достигнем конца файла.
                    while (line != null)
                    {
 
                        //Убираем лишний набор символов в строке ("ELEM_INFO".")
                        string pattern = @"""ELEM_INFO"".""";
                        string target = "";
                        Regex regex = new Regex(pattern);
                        line = regex.Replace(line, target);
 
                        //Убираем кавычки точка кавычки в строке, заменяем табуляцией.
                        pattern = @""".""";
                        target = "\t";
                        regex = new Regex(pattern);
                        line = regex.Replace(line, target);
 
                        //Убираем кавычки в конце строки
                        pattern = @"""$";
                        target = "";
                        regex = new Regex(pattern);
                        line = regex.Replace(line, target);
 
                        //Пишем строку в конечный файл
                        file2.WriteLine(line);
                        //Читаем следующую строку файла
                        line = file.ReadLine();
                    }
 
                    ////закрываем файлы
                    //file.Close();
                    //file2.Close();
                }
                //System.Console.ReadLine(); //строчка предотвращающая закрытие консольного окна, для отладки
            }
 
            catch (Exception e)
            {
                System.Console.WriteLine("Exception: " + e.Message);
            }
            finally
            {
                Console.WriteLine("Executing finally block.");
            }
        }
    }
Архив с изменениями
Вложения
Тип файла: 7z Digispot_to_PG v1.7z (196.3 Кб, 5 просмотров)
0
 Аватар для Smolko
0 / 0 / 0
Регистрация: 23.07.2019
Сообщений: 9
24.07.2019, 14:57  [ТС]
Элд Хасп, это слишком великодушно с вашей стороны. Как только я смогу, я всё изучу и, возможно, задам вопросы, если не пойму что-либо.
Спасибо;
0
Эксперт .NET
 Аватар для Rius
13164 / 7724 / 1679
Регистрация: 25.05.2015
Сообщений: 23,528
Записей в блоге: 14
24.07.2019, 15:23
И ещё:
Note This function is provided only for compatibility with 16-bit Windows-based applications. Applications should store initialization information in the registry.
Вы полагаетесь на давно устаревшую функцию.
0
 Аватар для Smolko
0 / 0 / 0
Регистрация: 23.07.2019
Сообщений: 9
25.07.2019, 10:42  [ТС]
Элд Хасп, Всё рассмотрел. С путем до ИНИ - так просто? С ума сойти Про класс (в отдельной dll) - тоже теперь понятно. Теперь можно к другим проектам если что - подключать.

Очень много спасибо.

Rius, Простите, о какой именно функции речь?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
25.07.2019, 10:42
Помогаю со студенческими работами здесь

Получить имя директории текущего файла
Есть способ быстрее этого ?: $this= explode(DIRECTORY_SEPARATOR, __DIR__); $this = end($modname);

Получить имя первого файла в директории?
В директории имеется n-количество вложенных директорий, в каждой директории также имеется n-количество файлов. Требуется получить из каждой...

Установка корневой директории в QFileSystemModel
Столкнулся с непонятной для меня проблемой. При попытке установить коневую директорию для модели (QFileSystemModel): ...

Ошибка нахождения корневой директории
package semestralka_baza_mangi; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.IOException; ...

Список файлов в корневой директории
Пустой список /storage/sdcard0 File root; File curFolder; ... root = new...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Сумматор с применением элементов трёх состояний.
Hrethgir 26.03.2026
Тут. https:/ / fips. ru/ EGD/ ab3c85c8-836d-4866-871b-c2f0c5d77fbc Первый документ красиво выглядит, но без схемы. Это конечно не даёт никаких плюсов автору, но тем не менее. . . всё может быть. . .
Автозаполнение реквизитов при создании документа
Maks 26.03.2026
Код из решения ниже размещается в модуле объекта документа, в процедуре "ПриСозданииНаСервере". Алгоритм проверки заполнения реализован для исключения перезаписи значения реквизита, которое может. . .
Команды "Заполнить" и "Очистить" на форме документа
Maks 26.03.2026
1. Команда формы "ЗаполнитьЗапчасти". На примере нетипового документа разработанного в конфигурации КА2. В качестве источника данных указан регистр накопления, в который записываются данные о. . .
Кому нужен AOT?
DevAlt 26.03.2026
Решил сделать простой ланчер Написал заготовку: dotnet new console --aot -o UrlHandler var items = args. Split(":"); var tag = items; var id = items; var executable = args;. . .
Отправка уведомления на почту при изменении наименования справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере изменения наименования типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной. . .
модель ЗдравоСохранения 5. Меньше увольнений- больше дохода!
anaschu 24.03.2026
Теперь система здравосохранения уменьшает количество увольнений. 9TO2GP2bpX4 a42b81fb172ffc12ca589c7898261ccb/ https:/ / rutube. ru/ video/ a42b81fb172ffc12ca589c7898261ccb/ Слева синяя линия -. . .
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
SDL3 для Desktop (MinGW): Вывод текста со шрифтом TTF с помощью библиотеки SDL3_ttf на Си и C++
8Observer8 24.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-text-sdl3-c. zip finish-text-sdl3-cpp. zip
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru