4 / 4 / 4
Регистрация: 29.11.2014
Сообщений: 131
1

Чтение файла в строку char *

22.11.2017, 03:02. Показов 6725. Ответов 12
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Задача состоит в том, чтобы считать последние 65536 байт файла в char *(без символа конца файла), и все вроде бы работает, но когда я вывожу в консоль считанные данные, то в конце лишние рандомные символы всегда. В чем я ошибся? Как их убрать?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
errno_t err; // Нужно для безопасной работы с файлами
 
        FILE *pFile; // Переменная с файлом
        err = fopen_s(&pFile, filename, "rb"); // Открываем файл на чтение
 
        long long nFileLen = 0; // Длина файла
        long long offset = 0; // метка, куда нужно будет переместить указатель в файле.
        long long postfix = 65536; // кол-во считываемых байт.
        char * buffer;
 
        fseek(pFile, 0, SEEK_END);
        nFileLen = ftell(pFile);
        if ((nFileLen - 65536) < 0) postfix = nFileLen; // Если файл меньше 64 кб, то устанавливаем кол-во байт для смещения = размеру файла.
        offset = nFileLen - postfix;
        fseek(pFile, offset, SEEK_SET); // Перемещаем указать файла на нужное нам значение с начала файла.
        buffer = (char*)malloc(sizeof(char) * postfix); // Задаем длину переменной, в которой будет хранится инфа.
        fread(buffer, 1, nFileLen, pFile);
        fclose(pFile);
Над комментариями не смеяться, я их для себя писал)
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
22.11.2017, 03:02
Ответы с готовыми решениями:

Чтение из файла в массив char
Доброе время суток господа. У меня есть массив char a=&quot;I am text&quot; кпримеру, сама программа для...

Чтение из файла и запись в массив char
Здравствуйте форумчане. Столкнулся с незнанием языка. У меня есть поток, который читает файл. Как...

Чтение текстового файла в вектор типа char
Имеется текстовый файл. Необходимо прочитать его ПОЛНОСТЬЮ, включая все символы переноса строки (и...

Чтение бинарного файла функцией std::ifstream::read(char*, streamsize)
Не могу нормально считать текст в бинарном режиме с помощью функции read(char*, streamsize). ...

12
4063 / 3317 / 924
Регистрация: 25.03.2012
Сообщений: 12,483
Записей в блоге: 1
22.11.2017, 03:13 2
\0 в конце строки нету. буфер же читался не как текстовая строка, а значит ноль в конец ему не добавляли
0
4 / 4 / 4
Регистрация: 29.11.2014
Сообщений: 131
22.11.2017, 03:44  [ТС] 3
тем не менее, в конце лишние символы при выводе, которых нету в файле.
0
4063 / 3317 / 924
Регистрация: 25.03.2012
Сообщений: 12,483
Записей в блоге: 1
22.11.2017, 03:46 4
шо "тем не менее"? Ты ноль в конец строки добавил?
0
4 / 4 / 4
Регистрация: 29.11.2014
Сообщений: 131
22.11.2017, 03:58  [ТС] 5
Вопрос не в нуле, а в том, как исправить то, что при чтении файла, в котором записано только "123456" выводится "123456⌂╚╚☺"(или что-то подобное, символы каждый раз случайные)
0
4063 / 3317 / 924
Регистрация: 25.03.2012
Сообщений: 12,483
Записей в блоге: 1
22.11.2017, 04:02 6
allCrowley, Я тебе назвал причину, по которой выводятся лишние символы. Эта причина - нет нуля. На всякий случай напишу: нет, не об "1234560" этом нуле!
0
4 / 4 / 4
Регистрация: 29.11.2014
Сообщений: 131
22.11.2017, 05:07  [ТС] 7
Чтение файла в строку char *
Чтение файла в строку char *

Не по теме:

На C++ у меня нет никакого опыта и 0 написанных программ(исключая Hello worl'ы различные). До этого я писал на C#, в котором таких проблем отродясь не было, язык простой, понятный и без заморочек.

0
nd2
3437 / 2816 / 1249
Регистрация: 29.01.2016
Сообщений: 9,426
22.11.2017, 05:25 8
Лучший ответ Сообщение было отмечено allCrowley как решение

Решение

Выдели память на один байт больше, чем размер данных в файле. После чтения файла, помести по индексу, равному размеру данных в файле, символ '\0' (признак конца Си-строки).
1
4 / 4 / 4
Регистрация: 29.11.2014
Сообщений: 131
22.11.2017, 20:09  [ТС] 9
Как это можно сделать, применительно к моему методу? Я видимо не догоняю.
Сделал вот так:
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
char * FileRead(char *filename)
    {
        errno_t err; // Нужно для безопасной работы с файлами
 
        FILE *pFile; // Переменная с файлом
        err = fopen_s(&pFile, filename, "rb"); // Открываем файл на чтение
 
        long long nFileLen = 0; // Длина файла
        long long offset = 0;
        long long postfix = 65536;
        char * buffer;
 
        fseek(pFile, 0, SEEK_END);
        nFileLen = ftell(pFile);
        if ((nFileLen - 65536) < 0) postfix = nFileLen; // Если файл меньше 64 кб, то устанавливаем кол-во байт для смещения = размеру файла.
        offset = nFileLen - postfix;
        fseek(pFile, offset, SEEK_SET); // Перемещаем указать файла на нужное нам значение с начала файла.
        buffer = (char*)malloc(sizeof(char) * postfix)+1; // Задаем длину переменной, в которой будет хранится инфа.
        fread(buffer, 1, nFileLen, pFile);
        int len = strlen(buffer);
        buffer[len-1] = '\0';
        fclose(pFile);
 
        return buffer;
    }
Ну, то есть я в строке
C++
1
buffer = (char*)malloc(sizeof(char) * postfix)+1;
поставил +1, а в строке
C++
1
buffer[len-1] = '\0';
на последний символ записал нулевой байт.
Предполагалось что-то в этом роде: допустим, файл весит 10 байт. В таком случае функция
C++
1
(char*)malloc(sizeof(char) * postfix);
Вернет 10. Добавляем к этому +1 и получаем 11. В первые 10(от 0 до 9) читается файл, а в buffer[(11-1)] запишется '\0', но выполнение этого кода заканчивается исключением.
0
4063 / 3317 / 924
Регистрация: 25.03.2012
Сообщений: 12,483
Записей в блоге: 1
22.11.2017, 20:13 10
Цитата Сообщение от allCrowley Посмотреть сообщение
buffer = (char*)malloc(sizeof(char) * postfix)+1;
неправильно, не туда +1 поставил.
Н-Е-П-Р-А-В-И-Л-Ь-Н-О!!!
0
nd2
3437 / 2816 / 1249
Регистрация: 29.01.2016
Сообщений: 9,426
22.11.2017, 20:29 11
Цитата Сообщение от allCrowley Посмотреть сообщение
C++
1
buffer = (char*)malloc(sizeof(char) * postfix)+1; // Задаем длину переменной, в которой будет хранится инфа.
Скобки поставь, чтобы не указатель увеличивался, а размер выделяемой памяти.
Цитата Сообщение от allCrowley Посмотреть сообщение
C++
1
fread(buffer, 1, nFileLen, pFile);
Размер памяти один выделяешь, а читаешь другой размер данных?
Цитата Сообщение от allCrowley Посмотреть сообщение
C++
1
int len = strlen(buffer);
strlen() требуется '\0' в конце Си-строки, чтобы определить количество символов в строке.

Добавлено через 11 минут
Вот тебе пример, дальше сам разбирайся:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
    ifstream fin ("input.txt", ios::binary);
    if (fin)
    {
        fin.seekg(0, fin.end);
        size_t n = fin.tellg();
        char* buff = new char[n + 1];
        fin.seekg(0, fin.beg);
        fin.read(buff, n);
        buff[n] = '\0';
        cout << buff << endl;
    }
    else
        cout << "Error opening file!" << endl;
1
4 / 4 / 4
Регистрация: 29.11.2014
Сообщений: 131
22.11.2017, 23:02  [ТС] 12
Разобрался, спасибо
В итоге метод выглядит как-то так(на случай, если этот вопрос загуглит такой же дурачок как я в будущем):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
char * Read(char *filename)
    {
        char * buffer;
        errno_t err; 
        long long nFileLen = 0;
        FILE *pFile;
        err = fopen_s(&pFile, filename, "rb");
        fseek(pFile, 0, SEEK_END);
        nFileLen = ftell(pFile);
        buffer = ((char*)malloc(sizeof(char) * nFileLen))+1;
        fseek(pFile, 0, SEEK_SET);
        fread(buffer, 1, nFileLen, pFile);
        fclose(pFile);
        buffer[nFileLen] = '\0';
        return buffer;
    }
0
nd2
3437 / 2816 / 1249
Регистрация: 29.01.2016
Сообщений: 9,426
22.11.2017, 23:42 13
Цитата Сообщение от allCrowley Посмотреть сообщение
C++
1
buffer = ((char*)malloc(sizeof(char) * nFileLen))+1;
Опять не так, опять к указателю единицу прибавляешь. При освобождении памяти ошибка будет.
C++
1
buffer = (char*)malloc(nFileLen + 1);
1
22.11.2017, 23:42
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
22.11.2017, 23:42
Помогаю со студенческими работами здесь

Как считать строку из файла в char?
Всем привет! Считать строку из файла в string - не проблема. Функцию getline() и погнали. Но мне...

Запись символов из файла в единичный char и строку
Всем привет, учусь получать данные из файла и нашёл такое явление: если у нас есть такой код:...

Чтение из файла в строку
Всем привет! Подскажите, пожалуйста, как прочитать весь текст из файла в переменную string!...

Считать с файла строку типа char до знака окончания строки
Всем доброго времени суток. Мне нужно считать с файла строку типа char до знака окончания строки (...


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru