Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.71
undestroyer
0 / 0 / 3
Регистрация: 24.03.2013
Сообщений: 53
#1

Посимвольное чтение из файла - C++

09.05.2013, 16:17. Просмотров 2637. Ответов 26
Метки нет (Все метки)

Всем добрый вечер (ночь)! Так сложилась ситуация что нужно мне посимвольно считать текст из файла fin в массив str[i][j], причем считывать надо только ДО символа переноса строки \n(включительно). Скажите пожалуйста почему не работает мой фрагмент (где-то зацикливается):
C++
1
2
3
4
5
6
7
8
9
10
11
while (!feof(fin))
    {
        do
        {
            str[i][j]=fgetc(fin);
            j++;
        }
        while (str[i][j]!='\n');
        i++;
        j=0;
    }
Добавлено через 20 часов 24 минуты
По ходу выполнения чтения в str[0][0] записывается ноль и больше ничего не происходит. В чем косяк?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.05.2013, 16:17
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Посимвольное чтение из файла (C++):

Посимвольное чтение файла в вектор
Вечер добрый. Есть файл sir.in.txt, содержащий строку ABC; посимвольно...

Посимвольное чтение
В консоль подается текст содержащий такие выражения: а=3 b=7 z=32 a=1...

Посимвольное чтение массива char
Производится чтение из файла.Определенный диапазон считывается в...

Посимвольное чтение строки типа string
Здравствуйте! Подскажите, пожалуйста. У меня есть строка типа string, нужно...

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

Как создать посимвольное чтение строки и загнать в массив
В консоль подается строка вида "()(()))((", нужно создать динамический массив...

26
stima
495 / 345 / 93
Регистрация: 22.03.2011
Сообщений: 1,107
Завершенные тесты: 2
09.05.2013, 16:42 #2
C++
1
2
3
4
5
6
    do
        {
            str[i][j]=fgetc(fin);
            j++; //<----------- Подумайте над этим) Подсказка, а именно о местоположении.
        }
        while (str[i][j]!='\n');
0
metaluga145
243 / 244 / 38
Регистрация: 08.04.2013
Сообщений: 927
09.05.2013, 16:45 #3
C++
1
2
3
4
5
6
7
8
9
10
11
while (!feof(fin))
    {
        do
        {
            str[i][j]=fgetc(fin);
            j++;
        }
        while (str[i][j-1]!='\n');
        i++;
        j=0;
    }
0
undestroyer
0 / 0 / 3
Регистрация: 24.03.2013
Сообщений: 53
09.05.2013, 16:57  [ТС] #4
Цитата Сообщение от stima Посмотреть сообщение
C++
1
2
3
4
5
6
    do
        {
            str[i][j]=fgetc(fin);
            j++; //<----------- Подумайте над этим) Подсказка, а именно о местоположении.
        }
        while (str[i][j]!='\n');
Насколько я понимаю тут все логично. заполнили 1 ячейку -> перешли на другую

Цитата Сообщение от metaluga145 Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
while (!feof(fin))
    {
        do
        {
            str[i][j]=fgetc(fin);
            j++;
        }
        while (str[i][j-1]!='\n');
        i++;
        j=0;
    }
аналогично зацикливается

Главная суть: Мне нужно сохранить текст из файла сохраняя форматирование (отдельная строка текста в отдельной строке массива[количество символов в строке меньше 80, но в каждой строке по-разному]). Возможно вы предложите лучшее решение
0
metaluga145
243 / 244 / 38
Регистрация: 08.04.2013
Сообщений: 927
09.05.2013, 17:04 #5
Вам поможет функция getline
0
stima
495 / 345 / 93
Регистрация: 22.03.2011
Сообщений: 1,107
Завершенные тесты: 2
09.05.2013, 17:12 #6
Цитата Сообщение от undestroyer Посмотреть сообщение
Насколько я понимаю тут все логично. заполнили 1 ячейку -> перешли на другую
Какую вы ячейку проверяете? Дууумайте.
0
undestroyer
0 / 0 / 3
Регистрация: 24.03.2013
Сообщений: 53
09.05.2013, 17:22  [ТС] #7
Цитата Сообщение от stima Посмотреть сообщение
Какую вы ячейку проверяете? Дууумайте.
какую только что заполнил. do ... while сначала выполняет блок do{}, потом проверяет условие в while. Заполнил ячейку очередным символом, если это символ переноса строки, то перехожу на другую строку (i++), если нет - продолжаю получать символы в текущую строку. Правильно?
0
metaluga145
243 / 244 / 38
Регистрация: 08.04.2013
Сообщений: 927
09.05.2013, 17:25 #8
Цитата Сообщение от undestroyer Посмотреть сообщение
какую только что заполнил. do ... while сначала выполняет блок do{}, потом проверяет условие в while. Заполнил ячейку очередным символом, если это символ переноса строки, то перехожу на другую строку (i++), если нет - продолжаю получать символы в текущую строку. Правильно?
Нет. Сначала выполнится i++, а потом уже проверится условие
0
stima
495 / 345 / 93
Регистрация: 22.03.2011
Сообщений: 1,107
Завершенные тесты: 2
09.05.2013, 17:29 #9
1. Прочитали символ. Сохранили его в i(0)j(0)
2. Инкрементируем j. Теперь там 1.
3. Проверили ячейку i(0)j(1).

Вопрос: Ну и что мы проверяем?
Вопрос 2: Это С или C++? Если С++ то http://www.cplusplus.com/reference/istream/istream/tellg/.
0
undestroyer
0 / 0 / 3
Регистрация: 24.03.2013
Сообщений: 53
09.05.2013, 17:37  [ТС] #10
Цитата Сообщение от metaluga145 Посмотреть сообщение
Нет. Сначала выполнится i++, а потом уже проверится условие
Спасибо, понял, но:
C++
1
2
3
4
5
6
7
8
9
10
11
while (!feof(fin))
    {
        j=0;
        do
        {
            str[i][j]=fgetc(fin);
            j++;
        }
        while (str[i][j-1]!='\n');
        i++;
    }
тоже где-то зацикливается.
Текст в тестируемом файле:
12354
4575
878
0
metaluga145
243 / 244 / 38
Регистрация: 08.04.2013
Сообщений: 927
09.05.2013, 17:42 #11
попробуйте вместо feof написать EOF
0
stima
495 / 345 / 93
Регистрация: 22.03.2011
Сообщений: 1,107
Завершенные тесты: 2
09.05.2013, 17:49 #12
Вы не хотите думать). Ладно:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int read_all(FILE* in, char** buff)
{
   if (!in) return 0;
   if (*buff) free(buff);
 
   int count = fseek (in, 0 , SEEK_END);
   *buff= (char*)malloc(count * sizeof(char));
 
   if (!*buff) return 0;
 
   fread (*buff, sizeof(char), count , in);
 
   return count;
}
0
undestroyer
0 / 0 / 3
Регистрация: 24.03.2013
Сообщений: 53
09.05.2013, 18:04  [ТС] #13
Цитата Сообщение от metaluga145 Посмотреть сообщение
попробуйте вместо feof написать EOF
точно не то. ругается при компилировании (expression must have (pointer-to-) function type).
сейчас попробую переписать на getline

Добавлено через 15 минут
Цитата Сообщение от stima Посмотреть сообщение
Вы не хотите думать). Ладно:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int read_all(FILE* in, char** buff)
{
   if (!in) return 0;
   if (*buff) free(buff);
 
   int count = fseek (in, 0 , SEEK_END);
   *buff= (char*)malloc(count * sizeof(char));
 
   if (!*buff) return 0;
 
   fread (*buff, sizeof(char), count , in);
 
   return count;
}
спасибо за код, возможно его и возьму, только не понимаю для чего вы мне возвращаете count...
0
stima
495 / 345 / 93
Регистрация: 22.03.2011
Сообщений: 1,107
Завершенные тесты: 2
09.05.2013, 18:05 #14
Это стандартная практика. Например если вы дальше будете записывать в файл? Что обратно цикл? или сразу блок в count charов
0
metaluga145
243 / 244 / 38
Регистрация: 08.04.2013
Сообщений: 927
09.05.2013, 18:13 #15
stima, у меня пару вопросов по Вашему коду.
http://www.cplusplus.com/reference/cstdio/fseek/
fseek возвращает 0, если все прошло удачно. Да? что делает эта строка ?
C++
1
int count = fseek (in, 0 , SEEK_END);
Добавлено через 2 минуты
Кроме этого надо было сохранить каждую строку файла в отдельную строку. Вместо этого все что было в файле, оказалось в буфере. Как разобрать где там какая строка?
0
stima
495 / 345 / 93
Регистрация: 22.03.2011
Сообщений: 1,107
Завершенные тесты: 2
09.05.2013, 18:16 #16
Вы правы ... используйте это ftell(in);
0
undestroyer
0 / 0 / 3
Регистрация: 24.03.2013
Сообщений: 53
09.05.2013, 18:19  [ТС] #17
Вопрос всем: почему нужно использовать специальные функции для получения строки? почему нельзя посимвольно получать данные из файла и проверять очередной символ на перенос строки?
0
stima
495 / 345 / 93
Регистрация: 22.03.2011
Сообщений: 1,107
Завершенные тесты: 2
09.05.2013, 18:22 #18
C
1
2
3
4
5
6
7
8
9
for (int i = 0, c = 0; (c = fgetc(fin)) != EOF; ++i)
{
     int j = 0;
     for ( ;str[i][j] != '\n'; ++j)
     {
          str[i][j] = c;
     }
     str[i][j] = 0;
}
п.с. не проверял, но должно работать)
0
metaluga145
243 / 244 / 38
Регистрация: 08.04.2013
Сообщений: 927
09.05.2013, 18:23 #19
Цитата Сообщение от undestroyer Посмотреть сообщение
Вопрос всем: почему нужно использовать специальные функции для получения строки? почему нельзя посимвольно получать данные из файла и проверять очередной символ на перенос строки?
Зачем изобретать велосипед?
0
undestroyer
0 / 0 / 3
Регистрация: 24.03.2013
Сообщений: 53
09.05.2013, 18:29  [ТС] #20
Цитата Сообщение от metaluga145 Посмотреть сообщение
Зачем изобретать велосипед?
когда мне нужно было провести какую-то обработку текста я всегда делал это "налету" посимвольно считывая из потока и сразу проводя нужные изменения. сейчас впервые приходится брать текст из файлов. хочется сделать по-привычке)
0
09.05.2013, 18:29
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.05.2013, 18:29
Привет! Вот еще темы с решениями:

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

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

Посимвольное считывание из файла в массив int
Вообщем есть файл с числами(там всегда будут числа). Примерно такого...

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


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru