PDA

Visualizza la versione completa : [C++] Uso della funzione getline() su file .obj


Sart
14-04-2012, 17:13
Ciao a tutti,
sto cercando di caricare un file .obj (contenente un modello 3D) con le OpenGL. Per fare questo ho creato una funzione che trova il numero dei vertici all'interno del file e poi crea una matrice con tutti i vertici.

Il problema che la funzione che trova il numero dei vertici non funziona D:

la stavo testando con una console app, ecco il codice:



#include "stdafx.h"
#include <iostream>
#include <string>
#include <fstream>
#include <stdio.h>

using namespace std;

int calcolaV(string file){
char *file_obj=new char[file.size()];
string riga="";
int n=0;

for(int i=0; i<file.size(); i++){
file_obj[i]=file[i];
}

fstream input;
input.open(file_obj,fstream::in);
while(getline(input,riga)){
if(riga[0]=='v' && riga[1]==' '){
n++;
}
}
input.close();

return n;
}

int main(){
int a;
int vertici=calcolaV("cubo.obj");
cout<<"Numero vertici: "<<vertici;



cout<<"\nFine";
cin>>a;
}


Il problema che getline non funziona! mi restituisce 0 perch il ciclo non parte proprio e quindi la variabile n non viene incrementata!! :dh: perch?? help :)

PS: se non avete notato, ho scritto alla fine:
cout<<"\nFine";
cin>>a;
perch l'unico modo per poter leggere i dati che ho scritto, altrimenti la finestra si chiude subito! perdonate la mia ignoranza, ma cosa dovrei scrivere? io ero abituato con il dev-c++ e scrivevo system("PAUSE"); ma ora sono passato a visual c++ 2010 e non so cosa scrivere :D

shodan
14-04-2012, 19:30
Sicuro che il file sia nella directory dell'eseguibile?


int calcolaV(string file){

// VS2010 implementa l'estensione C++11 che permette
// di aprire uno stream usando direttamente una std::string
ifstream input(file);
if (!input) {
cout << "file " << file << " non trovato" << endl;
return -1;
}

while(getline(input,riga)){
if(riga[0]=='v' && riga[1]==' '){
n++;
}
}
input.close();

return n;
}



io ero abituato con il dev-c++

:incupito:


ma ora sono passato a visual c++ 2010 e non so cosa scrivere

Avvia il progetto con CTRL+F5

Sart
14-04-2012, 19:54
Ho scritto come hai detto tu e inizialmente andato tutto bene, anche se il file obj non si trova nella directory del file eseguibile e quindi ha dato errore.

Allora ho cambiato e al posto di scrivere "cubo.obj" ho scritto l'intera path, ma ora mi d un altro errore: string subscript out of range. Dove sbaglio? Ho anche provato a scrivere di nuovo "cubo.obj" ma niente resta tutto uguale :bh:

shodan
14-04-2012, 19:58
Nessuno qui un indovino. Se non posti il codice modificato, come possiamo sapere cosa causa l'errore? E poi, hai usato la funzione che ho modificato? E per finire: questo cubo.obj un file di testo o binario?
(chiedo perch i file .obj di solito sono file oggetto prodotti da una compilazione).

Sart
14-04-2012, 20:05
S hai ragione :D ecco l'intero programma modificato:



#include "stdafx.h"
#include <iostream>
#include <string>
#include <fstream>
#include <stdio.h>

using namespace std;

int calcolaV(string file){
string riga="";
int n=0;

ifstream input(file);
if(!input){
cout<<"Il file "<<file<<" non stato trovato."<<endl;
return -1;
}

while(getline(input,riga)){
if(riga[0]=='v' && riga[1]==' '){
n++;
}
}
input.close();

return n;
}

int main(){
int a;
int vertici=calcolaV("G:/Informatica/C++/Prova_mod/Debug/cubo.obj");
cout<<"Numero vertici: "<<vertici;



cout<<"\nFine";
cin>>a;
}


Sui file .obj non conosco molto, ma comunque penso siano di testo in quanto si possono aprire con il blocco note e vedere il loro contenuto.

Solitamente in una riga in cui presente un vertice, il primo carattere 'v' e poi ci sono 3 numeri (float) che rappresentano le coordinate dei vertici x, y e z.

Esempio:
v 1.0000000 -1.9987434 0.6665543

shodan
14-04-2012, 20:14
Presumo che l'errore sia dovuto al fatto che tenti di accedere a una locazione inesistente della stringa (a differenza di un array di char, la std::string non ha locazioni a cui accedere di default).


while(getline(input,riga)){
if (riga.empty()) continue;
if(riga[0]=='v' && riga[1]==' '){
n++;
}
}

Mi sfugge per il : riga[1]== spazio. Non ti basta sapere se il primo carattere 'v'?

Sart
15-04-2012, 09:16
Perfetto ora funziona :D grazie infinite!

Comunque no, non mi basta sapere solo se c' la v perch in un file .obj sono presenti anche le coordinate delle normali e delle texture. Le coord delle normali sono indicate con 'vn', mentre quelle delle texture con 'uv'. Per cui non sufficiente sapere solo se c' una v a inizio riga perch potrebbe essere confusa con una normale :)

Loading