Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.80
Tilk
0 / 0 / 0
Регистрация: 13.03.2010
Сообщений: 79
#1

Парсинг файла игнорирует числа - C++

11.03.2012, 18:31. Просмотров 1306. Ответов 21
Метки нет (Все метки)

Всем добрый день. Пытаюсь прочитать данные из файла 3D модели в формате OBJ.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
bool L_ObjData::LoadFromFile(string FileName)
{
   ifstream ifs(FileName.c_str());
   if (!ifs)
   {
      return false;
   }
 
   bool check = true;
 
   while(check == true)
   {
      check = ProcessLine(ifs);
   }
   ifs.close();
   return true;
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
bool L_ObjData::ProcessLine(istream& is)
{
   string element_id;
   float x, y, z;   
 
   is >> ws;
 
   if (!(is >> element_id))
   {
      return false;
   }
   // Дальше проверка строки
Дебажу element_id, он по одному слову из файла берет, но когда доходит до чисел - они просто игнорируются.

Вот мой тестовый файл
Код
# Blender v2.56 (sub 0) OBJ File: 'cube.blend'
# www.blender.org
mtllib cube.mtl
o Cube
v 0.984421 -0.936853 -1.021311
v 0.984421 -0.936853 0.978689
v -1.015579 -0.936853 0.978689
v -1.015578 -0.936853 -1.021311
v 0.984422 1.063147 -1.021311
v 0.984421 1.063147 0.978690
v -1.015579 1.063147 0.978689
v -1.015579 1.063147 -1.021311
vt 0.000000 0.000000
vt 1.000000 0.000000
vt 1.000000 1.000000
vt 0.000000 1.000000
usemtl Material_matrix.jpg
s off
f 1/1 2/2 3/3 4/4
f 5/1 8/2 7/3 6/4
f 1/1 5/2 6/3 2/4
f 2/1 6/2 7/3 3/4
f 3/1 7/2 8/3 4/4
f 5/1 1/2 4/3 8/4
После того как в element_id вижу в дебаге "o" и "Cube", потом только "v" и "vt", числа пропускаются. Подскажите пожалуйста как по целой строчке записывать в строку, чтобы ее потом нарезать на куски? Или как еще это можно сделать?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.03.2012, 18:31
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Парсинг файла игнорирует числа (C++):

VS 2015 игнорирует функции из заголовочного файла - C++
Всем привет :) Заморочился соединить OpenGL с Windows Form по исходникам 2006 года, в результате в проекте куча файлов и возникла...

Парсинг файла - C++
Вот открываю через FILE*, файл ввида "test" { "test1" "test1_1" "test2" "test2_1" "test3" "test3_1" ...

Парсинг файла - C++
Загружаю файл в string, строка в файле только одна, так что масив ненужен. В чем задача стоит? Содержимое файла такое: {"параметр_1":...

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

Парсинг строк из файла - C++
Имеется файл с содержанием 3 Text Text2 Text3

Парсинг и валидация записи числа - C++
Дана запись числа: , требуется выполнить её валидацию и вернуть double в значении функции и код ошибки через параметр. Как нибудь я это...

21
gooseim
Эксперт С++
508 / 412 / 37
Регистрация: 23.09.2010
Сообщений: 1,159
11.03.2012, 18:46 #2
Что такое ws?
0
Tilk
0 / 0 / 0
Регистрация: 13.03.2010
Сообщений: 79
11.03.2012, 19:03  [ТС] #3
Это отсюда
http://www.cplusplus.com/reference/i...perator%3E%3E/
с манипуляторами экспериментирую

Эта строчка на результате не сказалась.

C++
1
is >> ws;
0
gooseim
Эксперт С++
508 / 412 / 37
Регистрация: 23.09.2010
Сообщений: 1,159
11.03.2012, 19:19 #4
Покажите полностью код ProcessLine(istream& is).
0
Tilk
0 / 0 / 0
Регистрация: 13.03.2010
Сообщений: 79
11.03.2012, 19:29  [ТС] #5
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
bool L_ObjData::ProcessLine(istream& is)
{
    string element_id;
    float x, y, z;   
 
    is >> ws;
 
    if (!(is >> element_id))
    {
        return false;
    }
 
    if (element_id == "v")
    {
        is >> x >> y >> z;
        AddPosition(float3(x, y, z));
    }
    else if (element_id == "vt")
    {
        is >> x >> y;
        AddUV(float2(x, 1.0f - y));
    }
    else if (element_id == "f")
    {   
        unsigned int vi[4] = {0, 0, 0, 0};
        unsigned int ti[4] = {0, 0, 0, 0};
 
        for (int i = 0; i < 4; i++)
        {
            char c;
            is >> vi[i] >> c >> ti[i];
            if(!is.good())
            {
                break;
            }
        }
 
        /*string tempstring;
        is >> tempstring;*/
 
        AddFace(S_ObjFace(vi[0], ti[0], vi[1], ti[1], vi[2], ti[2]));
        if(vi[3] != 0 && ti[3] != 0)
        {
            AddFace(S_ObjFace(vi[0], ti[0], vi[2], ti[2], vi[3], ti[3]));
        }
 
        is.clear();
    }
    else
    {
        SkipLine(is);
    }
 
    return true;
}
 
void L_ObjData::SkipLine(istream& is)
{
    char next;
    is >> std::noskipws;
    while( (is >> next) && (next != '\n') )
    {
 
    }
}
0
gooseim
Эксперт С++
508 / 412 / 37
Регистрация: 23.09.2010
Сообщений: 1,159
11.03.2012, 19:38 #6
Откуда вы сделали выводы, что числа пропускаются? Ваши операции. Какую переменную дебажили.
0
Tilk
0 / 0 / 0
Регистрация: 13.03.2010
Сообщений: 79
11.03.2012, 19:51  [ТС] #7
Я работаю в Visual Studio 2010 Express.

Поставил брейкпоинты на 10 и 13ую строки кода и периодически нажимая F5 наводился мышью на element_id.

Результаты дебага (данные в element_id)
#
#
mtllib
o
v
"" - на этом срабатывает выход из функции по условию if (!(is >> element_id))

Результаты дебага если закомментить это
(50-52 строчки в коде в 5ом посте)
C++
1
2
3
4
else
{
  //SkipLine(is);
}
#
Blender
v2.56
(sub
0)
OBJ
File:
cube.blend
#
www.blender.org
mtllib
cube.mtl
o
Cube
v
v
v
v
v
v
v
vt
vt
...

В обоих случаях фрагменты с числами были проигнорированы.
0
ValeryS
Модератор
6653 / 5062 / 470
Регистрация: 14.02.2011
Сообщений: 16,926
11.03.2012, 20:02 #8
Цитата Сообщение от Tilk Посмотреть сообщение
Поставил брейкпоинты на 10 и 13ую строки кода и периодически нажимая F5
пошаговое прохождение Ф10 без захода в функции Ф11 с заходом
Цитата Сообщение от Tilk Посмотреть сообщение
наводился мышью на element_id.
лучше записать в окно переменных

Добавлено через 6 минут
Цитата Сообщение от Tilk Посмотреть сообщение
element_id == "v"
ты считал строку а проверяешь её на символ(точнее строку из одной буквы) конечно они не равны
тебе надо функции поиска (находятся ли в строке символ v)
разделения
если да то все что справа прочитать числами
Цитата Сообщение от Tilk Посмотреть сообщение
float x, y, z;
Цитата Сообщение от Tilk Посмотреть сообщение
is >> x >> y >> z;
с чего ты взял что в текстовом файле есть числа?
это такие же строки которые надо конвертировать
0
gooseim
Эксперт С++
508 / 412 / 37
Регистрация: 23.09.2010
Сообщений: 1,159
11.03.2012, 20:05 #9
Tilk, вы проверяете переменную element_id, но в ней чисел быть и не может.
Числа обрабатываются здесь:
C++
1
is >> x >> y >> z;
0
Tilk
0 / 0 / 0
Регистрация: 13.03.2010
Сообщений: 79
11.03.2012, 20:11  [ТС] #10
gooseim
Господи, точно! Спасибо огромное!
0
Tilk
0 / 0 / 0
Регистрация: 13.03.2010
Сообщений: 79
13.03.2012, 18:24  [ТС] #11
Помогите пожалуйста найти ошибку. Парсинг этого же файла.

Фрагмент
Код
	case OBJ_STRING_VERTEXPOS:
		fin >> x >> y >> z;
		AddPosition(x, y, z);
		SkipLine(fin);
		break;
В x,y,z не записываются нормальные данные. (см. прилепленный файл)

Строчка в файле данных
Код
v 0.984421 -0.936853 0.978689
Весь код
Код
////////////////////////////////////////////////////////////////////////////////
// Filename: L_objdata.cpp
////////////////////////////////////////////////////////////////////////////////
#include "L_objdata.h"

L_ObjData::L_ObjData()
{

}

L_ObjData::~L_ObjData()
{

}

bool L_ObjData::LoadFromFile(string FileName)
{
	ifstream fin;
	fin.open(FileName);
	fin >> noskipws;

	if(!fin)
	{
		return false;
	}

	while(!fin.eof())
	{
		ProcessLine(fin);
	}

	return true;
}

OBJ_STRING L_ObjData::CheckLineType(string teststring)
{
	if(teststring == "#")
	{
		return OBJ_STRING_COMMENT;
	}
	if(teststring == "v")
	{
		return  OBJ_STRING_VERTEXPOS;
	}
	if(teststring == "vt")
	{
		return  OBJ_STRING_TEXCOORD;
	}
	if(teststring == "f")
	{
		return  OBJ_STRING_FACE;
	}

	return  OBJ_STRING_UNKNOWN;
}

bool L_ObjData::ProcessLine(ifstream& fin)
{
	string element_id;
	if(!(fin >> element_id))
	{
		return false;
	}

	float x, y, z;

	switch(CheckLineType(element_id))
	{
	case OBJ_STRING_COMMENT:
		SkipLine(fin);
		break;
	case OBJ_STRING_VERTEXPOS:
		fin >> x >> y >> z;
		AddPosition(x, y, z);
		SkipLine(fin);
		break;
	case OBJ_STRING_TEXCOORD:
		SkipLine(fin);
		break;
	case OBJ_STRING_FACE:
		SkipLine(fin);
		break;
	case OBJ_STRING_UNKNOWN:
		SkipLine(fin);
		break;
	};

	return true;
}

void L_ObjData::SkipLine(ifstream& fin)
{
    char next = ' ';
    while(next != '\n')
	{
		fin >> next;
	};
}

void L_ObjData::AddPosition(float tx, float ty, float tz)
{
	positions.push_back(float3(tx,ty,tz));
}
0
Миниатюры
Парсинг файла игнорирует числа  
slice
35 / 78 / 4
Регистрация: 04.11.2010
Сообщений: 249
13.03.2012, 20:06 #12
Цитата Сообщение от Tilk Посмотреть сообщение
fin >> noskipws;
Это зачем?
0
Tilk
0 / 0 / 0
Регистрация: 13.03.2010
Сообщений: 79
13.03.2012, 20:14  [ТС] #13
Без этого вообще ничего не читается. Один раз ловится "#" в element_id и больше ничего.
0
slice
35 / 78 / 4
Регистрация: 04.11.2010
Сообщений: 249
13.03.2012, 20:20 #14
А с ним разве лучше?
0
Tilk
0 / 0 / 0
Регистрация: 13.03.2010
Сообщений: 79
13.03.2012, 20:23  [ТС] #15
Да. С ним, если закомментить строчки 73 и 74 и поставить брейкоинты на все SkipLine(fin). То програма определяет все "#", "v", "vt", "f" в том порядке как они идут в файле. Не понятно только, почему после "v" не читаются три числа.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.03.2012, 20:23
Привет! Вот еще темы с ответами:

typdef struct + парсинг из файла - C++
Собственно такая задача : Надо создать структуру, на основе чтения из файла. От вас готового когда не прошу, если можно - просты ссылки...

Парсинг текстового файла в map - C++
Здравствуйте! Подскажите, пожалуйста, как парсить текстовый файл в map. Например, есть файл, в котором записано следующее: 1 a 2 b 3...

Парсинг из файла и суммирование столбца - C++
В файле &quot;data.txt&quot; записаны 2 столбца чисел. Написать функцию, которая находит сумму чисеол во 2 столбце. (столбцы разделены ' ') Заранее...

Парсинг файлов, найти целые числа - C++
добрый день, требуется следующее: есть файл list.txt его содержимое каждая строчка содержит путь к файлу например D:\file1.txt...


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

Или воспользуйтесь поиском по форуму:
15
Yandex
Объявления
13.03.2012, 20:23
Ответ Создать тему
Опции темы

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