2013-11-24 2 views
1

Я пытаюсь разработать простой просмотрщик трехмерных моделей, который должен иметь возможность читать файлы по строкам в формате obj. Это казалось очень простым, однако, когда std::getline попадает eof, программа выходит с ошибкой сегментации.Ошибка сегментации при чтении файла/ввода с помощью getline

Здесь я сделал наименьшее количество кода, которое дает мне segfault (здесь я использую std::cin, так что моя программа не заканчивается сразу, но я действительно получаю возможность ввести в нее некоторые вещи, и вручную ввести EOF):

std::string line; 
while(std::getline(std::cin, line)) 
    { 
     std::cout<<line; 
    } 

Другой вещь, чтобы заметить это, что этот код будет производить только Segfault, если строка, содержащая EOF пуста, в противном случае, если ВФ вводится в строке, содержащим что-нибудь еще, петля просто продолжается.

Edit: Теперь я воспроизвели с наименьшим кодом:

main.cpp

#include <iostream> 
#include "Model.h" 

int main(int argc, char* argv[]) 
{ 

    std::string path = "/home/thor/Skrivebord/3d_files/Exported.obj"; 
    obj::Model(path.c_str()); 

    return 0; 
} 

model.h

#ifndef MODEL_H_INCLUDED 
#define MODEL_H_INCLUDED 

namespace obj 
{ 
    class Model 
    { 
    public: 
     Model(const char* path); 
    }; 
} 

#endif // MODEL_H_INCLUDED 

Модель .cpp

#include <iostream> 
#include <vector> 
#include <fstream> 
#include <sstream> 
#include <string> 

namespace obj 
{ 
    class Model 
    { 
    public: 
     Model(const char* path); 

    private: 
     std::string name = ""; // Remove this line, and all works. 
    }; 

    Model::Model(const char* path) 
    { 
     std::string line; 

     while(std::getline(std::cin, line)) 
     { 
      std::cout << line; 
     } 
    } 
} 
+0

Просто сделайте 'while (getline (cin, line))' без условного 'eof()'. – 0x499602D2

+0

Я уже пробовал это, и это все равно дает мне segfault. – Lillesort131

+0

Затем покажите нам свой фактический код. – 0x499602D2

ответ

3

Проблема заключается в том, что ваш код имеет две противоречащие друг другу заявления Model.

В model.cpp у вас есть

class Model 
{ 
public: 
    Model(const char* path); 

private: 
    std::string name = ""; // Remove this line, and all works. 
}; 

но в model.h у вас есть

class Model 
{ 
public: 
    Model(const char* path); 
}; 

Вы должны иметь одно определение Model только положить, что в model.h и #include "Model.h" в модели .cpp

+0

Точно, какие части кода мне нужно переместить? Если я просто перемещаю сам класс, 'Model :: Model (const char * path) {...}' дает мне ошибку. – Lillesort131

+0

Просто переместите сам класс ** и ** добавьте '#include" Model.h "' в Model.cpp. – john

+0

У вас должно быть только одно определение любого класса. Поместите это определение в заголовочный файл и #include заголовочный файл где угодно. Это метод для того, чтобы убедиться, что у вас есть последовательные определения классов по всему вашему коду. – john

2

Это похоже на ошибку, хотя логика трудно понять.

void Face::AddVertex(float x, float y, float z) 
{ 
    if (vCnt > 3) 
    { 
     vertices[vCnt].SetPos(x, y, z); 
     ++vCnt; 
    } 
    else 
    { 
     vertices.push_back(Vertex(x, y, z)); 
     ++vCnt; 
    } 
} 

Это более логично с < не >, так как ваш vertices вектор первоначально размер 3

void Face::AddVertex(float x, float y, float z) 
{ 
    if (vCnt < 3) 
    { 
     vertices[vCnt].SetPos(x, y, z); 
     ++vCnt; 
    } 
    else 
    { 
     vertices.push_back(Vertex(x, y, z)); 
     ++vCnt; 
    } 
} 
+0

Все еще не работает, но спасибо за его поиск. – Lillesort131

Смежные вопросы