• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Sortowanie liczb - optymalizacja

Aruba Cloud VPS - 50% taniej przez 3 miesiące!
0 głosów
616 wizyt
pytanie zadane 22 maja 2017 w C i C++ przez lukaszek98 Nowicjusz (120 p.)
edycja 22 maja 2017 przez lukaszek98

Witam! Zrobiłem program. Odczytuje on z pliku pierwszą liczbę (ile liczb będzie w danej linijce) i potem szczytuje liczby oddzielone spacją w jednej linijce i sortuje od najmniejszej do największej. Czy ktoś podpowie jak przekształcić program, zeby nie trzeba było podawać tej pierwszej wartości, jak zadeklarować wielkośc tablicy potrzebnej do przechowywania liczb dopiero po szczytaniu ich oraz gdzie powinienem użyć procedury xyz.close(); ?
KOD:
 


#include <iostream>
#include <fstream>


using namespace std;
int main()
{ifstream in;
ofstream out;
in.open("odczyt.txt");
out.open("zapis.txt");
if (in.good()==false)
{
    cout<<"Plik wejsciowy nie istnieje" << endl;
}
cout << "Sortowanie liczb z pliku" << endl;
    do{
                double T[100];
                int licznik;
    in >> licznik;
    for (int i2=0; i2<licznik; i2=i2+1)
    {
        in >> T[i2];
    }

    for ( int l=licznik-1; l>0; l--)
{
    for (int i1=0; i1<l; i1++)
    {
            if (T[i1]>T[i1+1])
        {
         double x=T[i1+1];
        T[i1+1]=T[i1];
        T[i1]=x;
}}}
    cout << "Liczby w kolejnosci od najmniejszej do najwiekszej: " << endl;
        for (int a=0; a<licznik; a=a+1)
            {
                cout << T[a];
                out << T[a];
                if (a!=licznik-1)
        {
            cout << ", " ;
            out << ", ";
        }}
        cout << endl;
        out << endl;
} while (!in.eof());

}


 

komentarz 22 maja 2017 przez vector Dyskutant (9,200 p.)
edycja 22 maja 2017 przez vector

Skoro wiesz, że liczby są oddzielone spacją możesz wczytać całą linię za pomocą std::getline rozdzielić łańcuch znaków względem spacji i przekonwertować to, co dostałeś na liczby, chociażby za pomocą std::istringstream.

Popraw wklejony kod z plain-textu to na C/C++. Przy okazji mógłbyś to sformatować, aby się dało czytać.

 

gdzie powinienem użyć procedury xyz.close(); ?

Po pierwsze metody, jeżeli już, po drugie po skończeniu używania strumienia.

1
komentarz 22 maja 2017 przez adrian17 Mentor (350,120 p.)

Po pierwsze metody, jeżeli już, po drugie po skończeniu używania strumienia.

Po trzecie, nie używać, bo po to jest destruktor.

komentarz 22 maja 2017 przez Wiciorny Ekspert (277,980 p.)
po pierwsze nie metoda, ale funkcja. Bo close, nie musi przynależeć do klasy :)  a dalej jw... ;]
komentarz 22 maja 2017 przez vector Dyskutant (9,200 p.)
edycja 22 maja 2017 przez vector
template <typename _CharT, typename _Traits>
class basic_fstream : public basic_iostream<_CharT, _Traits> {
    // ...
    
    /**
   *  @brief  Opens an external file.
   *  @param  __s  The name of the file.
   *  @param  __mode  The open mode flags.
   *
   *  Calls @c std::basic_filebuf::open(__s,__mode).  If that
   *  function fails, @c failbit is set in the stream's error state.
   *
   *  Tip:  When using std::string to hold the filename, you must use
   *  .c_str() before passing it to this constructor.
   */
    void open(const char *__s, ios_base::openmode __mode = ios_base::in | ios_base::out) {
	if(!_M_filebuf.open(__s, __mode))
	    this->setstate(ios_base::failbit);
	else
	    // _GLIBCXX_RESOLVE_LIB_DEFECTS
	    // 409. Closing an fstream should clear error state
	    this->clear();
    }
}

Z gcc 6.3.1 Jak dla mnie to jest metoda

 

@adrian17

Oczywiście masz rację z dekonstruktorem, lecz jeżeli nie robi się ręcznie close() lub flush() zaraz po skończeniu zapisywania do pliku nastąpi crash to prawdopodobnie na dysku nie pozostanie śladu po zapisie. Więc ręczne użycie close() ma sens. Przykład:

#include <fstream>

int main(void) {
    std::ofstream ofs("tmp.txt");
    ofs << "asd";
    // ofs.close();
    throw std::runtime_error("");
    return 0;
}

 

komentarz 23 maja 2017 przez lukaszek98 Nowicjusz (120 p.)
Nie za bardzo wiem jak podzielić tego stringa względem spacji na integery, ktoś podpowie?
komentarz 23 maja 2017 przez vector Dyskutant (9,200 p.)

Tutaj masz sensowne rozwiąznie na stackoverflow lub możesz użyć boosta.

komentarz 23 maja 2017 przez adrian17 Mentor (350,120 p.)
edycja 23 maja 2017 przez adrian17

@vector

to prawdopodobnie na dysku nie pozostanie śladu po zapisie

Dokładnie po to jest destruktor, że nawet jeśli stanie się np. wyjątek, to destruktor i tak się wykona i poprawnie zamknie plik.

Kod który wrzuciłeś gwarantuje, że plik będzie poprawnie zapisany.

komentarz 23 maja 2017 przez vector Dyskutant (9,200 p.)

To jak to wytłumaczysz ?

 

// Edit

Jak coś to gcc 6.3.1

komentarz 23 maja 2017 przez adrian17 Mentor (350,120 p.)

Ups, wpadka z mojej strony, niezłapane wyjątki to faktycznie szczególny przypadek o którym zapomniałem.

Ale w normalnym przypadku łapanego wyjątku taka gwarancja istnieje:

	try {
		std::ofstream f("stuff.txt");
		// cokolwiek, na przyklad
		// throw std::exception();
	} catch(...) {

	}

Dlatego czasem cały main() owija się dużym try/catchem.

komentarz 24 maja 2017 przez lukaszek98 Nowicjusz (120 p.)
Próbowałem skorzystać z funkcji stoi(), ale wyskakuje mi cały czas 'stoi was not declared in this scope', zaktualizowałem codeblocks do najnowszej wersji, w ustawieniach dałem opcję związaną z C++11, zainstalowałem webmingw i dalej nic :/ Ktoś podsunie pomysł?
komentarz 24 maja 2017 przez Wiciorny Ekspert (277,980 p.)

stoi nie jest wspierane przez stare kompilatory masz to napisane http://www.cplusplus.com/reference/string/stoi/ stąd nawet aktualizacja może nie pomóc. 

A dodałeś biblioteke nagłówkową? 

#include <string>  // w niej mamy std::stoi

 

komentarz 24 maja 2017 przez lukaszek98 Nowicjusz (120 p.)
Tak, dodałem :)
komentarz 24 maja 2017 przez lukaszek98 Nowicjusz (120 p.)
Czyli nie dam rady w codeblocks zamienić string na int?
komentarz 24 maja 2017 przez vector Dyskutant (9,200 p.)
Zawsze możesz napisać własną funkcję konwertującą std::string na int.
komentarz 24 maja 2017 przez lukaszek98 Nowicjusz (120 p.)
Chyba się na razie poddaje, bo nie wiem jak :/
komentarz 1 czerwca 2017 przez piotrek132 Obywatel (1,410 p.)

Spróbuj użyć

std::stoi( str )

gdzie str to konkretny wartość string

Zaloguj lub zarejestruj się, aby odpowiedzieć na to pytanie.

Podobne pytania

+1 głos
1 odpowiedź 164 wizyt
pytanie zadane 21 września 2020 w Matematyka, fizyka, logika przez spectral Nowicjusz (160 p.)
0 głosów
1 odpowiedź 375 wizyt
pytanie zadane 14 lutego 2018 w C i C++ przez Kurczak Użytkownik (940 p.)
0 głosów
0 odpowiedzi 409 wizyt
pytanie zadane 12 stycznia 2018 w C i C++ przez marcin_kub Obywatel (1,420 p.)

93,109 zapytań

142,088 odpowiedzi

321,611 komentarzy

62,450 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Wprowadzenie do ITsec, tom 1 Wprowadzenie do ITsec, tom 2

Można już zamawiać dwa tomy książek o ITsec pt. "Wprowadzenie do bezpieczeństwa IT" - mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy aż 15% zniżki! Dziękujemy ekipie Sekuraka za fajny rabat dla naszej Społeczności!

...