Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Построчное чтение из файла? для поиска слова 
:(
    Опции темы
LeoKiyv
Дата 9.5.2012, 12:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 4.4.2012

Репутация: нет
Всего: нет



Доброго времени суток. У меня совсем простой вопрос, но который для меня оказался сложен.
Как читать построчно из файла?
Пример о функции fgets читает только первую строку:

Код

/* fgets example */
#include <stdio.h>

int main()
{
   FILE * pFile;
   char mystring [100];

   pFile = fopen ("myfile.txt" , "r");
   if (pFile == NULL) perror ("Error opening file");
   else {
     if ( fgets (mystring , 100 , pFile) != NULL )
       puts (mystring);
     fclose (pFile);
   }
   return 0;
}


А как считывать остальные строки?
Нужно для нахождения определенного слова в файле вида:
Цитата

Кошка;"пушистый, лохматый зверь"
Собака;"четвероногий друг человека"
Чайник;"емкость для разлива чая по чашкам"

а именно первых слов (Кошка, Собака, Чайник), для программы-словарика, о которой я писал:
http://forum.vingrad.ru/forum/topic-351496.html

Это сообщение отредактировал(а) LeoKiyv - 9.5.2012, 12:33
PM MAIL   Вверх
NadezdaT
Дата 9.5.2012, 13:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Крылья



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 4.4.2012

Репутация: нет
Всего: нет



попробуй 
while (!feof(fin)) // fin файл
    {
        fgets(strok, l_model, fin);//strok строка из n символов
        fscanf_s(fin, "\n");
        
    }
PM MAIL WWW   Вверх
feodorv
Дата 9.5.2012, 14:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 12
Всего: 45



Код

    while( fgets (mystring , 100 , pFile) != NULL )
    {
      ...
    }
    if( ferror( pFile ) ) ...;



--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
LeoKiyv
Дата 9.5.2012, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 4.4.2012

Репутация: нет
Всего: нет



feodorv, спасибо, заработало.
Модифицировал немного прогу, чтобы она находила искомую строку:

Код

#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;

int main()
{
   FILE * pFile;
   char mystring [100], word[100];
   cout << "Vvedite slovo dlia poiska: "; cin >> word;

   pFile = fopen ("slovar.txt" , "r");
   if (pFile == NULL) perror ("Error opening file");
   else {
     while ( fgets (mystring , 100 , pFile) != NULL )
     {
       puts (mystring);
       if (strstr(mystring, word)) {
            cout << "Prisutstvuet!" << endl; return 0; }
     }
     if( ferror( pFile) )
         fclose (pFile);
   }
   return 0;
}

Как сделать, чтобы она выдавала текст в строке, после найденного слова?
К примеру, нашло оно слово Кошка и выдавало его определение: пушистый, лохматый зверь ?

Это сообщение отредактировал(а) LeoKiyv - 9.5.2012, 19:26
PM MAIL   Вверх
feodorv
Дата 9.5.2012, 20:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 12
Всего: 45



Цитата(LeoKiyv @  9.5.2012,  18:18 Найти цитируемый пост)
Как сделать, чтобы она выдавала текст в строке, после найденного слова?


Да практически намёки уже есть в коде:
Цитата(LeoKiyv @  9.5.2012,  18:18 Найти цитируемый пост)
       if (strstr(mystring, word)) 

Функция strstr (а Вам точно зависимый от регистра букв поиск нужен?) возвращает не просто есть-нет, а прямо-таки указатель внутрь строки, где встретилась искомая последовательность. Только, на мой взгляд, Вы неправильно делаете. Если у Вас строки в словаре имеют вид
Цитата(LeoKiyv @  9.5.2012,  13:32 Найти цитируемый пост)
Кошка;"пушистый, лохматый зверь"
Собака;"четвероногий друг человека"
Чайник;"емкость для разлива чая по чашкам"

то нужно сравнивать начало строки (а не искать подстроку), плюс нужно убедиться, что в конце слова стоит точка с запятой. Это можно сделать так: заранее (до цикла) узнать длину слова, внутри цикла сравнить считанную строчку и заданное слово с помощью strncmp( mystring, word, wordlen), а затем 
посмотреть окончание слова:
Код

if( strncmp( mystring, word, wordlen) == 0 && mystring[wordlen] == ';' )
{
  ... found ...
}

Ну и с двойными ковычками разобраться (если они действительно нужны).


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
LeoKiyv
Дата 9.5.2012, 21:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 4.4.2012

Репутация: нет
Всего: нет



Цитата

Да практически намёки уже есть в коде:
Цитата(LeoKiyv @  9.5.2012,  18:18 Найти цитируемый пост)
       if (strstr(mystring, word)) 

Функция strstr (а Вам точно зависимый от регистра букв поиск нужен?) возвращает не просто есть-нет, а прямо-таки указатель внутрь строки, где встретилась искомая последовательность. 

А как это использовать?
Я потом с помощью:
Код

count = strspn(mystring, word);

Узнаю номер символа, где в строке заканчивается это слово. И вывожу потом оставшуюся часть строки на экран:
Код

int count, i, size;
count = strspn(mystring, word);
size = sizeof(mystring);
for (i = count; i<=size; i++)
    cout << mystring[i];

Вот только оно выдает еще кучу левых символов, после окончания строки, которыми оно заполнило масив char до сотни.
Так и не знаю, как отлавливать конец строки.
-------------------------------------------------------------------------------------------------------
Цитата

Только, на мой взгляд, Вы неправильно делаете. Если у Вас строки в словаре имеют вид
Цитата(LeoKiyv @  9.5.2012,  13:32 Найти цитируемый пост)
Кошка;"пушистый, лохматый зверь"
Собака;"четвероногий друг человека"
Чайник;"емкость для разлива чая по чашкам"

то нужно сравнивать начало строки (а не искать подстроку), плюс нужно убедиться, что в конце слова стоит точка с запятой. Это можно сделать так: заранее (до цикла) узнать длину слова, внутри цикла сравнить считанную строчку и заданное слово с помощью strncmp( mystring, word, wordlen), а затем 
посмотреть окончание слова:
Код

if( strncmp( mystring, word, wordlen) == 0 && mystring[wordlen] == ';' )
{
  ... found ...
}


Благодарю за подсказку.
А как узнать длину wordlen вводимого с клавиатуры слова?
sizeof(mystring) выдает всегда именно ту длину, которую я указал вручную, а именно 100.

Это сообщение отредактировал(а) LeoKiyv - 9.5.2012, 21:37
PM MAIL   Вверх
feodorv
Дата 10.5.2012, 09:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 12
Всего: 45



Цитата(LeoKiyv @  9.5.2012,  22:27 Найти цитируемый пост)
А как это использовать?

Код

char *p, *end;
if( (p = strstr( mystring, word)) != NULL )
{
  end = &p[wordlen];
  ...
}



Цитата(LeoKiyv @  9.5.2012,  22:27 Найти цитируемый пост)
А как узнать длину wordlen вводимого с клавиатуры слова?

Код

int wordlen = strlen( word );

 smile 


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
LeoKiyv
Дата 10.5.2012, 11:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 4.4.2012

Репутация: нет
Всего: нет



Цитата(feodorv @ 10.5.2012,  09:45)
Код

char *p, *end;
if( (p = strstr( mystring, word)) != NULL )
{
  end = &p[wordlen];
  ...
}

Код

int wordlen = strlen( word );

Спасибо, заработало)
Ты настоящий волшебник! smile 
Вот у меня еще вопрос. Используя код:
Код

if( strncmp( mystring, word, wordlen) == 0 && mystring[wordlen] == ';' )
{
  ... found ...
}

Как потом вывести часть строки после ';', без изспользования цикла for?

Это сообщение отредактировал(а) LeoKiyv - 10.5.2012, 11:11
PM MAIL   Вверх
feodorv
Дата 10.5.2012, 12:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 12
Всего: 45



Цитата(LeoKiyv @  10.5.2012,  12:06 Найти цитируемый пост)
 smile 

))))


Цитата(LeoKiyv @  10.5.2012,  12:06 Найти цитируемый пост)
Как потом вывести часть строки после ';', без изспользования цикла for?

Код

cout << &mystring[wordlen+1];

подойдёт?

PS Если строка в файле заканчивается переводом строки, то при её печати перевод строки на новую строку уже будет ;) Если нет (такое возможно для самой последней строки файла), то не будет)))


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
LeoKiyv
Дата 10.5.2012, 15:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 4.4.2012

Репутация: нет
Всего: нет



Цитата

подойдёт?

Да, то что нужно.
Переделал программу, чтобы она читала словарь Даля, который взял здесь:
http://www.zipsites.ru/slovari/dal/
Там слова представлены в виде:
Цитата
   БАНДУРА ж.  музыкальное  орудие,  весьма  похожее  на  лютню  или  на
балалайку, с округлым кузовом и металлическими струнами; на  ней  играют
перышком, как на турецкой домре.  |  У  нас  (малорос.)  бандурой  зовут
торбан, который гораздо больше и пузастее, а  играют  на  нем  пальцами,
по-гитарному. Бандурный или торбанный строй весь в один лад (аккорд),  а
струн бывает много, но не всегда  равно.  Бандурист  м.  бандуристка  ж.
игрок на бандуре. Бандуристы  или  торбанщики  бывали  прежде  в  каждом
порядочном  барском  дворе  Малороссии,  и  казачки  плясали  и  пели  с
бандурами. Бандурить, бренчать, заниматься музыкой для  забавы;  упуская
дело.
   БАНЕЦ? м. на канатном заводе: рученька  пеньки,  которую  прядильщик,
для сподручности, окатывает вокруг поясницы.

Мой рабочий код:
Код

#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;

int main()
{
   FILE * pFile;
   char mystring[1000], word[1000]; 
   cout << "Vvedite slovo dlia poiska: "; cin >> word;

   pFile = fopen ("tolkovyi_slovar_dalya.txt" , "r");
   if (pFile == NULL) perror ("Error opening file");
  
   while ( fgets (mystring , 1000 , pFile) != NULL ) // Считываем весь файл
   {
       if( strstr( mystring, word) != NULL ) { // Находим слово в верхнем регистре
           cout << mystring;                                // Выводим первую строку
           fgets (mystring , 1000 , pFile);            // Считываем следующую строку
               while (strstr(mystring, "   ") == NULL) { // До тех пор пока строка не будет начинаться с "   " - выводим на экран
                                                                                          // определение слова, считывая строки
                    cout << mystring; 
                    fgets (mystring , 1000 , pFile);
               }
               return 0;
       }
   }
   
   return 0;
}

Пока не знаю, как научить программу воспринимать кирилицу, транслитерировал весь словарь Штирлицем.
Сейчас учусь как привязать все это к простой форме MFC:
http://forum.vingrad.ru/forum/topic-351496.html

Это сообщение отредактировал(а) LeoKiyv - 10.5.2012, 15:31
PM MAIL   Вверх
feodorv
Дата 10.5.2012, 22:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 12
Всего: 45



Цитата(LeoKiyv @  10.5.2012,  16:23 Найти цитируемый пост)
Мой рабочий код:

С многострочными записями работать не так просто. Вот например:
Цитата(LeoKiyv @  10.5.2012,  16:23 Найти цитируемый пост)
           fgets (mystring , 1000 , pFile);            // Считываем следующую строку

А если нету следующей строки? Где проверка на NULL?


Цитата(LeoKiyv @  10.5.2012,  16:23 Найти цитируемый пост)
if( strstr( mystring, word) != NULL ) { // Находим слово в верхнем регистре

Про то, что strstr делает совсем не то, что Вы от неё хотите, я уже писал. Писал и как правильно сравнивать начало строк smile 
И где перевод в верхний регистр?


Цитата(LeoKiyv @  10.5.2012,  16:23 Найти цитируемый пост)
               while (strstr(mystring, "   ") == NULL) { // До тех пор пока строка не будет начинаться с "   " - выводим на экран

Опять таки, strstr - поиск подстроки в строке, а не сравнение начала строки (а вдруг такое встретится в ненужном месте?) Судя по тем записям словаря Даля, который Вы привели, достаточно проверить
Код

if( mystring[0] == ' ' && mystring[1] == ' ' && mystring[2] == ' ' ) ...;



Цитата(LeoKiyv @  10.5.2012,  16:23 Найти цитируемый пост)
Пока не знаю, как научить программу воспринимать кирилицу

Можно почитать здесь smile 


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
LeoKiyv
Дата 13.5.2012, 20:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 4.4.2012

Репутация: нет
Всего: нет



Подключил #include <locale.h>
Написал setlocale(LC_ALL, "");
Все равно не хочет искать русский текст в файле.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

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


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.2750 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.