Перейти к содержимому

Как подключить текстовый файл к проекту c

  • автор:

Использование Visual C# для чтения и записи в текстовый файл

В этой статье описано, как выполнить чтение и запись в текстовый файл с помощью Visual C#.

Оригинальная версия продукта: Visual Studio
Оригинальный номер базы знаний: 816149

Сводка

В разделе Чтение текстового файла этой статьи описывается, как использовать класс StreamReader для чтения текстового файла. В разделах Запись в текстовый файл (пример 1) и Запись в текстовый файл (пример 2) описывается, как использовать класс StreamWriter для записи текста в файл.

Чтение текстового файла

В следующем коде используется класс StreamReader для открытия, чтения и закрытия текстового файла. Можно передать путь к текстовому файлу в конструктор StreamReader для автоматического открытия файла. Метод ReadLine считывает каждую строку текста и перемещает указатель файла на следующую строку по мере чтения. Если метод ReadLine достигает конца файла, он возвращает пустую ссылку. Дополнительные сведения см. в разделе Класс StreamReader.

  1. Создайте пример текстового файла в Блокноте. Выполните приведенные ниже действия.
    1. Вставьте текст hello world в Блокнот.
    2. Сохраните файл как Sample.txt.
    using System.IO; 
    String line; try < //Pass the file path and file name to the StreamReader constructor StreamReader sr = new StreamReader("C:\\Sample.txt"); //Read the first line of text line = sr.ReadLine(); //Continue to read until you reach end of file while (line != null) < //write the line to console window Console.WriteLine(line); //Read the next line line = sr.ReadLine(); >//close the file sr.Close(); Console.ReadLine(); > catch(Exception e) < Console.WriteLine("Exception: " + e.Message); >finally
    Hello world 

    Запись в текстовый файл (пример 1)

    В следующем коде используется класс StreamWriter для открытия, записи и закрытия текстового файла. Аналогично тому, как используется класс StreamReader , можно передать путь к текстовому файлу в конструктор StreamWriter для автоматического открытия файла. Метод WriteLine записывает всю текстовую строку в текстовый файл.

    1. Запустите Visual Studio.
    2. В меню Файл выберите пункт Создать, а затем выберите Проект.
    3. Выберите Проекты Visual C# в разделе Типы проектов, а затем выберите Консольное приложение в разделе Шаблоны.
    4. Добавьте следующий код в начало файла Class1.cs:

    using System.IO; 
    try < //Pass the filepath and filename to the StreamWriter Constructor StreamWriter sw = new StreamWriter("C:\\Test.txt"); //Write a line of text sw.WriteLine("Hello World!!"); //Write a second line of text sw.WriteLine("From the StreamWriter class"); //Close the file sw.Close(); >catch(Exception e) < Console.WriteLine("Exception: " + e.Message); >finally
    Hello World!! From the StreamWriter class 

    Запись в текстовый файл (пример 2)

    В следующем коде используется класс StreamWriter для открытия, записи и закрытия текстового файла. В отличие от предыдущего примера, этот код передает в конструктор два дополнительных параметра. Первый параметр — путь к файлу и имя файла. Второй параметр, true , указывает, что файл открыт в режиме добавления. Если вы задаете false для второго параметра, содержимое файла перезаписывается при каждом запуске кода. Третий параметр задает Unicode , чтобы кодирование файла в StreamWriter выполнялось в формате Юникода. Можно также указать следующие методы кодирования для третьего параметра:

    Метод Write аналогичен методу WriteLine , за исключением того, что метод Write не вставляет автоматически сочетание символов возврата каретки или перевода строки (CR/LF). Это полезно, когда нужно одновременно записывать по одному символу.

    1. Запустите Visual Studio.
    2. В меню Файл выберите пункт Создать и затем пункт Проект.
    3. Нажмите Проекты Visual C# в разделе Типы проектов, а затем нажмите Консольное приложение в разделе Шаблоны.
    4. Добавьте следующий код в начало файла Class1.cs:

    using System.IO; using System.Text; 
    Int64 x; try < //Open the File StreamWriter sw = new StreamWriter("C:\\Test1.txt", true, Encoding.ASCII); //Write out the numbers 1 to 10 on the same line. for(x=0; x < 10; x++) < sw.Write(x); >//close the file sw.Close(); > catch(Exception e) < Console.WriteLine("Exception: " + e.Message); >finally

    Полный код сборки для чтения текстового файла

    //Read a Text File using System; using System.IO; namespace readwriteapp < class Class1 < [STAThread] static void Main(string[] args) < String line; try < //Pass the file path and file name to the StreamReader constructor StreamReader sr = new StreamReader("C:\\Sample.txt"); //Read the first line of text line = sr.ReadLine(); //Continue to read until you reach end of file while (line != null) < //write the line to console window Console.WriteLine(line); //Read the next line line = sr.ReadLine(); >//close the file sr.Close(); Console.ReadLine(); > catch(Exception e) < Console.WriteLine("Exception: " + e.Message); >finally < Console.WriteLine("Executing finally block."); >> > > 

    Полный код сборки для записи в текстовый файл (версия 1)

    //Write a text file - Version-1 using System; using System.IO; namespace readwriteapp < class Class1 < [STAThread] static void Main(string[] args) < try < //Pass the filepath and filename to the StreamWriter Constructor StreamWriter sw = new StreamWriter("C:\\Test.txt"); //Write a line of text sw.WriteLine("Hello World!!"); //Write a second line of text sw.WriteLine("From the StreamWriter class"); //Close the file sw.Close(); >catch(Exception e) < Console.WriteLine("Exception: " + e.Message); >finally < Console.WriteLine("Executing finally block."); >> > > 

    Полный код сборки для записи в текстовый файл (версия 2)

    //Write a text file - Version 2 using System; using System.IO; using System.Text; namespace readwriteapp < class Class1 < [STAThread] static void Main(string[] args) < Int64 x; try < //Open the File StreamWriter sw = new StreamWriter("C:\\Test1.txt", true, Encoding.ASCII); //Writeout the numbers 1 to 10 on the same line. for(x=0; x < 10; x++) < sw.Write(x); >//close the file sw.Close(); > catch(Exception e) < Console.WriteLine("Exception: " + e.Message); >finally < Console.WriteLine("Executing finally block."); >> > > 

    Устранение неполадок

    Перенос кода в блок try-catch-finally для обработки ошибок и исключений является хорошей практикой программирования, когда речь заходит о выполнении любых операций с файлом. В частности, может потребоваться освободить дескрипторы файла в окончательном блоке, чтобы файл не был заблокирован на неопределенный срок. Некоторые возможные ошибки включают файл, который не существует, или файл, который уже используется.

    Обратная связь

    Были ли сведения на этой странице полезными?

    C++. Работа с текстовыми файлами

    Файлы позволяют пользователю считывать большие объемы данных непосредственно с диска, не вводя их с клавиатуры. Существуют два основных типа файлов: текстовые и двоичные.

    Текстовыми называются файлы, состоящие из любых символов. Они организуются по строкам, каждая из которых заканчивается символом «конца строки». Конец самого файла обозначается символом «конца файла». При записи информации в текстовый файл, просмотреть который можно с помощью любого текстового редактора, все данные преобразуются к символьному типу и хранятся в символьном виде.

    В двоичных файлах информация считывается и записывается в виде блоков определенного размера, в которых могут храниться данные любого вида и структуры.

    Для работы с файлами используются специальные типы данных, называемые потоками. Поток ifstream служит для работы с файлами в режиме чтения, а ofstream в режиме записи. Для работы с файлами в режиме как записи, так и чтения служит поток fstream.

    В программах на C++ при работе с текстовыми файлами необходимо подключать библиотеки iostream и fstream.

    Для того чтобы записывать данные в текстовый файл, необходимо:

    1. описать переменную типа ofstream.
    2. открыть файл с помощью функции open.
    3. вывести информацию в файл.
    4. обязательно закрыть файл.

    Для считывания данных из текстового файла, необходимо:

    1. описать переменную типа ifstream.
    2. открыть файл с помощью функции open.
    3. считать информацию из файла, при считывании каждой порции данных необходимо проверять, достигнут ли конец файла.
    4. закрыть файл.

    Запись информации в текстовый файл

    Как было сказано ранее, для того чтобы начать работать с текстовым файлом, необходимо описать переменную типа ofstream. Например, так:

    ofstream F;

    Будет создана переменная F для записи информации в файл. На следующим этапе файл необходимо открыть для записи. В общем случае оператор открытия потока будет иметь вид:

    F.open(«file», mode);

    Здесь F — переменная, описанная как ofstream, file — полное имя файла на диске, mode — режим работы с открываемым файлом. Обратите внимание на то, что при указании полного имени файла нужно ставить двойной слеш. Для обращения, например к файлу accounts.txt, находящемуся в папке sites на диске D, в программе необходимо указать: D:\\sites\\accounts.txt.

    Файл может быть открыт в одном из следующих режимов:

    • ios::in — открыть файл в режиме чтения данных; режим является режимом по умолчанию для потоков ifstream;
    • ios::out — открыть файл в режиме записи данных (при этом информация о существующем файле уничтожается); режим является режимом по умолчанию для потоков ofstream;
    • ios::app — открыть файл в режиме записи данных в конец файла;
    • ios::ate — передвинуться в конец уже открытого файла;
    • ios::trunc — очистить файл, это же происходит в режиме ios::out;
    • ios::nocreate — не выполнять операцию открытия файла, если он не существует;
    • ios::noreplace — не открывать существующий файл.

    Параметр mode может отсутствовать, в этом случае файл открывается в режиме по умолчанию для данного потока.

    После удачного открытия файла (в любом режиме) в переменной F будет храниться true, в противном случае false. Это позволит проверить корректность операции открытия файла.

    Открыть файл (в качестве примера возьмем файл D:\\sites\\accounts.txt) в режиме записи можно одним из следующих способов:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    //первый способ
    ofstream F ;
    F. open ( «D: \\ sites\\accounts.txt» , ios :: out ) ;
    //второй способ, режим ios::out является режимом по умолчанию
    //для потока ofstream
    ofstream F ;
    F. open ( «D: \\ game \\ noobs.txt» ) ;
    //третий способ объединяет описание переменной и типа поток
    //и открытие файла в одном операторе
    ofstream F ( «D: \\ game \\ noobs.txt» , ios :: out ) ;

    После открытия файла в режиме записи будет создан пустой файл, в который можно будет записывать информацию.

    Если вы хотите открыть существующий файл в режиме дозаписи, то в качестве режима следует использовать значение ios::app.

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

    Например, для записи в поток F переменной a, оператор вывода будет иметь вид:

    Для последовательного вывода в поток G переменных b, c, d оператор вывода станет таким:

    Закрытие потока осуществляется с помощью оператора:

    F.close();

    В качестве примера рассмотрим следующую задачу.

    Задача 1

    Создать текстовый файл D:\\sites\\accounts.txt и записать в него n вещественных чисел.

    Решение

    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

    #include «stdafx.h»
    #include
    #include
    #include
    using namespace std ;
    int main ( )
    <
    setlocale ( LC_ALL, «RUS» ) ;
    int i, n ;
    double a ;
    //описывает поток для записи данных в файл
    ofstream f ;
    //открываем файл в режиме записи,
    //режим ios::out устанавливается по умолчанию
    f. open ( «D: \\ sites \\ accounts.txt» , ios :: out ) ;
    //вводим количество вещественных чисел
    cout > n ;
    //цикл для ввода вещественных чисел
    //и записи их в файл
    for ( i = 0 ; i < n ; i ++ )
    <
    cout //ввод числа
    cin >> a ;
    f >
    //закрытие потока
    f. close ( ) ;
    system ( «pause» ) ;
    return 0 ;
    >

    Чтение информации из текстового файла

    Для того чтобы прочитать информацию из текстового файла, необходимо описать переменную типа ifstream. После этого нужно открыть файл для чтения с помощью оператора open. Если переменную назвать F, то первые два оператора будут такими:

    ifstream F ;
    F. open ( «D: \\ sites \\ accounts.txt» , ios :: in ) ;

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

    Например, для чтения данных из потока F в переменную a, оператор ввода будет выглядеть так:

    F>>a;

    Два числа в текстовом редакторе считаются разделенными, если между ними есть хотя бы один из символов: пробел, табуляция, символ конца строки. Хорошо, когда программисту заранее известно, сколько и какие значения хранятся в текстовом файле. Однако часто известен лишь тип значений, хранящихся в файле, при этом их количество может быть различным. Для решения данной проблемы необходимо считывать значения из файла поочередно, а перед каждым считыванием проверять, достигнут ли конец файла. А поможет сделать это функция F.eof(). Здесь F — имя потока функция возвращает логическое значение: true или false, в зависимости от того достигнут ли конец файла.

    Следовательно, цикл для чтения содержимого всего файла можно записать так:

    1
    2
    3
    4
    5
    6
    7
    8
    9

    //организуем для чтения значений из файла, выполнение
    //цикла прервется, когда достигнем конец файла,
    //в этом случае F.eof() вернет истину
    while ( ! F. eof ( ) )
    <
    //чтение очередного значения из потока F в переменную a
    F >> a ;
    //далее идет обработка значения переменной a
    >

    Для лучшего усвоения материала рассмотрим задачу.

    Задача 2

    В текстовом файле D:\\game\\accounts.txt хранятся вещественные числа, вывести их на экран и вычислить их количество.

    Решение

    #include «stdafx.h»
    #include
    #include
    #include
    #include
    using namespace std ;
    int main ( )
    <
    setlocale ( LC_ALL, «RUS» ) ;
    int n = 0 ;
    float a ;
    fstream F ;
    //открываем файл в режиме чтения
    F. open ( «D: \\ sites \\ accounts.txt» ) ;
    //если открытие файла прошло корректно, то
    if ( F )
    <
    //цикл для чтения значений из файла; выполнение цикла прервется,
    //когда достигнем конца файла, в этом случае F.eof() вернет истину.
    while ( ! F. eof ( ) )
    <
    //чтение очередного значения из потока F в переменную a
    F >> a ;
    //вывод значения переменной a на экран
    cout //увеличение количества считанных чисел
    n ++ ;
    >
    //закрытие потока
    F. close ( ) ;
    //вовод на экран количества считанных чисел
    cout >
    //если открытие файла прошло некорректно, то вывод
    //сообщения об отсутствии такого файла
    else cout system ( «pause» ) ;
    return 0 ;
    >

    На этом относительно объемный урок по текстовым файлам закончен. В следующей статье будут рассмотрены методы манипуляции, при помощи которых в C++ обрабатываются двоичные файлы.

    Visual Studio. Как добавить .txt файл?

    Задача:
    Есть проект, в него надо добавить текстовый файл(Readme.txt) и, соответственно, заполнить его. Что-то не могу догнать, можно ли это сделать средствами такого распиаренного Visual Studio(до этого сидел на Rider, там это делается в 2 клика — ПКМ->добавить файл).

    • Вопрос задан более трёх лет назад
    • 9752 просмотра

    Комментировать

    Решения вопроса 1

    Rem_u

    Эх, как же хочется худенькую, бледную, не очень.

    ПКМ пр проекту — добавить — создать элемент — текстовый файл. он будет лежать в C:\Users\User\source\repos\WindowsFormsApp1\WindowsFormsApp1 где и папка bin (это всё по стандарту) полный путь, содержание, настройка отношения файла к процессам сборки и внедрения, имя файла и ещё 2 пункта можно изменить в самом Visual Studio.

    Ответ написан более трёх лет назад

    Комментировать

    Нравится Комментировать

    Как подключить содержимое любых файлов для использования в коде C / C++

    Это моя первая статья и у меня есть чем поделиться. Возможно мой велосипед не нов и этим способом пользуется каждый, но когда-то давно искал решения, с ходу найти не получилось.

    О чем речь?

    Задача состояла в подключении файлов: HTML, JS, CSS; без специальной подготовки. Так же неудобно подключать бинарные файлы (например картинки) конвертируя их в HEX. Так как не хотелось конвертировать в HEX или разделять на строки, искал способ подключения файла в адресное пространство программы.

    Как обычно это выглядит

    Пример, c разделением строк:

    const char text[] = "" "\r\n" "Text" "\r\n" "";

    Пример, с HEX (больше подходит для бинарных данных):

    const char text[] = < 0x3C, 0x68, 0x74, 0x6D, 0x6C, 0x3E, 0x0A, 0x3C, 0x62, 0x6F, 0x64, 0x79, 0x3E, 0x54, 0x65, 0x78, 0x74, 0x3C, 0x2F, 0x62, 0x6F, 0x64, 0x79, 0x3E, 0x0A, 0x3C, 0x2F, 0x68, 0x74, 0x6D, 0x6C, 0x3E, 0 >;

    Видел даже такое:

    #define TEXT "\r\nText\r\n" const char text[] = TEXT;

    Все #define располагались в отдельном .h файле и подготавливались скриптом на Python. С аннотацией, что некоторые символы должны быть экранированы \ вручную в исходном файле. Честно немного волосы дыбом встали от такого мазохизма.

    А хотелось, чтобы файлы можно было спокойно редактировать, просматривать и при компиляции всё само подключалось и было доступно, например так:

    extern const char text[];

    Оказалось всё просто, несколько строчек в Assembler.

    Подключаем файл в Arduino IDE

    Добавляем новую вкладку или создаём файл в папке проекта с названием text.S, там же размещаем файл text.htm.

    Содержимое файла text.htm:

     Text 

    Содержимое файла text.S:

    .global text .section .rodata.myfiles text: .incbin "text.htm" .byte 0

    Не забываем нулевой символ \0 в конце, он здесь в строке сам не добавится.

    extern const char text[] PROGMEM; void setup() < Serial.begin(115200); Serial.println(text); >void loop()

    Компилируем, загружаем и смотрим вывод:

    Отлично, когда-то бы я от радости прыгал до потолка, от того что всё получилось.

    Код работает в AVR8, но например в ESP8266 получим аппаратный сбой. Всё потому, что чтение из Flash доступно по 32 бита и по адресам кратным 32 бит. Чтобы было всё хорошо, каждому файлу требуется делать отступ для кратности, код будет выглядеть так:

    .global text .section .rodata.myfiles .align 4 text: .incbin "text.htm" .byte 0

    Загрузить можно в секцию кода: .irom.text, если не хватает места в .rodata.

    Для STM32 так же рекомендуется выравнивать по 32 бита, но не обязательно.

    А как записать размер данных во время компиляции? Например, для бинарных данных не получится остановится по нулевому символу. Так же просто:

    .global text, text_size .section .rodata.myfiles text: .incbin "text.htm" text_end: .byte 0 text_size: .word (text_end - text)
    extern const char text[] PROGMEM; extern const uint16_t text_size PROGMEM;

    Осталось написать макрос, для удобства подключения файлов:

    .macro addFile name file .global \name, \name\()_size // .align 4 \name: .incbin "\file" \name\()_end: .byte 0 // .align 4 \name\()_size: .word (\name\()_end - \name) .endm .section .rodata.myfiles addFile text1 1.txt addFile text2 2.txt addFile text3 3.txt

    И макрос для объявления:

    #define ADD_FILE(name) \ extern const char name[] PROGMEM; \ extern const uint16_t name##_size PROGMEM; ADD_FILE(text1); ADD_FILE(text2); ADD_FILE(text3); void setup() < Serial.begin(115200); Serial.println(text1); Serial.println(text1_size); Serial.println(text2); Serial.println(text2_size); Serial.println(text3); Serial.println(text3_size); >void loop()

    Таким образом можно подключить любой файл и представить его любым типом, структурой или массивом.

    Подключаем любой файл и не только, в GNU toolchain

    Принцип тот же самый, ничем не отличается для Arduino. В принципе в Arduino используется тот же toolchain от Atmel.

    Только здесь у нас в руках Makefile и мы можем до компиляции и сборки запустить какой-нибудь скрипт.

    Для примера возьму код из готового моего проекта на STM32, где автоматически при компиляции увеличивается версия сборки. Так же включаются в проект WEB-интерфейс для последующего использования в LWIP / HTTPD.

    Скрипт version.sh:

    #!/bin/bash # Version generator # running script from pre-build MAJOR=1 MINOR=0 cd "$(dirname $0)" &>/dev/null FILE_VERSION="version.txt" FILE_ASM="version.S" BUILD=$(head -n1 "$FILE_VERSION" 2>/dev/null) if [ -z "$BUILD" ]; then BUILD=0 else BUILD=$(expr $BUILD + 1) fi echo -n "$BUILD" >"$FILE_VERSION" cat "$FILE_ASM" /** * no editing, automatically generated from version.sh */ .section .rodata .global __version_major .global __version_minor .global __version_build __version_major: .word $MAJOR __version_minor: .word $MINOR __version_build: .word $BUILD .end EOF cd - &>/dev/null exit 0

    Создаётся файл version.S в который из version.txt загружается номер версии предыдущей сборки.

    В Makefile добавляется цель pre-build:

    ####################################### # pre-build script ####################################### pre-build: bash version.sh

    В цель all надо дописать pre-build:

    all: pre-build $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin

    Объявление и макросы для printf у меня в macro.h:

    extern const uint16_t __version_major; extern const uint16_t __version_minor; extern const uint16_t __version_build; #define FMT_VER "%u.%u.%u" #define FMT_VER_VAL __version_major, __version_minor, __version_build

    В HTTPD из LWIP немного был удивлён когда увидел, что содержимое файлов надо хранить вместе с заголовками HTTP. Чтобы не менять архитектуру, загрузку делал как это организовано в примере fsdata.c. Использовал fsdata_custom.c, для этого установлен флаг HTTPD_USE_CUSTOM_FSDATA.

    Код в fsdata_custom.c:

    #include "lwip/apps/fs.h" #include "lwip/def.h" #include "fsdata.h" #include "macro.h" extern const struct fsdata_file __fs_root; #define FS_ROOT &__fs_root

    Сборка файлов fsdata_make.S:

    .macro addData name file mime \name\(): .string "/\file\()" \name\()_data: .incbin "mime/\mime\().txt" .incbin "\file\()" \name\()_end: .endm .macro addFile name next \name\()_file: .word \next\() .word \name\() .word \name\()_data .word \name\()_end - \name\()_data .word 1 .endm .section .rodata.fsdata .global __fs_root /* Load files */ addData __index_htm index.htm html addData __styles_css styles.css css addData __lib_js lib.js js addData __ui_js ui.js js addData __404_htm 404.htm 404 addData __favicon_ico img/favicon.ico ico addData __logo_png img/logo.png png /* FSDATA Table */ addFile __logo_png 0 addFile __favicon_ico __logo_png_file addFile __404_htm __favicon_ico_file addFile __ui_js __404_htm_file addFile __lib_js __ui_js_file addFile __styles_css __lib_js_file __fs_root: addFile __index_htm __styles_css_file .end 

    В начале каждого файла загружается заголовок, пару примеров из папки mime.

    Файл html.txt:

    HTTP/1.1 200 OK Content-Type: text/html; charset=UTF-8 Connection: close 

    Файл 404.txt:

    HTTP/1.1 404 Not found Content-Type: text/plain; charset=UTF-8 Connection: close 

    Нужно обратить внимание на пустую строку, чего требует спецификация HTTP для обозначения конца заголовка. Каждая строка должна заканчиваться символом CRLF (\r\n).

    P.S. Код проекта из ветхого сундука, так что в реализации мог забыть чего ни будь уточнить.

    В завершении

    Долго искал, что изложить в статье полезного. Надеюсь мой опыт пригодится новичку и гуру.

    Спасибо за внимание, удачных разработок!

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

https://kapelnicza.vyvod-iz-zapoya-na-domu-voronezh.ru/