[C++] Wczytywanie konfiguracji z pliku
Ostatnio zmodyfikowano 2014-01-30 12:53
alixir |
» 2014-01-29 07:26:56 Wczytujesz pierwszą linię i odrazu w pętli masz warunek: if( name.compare( option_name ) ) { return option_value; } else { return 0; }
Jeśli nie ma tu szukanego wyrazu to funkcja się kończy 'return 0'. Przesuń return 0; poza pętlę while, a w jego miejsce wstaw continue; A ogólnie to według mnie twoja metoda ma wadę, dlatego że uwzględnia/nieuwzględnia spacji. Co się stanie gdy w pliku konfigracyjnym zamiast: ts3_stop = stop będzie ts3_stop = stop lub ts3_stop=stop |
|
RazzorFlame |
» 2014-01-29 09:34:33 while( std::getline( file, line ) ) { if( !line.length() ) continue;
(...) program wczytuje tylko pierwszą linijkę pliku
|
A co chciałeś osiagnąć? Przecież program wczyta pierwszą linijkę która nie jest pusta i od razu sprawdza warunek, powinieneś sprawdzać czy podana nazwa wartości jest w danej linijce a jeżeli nie to przejdź do dalszej linijki (a nie wyjdź z programu - return). |
|
--Smigol-- Temat założony przez niniejszego użytkownika |
» 2014-01-29 13:40:08 Zrobiłem tak jak napisał Alixir i wszystko działa - dzięki wielkie. Jeśli masz jakiś pomysł jak to poprawić, żeby działało nawet ze spacjami, to chętnie się czegoś nauczę. Pozdrawiam. |
|
alixir |
» 2014-01-30 12:53:00 Nie jestem dobrym nauczycielem, bo sam się szkolę, ale napisałem sobie taki przykładowy programik. Może dzięki jego analizie wpadną ci do głowy nowe pomysły. #include <iostream> #include <string> #include <limits> #include <fstream> #include <sstream> #include <vector>
struct sConfig { std::string name, value; };
void PressEnter(); void removeSpaces( std::string & ); int readConfig( std::string, std::vector < sConfig > * );
int main() { std::string file_name = "config.txt"; std::vector < sConfig > vConf; if( readConfig( file_name, & vConf ) ) { for( int i = 0; i < vConf.size(); i++ ) { std::cout << "Name = " << vConf[ i ].name; std::cout << "\tValue = " << vConf[ i ].value << std::endl; } } PressEnter(); return 0; }
void PressEnter() { std::cout << "Press ENTER to continue..."; std::cin.clear(); std::cin.ignore( std::numeric_limits < std::streamsize >::max(), '\n' ); }
void removeSpaces( std::string & text ) { while( text.find( ' ' ) != std::string::npos ) text.erase( text.find( ' ' ), 1 ); }
int readConfig( std::string fname, std::vector < sConfig > * vec ) { std::ifstream h_file( fname.c_str() ); if( !h_file.good() ) { std::cout << "Error reading the config file. Check path and permissions." << std::endl; return 0; } std::string buff; bool fail = false; int line_nr = 1; while( std::getline( h_file, buff ) ) { size_t pos = buff.find( "#" ); if( pos != std::string::npos ) buff.erase( pos, buff.length() - pos ); removeSpaces( buff ); std::istringstream ss( buff ); std::string token; sConfig conf; int counter = 0; while( std::getline( ss, token, '=' ) ) { if( token.length() == 0 ) { std::cout << "Error in config file. Line nr: " << line_nr << " (name missing)" << std::endl; fail = true; break; } if( counter == 0 ) conf.name = token; else if( counter == 1 ) conf.value = token; else { std::cout << "Error in config file. Line nr: " << line_nr << " (using twice '=')" << std::endl; fail = true; break; } counter++; } if( counter == 1 ) { std::cout << "Error in config file. Line nr: " << line_nr << " (value or '=' missing)" << std::endl; fail = true; } if( fail ) { h_file.close(); return 0; } line_nr++; if( counter == 0 ) continue; vec->push_back( conf ); } h_file.close(); return 1; } Plik na którym testowałem: Możesz potestować usuwając co się da i jak się da (nie zawiera oczywiście wszelkich zabezpieczeń, ale ma zobrazować sytuację) # Comment 1 game_start = start# game_stop = stop # Comment 2 game_player = player1, player2, player3 game_speed = 100 # comment 3 game_status = ready
|
|
1 « 2 » |