Operacja na plikach: tworzenie wielu nazw plików

0

W Projekcie mam pliku nazwane Gracz0.txt, Gracz1.txt, itd...
Chciałbym wczytywać dane z tych plików. Utworzyłem więc funkcję która ma za zadanie tworzyć nazwy tych plików do wczytania i do zapisywania.

 
    const char * UtworzNazwePliku(int nr) // taki typ zwracany  jest potrzebny do operacji na plikach
    {
        char  pomocnicza[5]; // na max 5 cyfrowe liczby
        string  nazwa = "Gracz";
        nazwa += itoa(nr , pomocnicza, 10); // konwersja  int na string, 
        nazwa += ".txt";
        cout << nazwa.c_str() << endl;
        return  nazwa.c_str();// c_str() konwersja z string na const char
    }

Wywołując tą funkcję w taki sposób:

 plik.open(UtworzNazwePliku(0), ios::in);

Dane nie są wczytywane.
Natomiast jeżeli podam bezpośrednio nazwę:

plik.open("Gracz0.txt", ios::in);

wszystko działa poprawnie, dodatkowo na ekranie widać poprawną nazwę

Pytania:

  1. Czy ma to coś związek z Typem string i znakiem zera na końcu?
  2. Czy jest możliwość, przeprowadzenia konwersji bez tej pomocniczej tablicy ?
2

zgodnie co pokazuja tutaj
http://www.cplusplus.com/reference/fstream/fstream/open/
powinienes moc przekazac stringa jako parametr. Wiec problemu nie powinno byc.

nazwa += to_string(nr);
http://www.cplusplus.com/reference/string/to_string/

do tych dwoch podpunktow wymagany jest c++11

a nie dziala dalego bo zwracasz wynik LOKALNEJ zmiennej ktora jest niszczona po jej wyjsciu (zapewne)

2

Nie używaj itoa jak nie musisz, tej funkcji nie ma w standardzie.

Tę całą funkcję można zastąpić

string("Gracz" + to_string(nr) + ".txt").c_str()

albo tak jak @fasadin napisał, nawet c_str() nie jest potrzebne.

0

dodatkowo

  char  pomocnicza[5]; // na max 5 cyfrowe liczby

to raczej max 4 cyfry...

0

Wygląda na to, że czym predzej musze przerzucić się na C++11, bardzo ułatwia życie.

a nie dziala dalego bo zwracasz wynik LOKALNEJ zmiennej ktora jest niszczona po jej wyjsciu (zapewne)
W uproszczeniu sprawa wygląda tak:

const char * UtworzNazwePliku(int nr) // taki typ zwracany  jest potrzebny do operacji na plikach
    {
        string nazwa ="Gracz0.txt";
        //return "Gracz0.txt"; // Dziala na ekranie pojawia sie 1
        //return  nazwa.c_str();// Nie dziala na eranie pojawia sie 0
    } 
 
    void WczytanieGraczyZPliku()
    {
        int ilsocWczytanychGraczy=0;
        fstream plik;
        for(int i=0; ; i++) // dla kazdego Gracza do ktorego znajdziemy plik, //
        {
            plik.open(UtworzNazwePliku(0), ios::in);
            if(!plik.good()) // jezeli nie udalo sie otworzyc pliku, znaczy ze juz wiecej  plikow z graczami nie ma
            {
                cout << "Wczytano  graczy: " <<  ilsocWczytanychGraczy << endl;
                break;
            }
            else
                ilsocWczytanychGraczy++;
        }
        plik.close();
    }

ale nadal gdy zwracam:

 nazwa.c_str()

nie działa, a dla przypadku

 return "Gracz0.txt";

śmiga...

1
string UtworzNazwePliku(int nr) // taki typ zwracany  jest potrzebny do operacji na plikach
{
        string nazwa ="Gracz0.txt";
        return nazwa;
} 
...
plik.open(UtworzNazwePliku(0).c_str(), ios::in);
0

działa, ale nie rozumiem dlaczego przez zwracany typ "const char *" funkcji wystąpił ten problem. Myślałem nad tym aby kwestie konwersję załatwić w funkcji, bo tak jest mało czytelne :)

0

@fasadin Ci napisał, w pierwszej wersji masz lokalny std::string, który zostaje zniszczony po wyjściu z funkcji, więc to co zwracasz też przestaje istnieć.

Natomiast jeśli robisz

return "Gracz10.txt";

to zwracasz literał, który nie jest zmienną lokalną i ma inny czas życia.

1 użytkowników online, w tym zalogowanych: 0, gości: 1