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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как прочитать файл до конца? 
:(
    Опции темы
Elfet
Дата 7.10.2009, 07:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

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



Приветствую!

Возникла такая проблема: мне нужно прочитать из файла такую структуру: 
Цитата


(0 "Zones:")
(45 (2 fluid fluid)())
(45 (3 wall bottom)())
(45 (4 wall top)())
(45 (5 pressure-outlet outlet)())
(45 (6 pressure-inlet inlet)())
(45 (7 wall cylinder)())
(45 (9 interior default-interior)())


и запомнить номер зоны и её название: (45 (id name)())

Пробовал делать вот, так:
Код

    int zone_id = 0; 
    char zone_name[255];
    char zone_name_2[255];

    while(fscanf(stream, "(45 (%d %s %s)())", zone_id, &zone_name, &zone_name_2) != 3)
    {
        mesh->zones->push_back(
                                                   new Zone( zone_id  ,  string(zone_name) + " " + string(zone_name_2)  )
                                                   );
    }


но ничего не получилось. 

Пожалуйста помогите! Заранее спасибо!


--------------------
PM MAIL WWW Skype   Вверх
niXman
Дата 7.10.2009, 08:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Elfet, Попробуйте так:
Код

    int zone_id = 0; 
    char zone_name[255];
    char zone_name_2[255];
    while(fscanf(stream, "(45 (%d %s %s)())", &zone_id, zone_name, zone_name_2) != 3)
    {
        mesh->zones->push_back(
                                                   new Zone( zone_id  ,  string(zone_name) + " " + string(zone_name_2)  )
                                                   );
    }


Но лучший вариант, это парсинг.
--------------------
if ( !c++ ) {   *power--;   this->wussiness += 10;}
PM MAIL   Вверх
Static
Дата 7.10.2009, 08:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(Elfet @  7.10.2009,  06:48 Найти цитируемый пост)
 while(fscanf(stream, "(45 (%d %s %s)())", zone_id, &zone_name, &zone_name_2) != 3)

fscanf возвращает количество успешно прочитанных элементов. Там точно должно быть "не равно"?
--------------------
Я не настолько безнадежен, как кажется...
PM MAIL   Вверх
Elfet
Дата 7.10.2009, 09:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

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



У меня считывается вот это: "fluid fluid)())" и происходит зацикливание. Как определить что мы уже пришли к концу файла?


--------------------
PM MAIL WWW Skype   Вверх
Static
Дата 7.10.2009, 09:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



ну надо не забыть, что после fscanf еще остается конец строки в файле... Поэтому надо делать fgets внутри while.

Добавлено через 2 минуты и 7 секунд
ну и да, вот это ")())" - воспринимается как часть считываемой строки.
--------------------
Я не настолько безнадежен, как кажется...
PM MAIL   Вверх
Elfet
Дата 7.10.2009, 09:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

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



Static, а можно ли как-нибудь это ")())" убрать? (или только вручную?)
Так как определить что больше нету нужных мне строк для считывания и файл закончен? 


--------------------
PM MAIL WWW Skype   Вверх
Static
Дата 7.10.2009, 10:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



можно в исходном файле автозаменой пробелы проставить smile

Добавлено через 1 минуту и 12 секунд
А определить - просто. Я ж написал, что там должно быть ==, а не !=. Когда он доберется до конца файла - как раз произойдет это != и цикл прервется.

Добавлено через 2 минуты и 31 секунду
Код

int zone_id;
char zone_name[128], zone_name_2[128];
FILE *f = fopen("sample.txt", "r");
while(fscanf(f, "(45 (%d %s %s)())", &zone_id, zone_name, zone_name_2) == 3) //пока три элемента можно прочитать - работаем
    {
    cout << zone_id << " " << zone_name << " " << zone_name_2 << endl;
    fgets(zone_name, 127, f); //читаем "огрызок" строки
    }

fclose (f);

--------------------
Я не настолько безнадежен, как кажется...
PM MAIL   Вверх
Elfet
Дата 7.10.2009, 10:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

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



Static, у меня перед всем этим ещё идёт и 
Цитата



(0 "Zones:")

Так что это нужно пропустить. И разбирать всё что начинается с (45 
Пробую сделать вот так, но программа подвисает:
Код

while(block_open(45))
    {
        int zone_id=0;
        char zone_name[255];
        char zone_name_2[255];

        if ( fscanf(stream, " (%d %s %s", &zone_id, zone_name, zone_name_2) != 3 )
            throw MyError();

        mesh->zones->push_back(new Zone(zone_id, string(zone_name) + " " + string(zone_name_2) ));
    }

...

bool block_open(int id)
{
    bool got_one = false;
    int tmp_id = 0;

    while (!got_one)
    {
        while ( fgetc( stream ) != '(' );

        if ( fscanf(stream, " %d", &tmp_id) != 1 )
            return false;

        got_one = (tmp_id == id);
    }

    return got_one;
}



--------------------
PM MAIL WWW Skype   Вверх
xvr
Дата 7.10.2009, 11:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Рекомендую сделать парсер. На связке flex+bison это займет строк 10  smile 

PM MAIL   Вверх
Elfet
Дата 7.10.2009, 16:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

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



Мне бы пока без парсера, так как предвещающая часть уже написана в таком стиле и переделывать её времени нет.


Как определить что файл закончен? 


--------------------
PM MAIL WWW Skype   Вверх
zim22
Дата 7.10.2009, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

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



Цитата(Elfet @  7.10.2009,  16:27 Найти цитируемый пост)
Как определить что файл закончен? 

feof


--------------------
PM MAIL   Вверх
Dov
Дата 7.10.2009, 17:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


аСинизатор
***


Профиль
Группа: Завсегдатай
Сообщений: 1721
Регистрация: 10.5.2003
Где: Эрец-Исраэль

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



Как-то так:
Код
#define SZ 128

int main()
{
    int   zone_id          = 0;
    char  zone_name[SZ]    = ""; 
    char  zone_name_2[SZ]  = "";
    char  buf[128]         = "";
    FILE *f                = fopen("filein.txt", "r");

    fgets(buf, SZ, f);   // 'пропускаем' первую строку файла
    while(!feof(f)) 
    {
        fgets(buf, SZ, f);
        sscanf(buf + 5, "%d%s%[^)]s", &zone_id, zone_name, zone_name_2);
        printf("%d %s %s\n", zone_id, zone_name, zone_name_2);        
    }
    
    fclose (f);
    return 0;
}



--------------------
Тут вечности запах томительный,
И свежие фрукты дешевые, 
А климат у нас – изумительный, 
И только соседи – #уевые. 
                           Игорь Губерман.
PM   Вверх
xvr
Дата 7.10.2009, 19:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Лучше fgets поставить в while вместо feof:
Код

    while(fgets(buf, SZ, f)) 
    {
        sscanf(buf + 5, "%d%s%[^)]s", &zone_id, zone_name, zone_name_2);
        printf("%d %s %s\n", zone_id, zone_name, zone_name_2);        
    }
иначе последняя строка будет обработана 2 раза

PM MAIL   Вверх
Dov
Дата 7.10.2009, 22:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


аСинизатор
***


Профиль
Группа: Завсегдатай
Сообщений: 1721
Регистрация: 10.5.2003
Где: Эрец-Исраэль

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



Цитата(xvr @  7.10.2009,  18:27 Найти цитируемый пост)
Лучше fgets поставить в while вместо feof:

Да, так тоже хорошо.   smile 

А я ещё вот этого не понял:
Цитата(Elfet @  7.10.2009,  06:48 Найти цитируемый пост)
мне нужно прочитать из файла такую структуру

Если есть структура, то как она выглядит? Можно же её целиком считывать с файла, а потом уже с ней работать. Или я чего-то не понял?   smile 



--------------------
Тут вечности запах томительный,
И свежие фрукты дешевые, 
А климат у нас – изумительный, 
И только соседи – #уевые. 
                           Игорь Губерман.
PM   Вверх
Elfet
Дата 7.10.2009, 23:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

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



Dov, да внутри файла такая структура данных:
Цитата

что-то ещё...

(0 "Zones:")
(45 (2 fluid fluid)())
(45 (3 wall bottom)())
(45 (4 wall top)())
(45 (5 pressure-outlet outlet)())
(45 (6 pressure-inlet inlet)())
(45 (7 wall cylinder)())
(45 (9 interior default-interior)())




--------------------
PM MAIL WWW Skype   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

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

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


 




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


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

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