Wczytywanie liczb z pliku.

Wczytywanie liczb z pliku.
Rafbeam
  • Rejestracja:ponad 7 lat
  • Ostatnio:około 5 lat
  • Postów:44
0

W jaki sposób wczytać liczby oraz nazwy opcji, chcę zmodyfikować ten kod:

Kopiuj
#include <iostream>
#include <fstream>
#include <string>

int main()
{
    std::string option = "";
    std::string value = "";
    std::string line = "";
    std::ifstream cfg("game.cfg");
    int index = 0;
    if (cfg.is_open())
    {
        while (getline(cfg, line) )
        {
            if(line[0] != '#' && line != "")
            {
                value = line;
                option = line;

                index = option.find('=');
                value.erase(0, index+1);
                option.erase(index, line.length()-1);

                index = 0;
                line = "";

                std::cout<<option<<" = "<<value<<"\n";

                option = "";
                value = ""; //Chcę mieć liczby
            }
        }
        cfg.close();
    }
}

Przykładowy plik:

Kopiuj
#GAME CLIENT CONFIGURATION FILE
#DO NOT CHANGE ANY CONTENTS OF THIS FILE

#########################################
#ONLY FOR PEOPLE WHO KNOW WHAT TO DO HERE
#########################################

#BEGIN

fullscreen=1 //nazwa_opcji=liczba
width=0
height=0
vsync=0
renderdistance=100

#END
YooSy
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad 5 lat
  • Postów:472
0

Użyj debuggera lub wypisz pobrane dane przed obróbką, aby zobaczyć na jakich danych pracuje program, a zrozumiesz błąd w myśleniu.


Nie pisz na priv. Zadaj dobre pytanie na forum.
Rafbeam
Chcę mieć liczbę int (jeżeli się da to float) zamiast liczby string (char*). Nie wiem o jaki błąd ci chodzi. Po prostu chcę pobrać liczbę ze string (dowolna ilość cyfr) i zamienić ją na int.
Rafbeam
WYJŚCIE: (koniec linii oznaczony średnikiem); LINE: line; option << " = " << value; LINE: #GAME CLIENT CONFIGURATION FILE; LINE: #DO NOT CHANGE ANY CONTENTS OF THIS FILE; LINE: ; LINE: #########################################; LINE: #ONLY FOR PEOPLE WHO KNOW WHAT TO DO HERE; LINE: #########################################; LINE: ; LINE: #BEGIN; LINE: ; LINE: fullscreen=1; fullscreen = 1 LINE: width=0; width = 0 LINE: height=0; height = 0 LINE: vsync=0; vsync = 0 LINE: ; LINE: #END;
YooSy
'Nie wiem o jaki błąd ci chodzi.' - pobierasz jeden wiersz, a jednym obiegu pętli obsługujesz ten wiers, jakby była pobrana całość z pliku. Wypisuj kontrolnie dane lub używaj debuggera.
Rafbeam
  • Rejestracja:ponad 7 lat
  • Ostatnio:około 5 lat
  • Postów:44
0

Mógłbym też zrobić:

Kopiuj
int index = value.length()-1;
int n = 1;
int num = 0;
while(index >= 0)
{
     num += (value[index] - '0')  *  n;
     n *= 10;
     index--;
}

Tylko czy da się to zrobić krótszym kodem, bardziej czytelnym?

Rafbeam
Tzn. Jedną funkcją na przykład. (z jakiejś biblioteki)
Rafbeam
I jak to zmodyfikować, żeby odbierało także float'y, bez dużej ilości kodu?
fasadin
  • Rejestracja:prawie 14 lat
  • Ostatnio:prawie 3 lata
  • Postów:4882
0

najpierw uwstaw strumien za #begin (znajdz gdzie jest a nastepnie uzyj http://www.cplusplus.com/reference/istream/istream/seekg/)
pozniej uzyj std::map<string, int> i wczytuj linia po linii (najlepiej jakbys mial spacje w pliku bo wtedy nie musialbys parsowac stringa, bo operator >> wczyta po prostu nastepne slowo)
a parsowac stringa to chyba potrafisz ;)

MarekR22
Moderator C/C++
  • Rejestracja:ponad 17 lat
  • Ostatnio:4 minuty
0
Kopiuj
const std::String BeginOptionsMark = "#BEGIN";
const std::String EndOptionsMark = "#End";

std::unordered_map<std::string, int> LoadConfiguration(std::istream& input)
{
     std::string line;
     while (std::getline(input, line)) {
          if (line == BeginOptionsMark) {
               break;
          }
     }
     std::unordered_map<std::string, int> result;
     while (std::getline(input, line)) {
          if (line == EndOptionsMark) {
               break;
          }
          std::istringstream data { line };
          std::string name;
          int value;
          data >> std::ws;
          if (std::getline(data, name, '=') >> value) {
                if (name[0] != StartCommentChar) {
                    result[name] = value;
                }
          } else {
                if (name[0] != StartCommentChar) {
                    std::cerr << "Unexpected entry: " << line << '\n';
                }
          }
     }
     return result;
}


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 1x, ostatnio: MarekR22
Rafbeam
  • Rejestracja:ponad 7 lat
  • Ostatnio:około 5 lat
  • Postów:44
0

A czy tak będzie dobrze?

Kopiuj
    std::string option = "";
    int value = 0;
    std::ifstream cfg("game.cfg");
    if(cfg.is_open())
    {
        while(!cfg.eof())
        {
            cfg >> option >> value;

            std::cout<<option<<" = "<<value<<"\n";
        }
        cfg.close();
    }

Jak tutaj można w prosty sposób zaimplementować pomijanie pustych linii i komentarzy zaczynających się od '#' (jednoliniowych)?

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.