MatthewPL Posted January 25, 2011 Report Share Posted January 25, 2011 Więc mam taki program na zaliczenie, jeszcze nie sprawdzony. Ogólnie wszystko co ma być to chyba jest, tylko poprawiłbym w nim parę rzeczy a nie wiem za bardzo jak. Po pierwsze, nie ma mowy o użyciu tablic. Wcześniej trzeba stworzyć plik z zawartością. Jedna rzecz to: jak wczytuję plik gdzie każda liczba, litera lub słowo jest w oddzielnej linijce to przy wypisywaniu liczb zostają puste linie tam gdzie były litery. Niby ok, ale trochę brzydko wygląda i nie wiem jak to zlikwidować. Wydaje mi się, że problem tkwi w sposobie, który rozwiązuje problem i nie jest on chyba najlepszy bo jeśli w pliku będzie liczba zapisana w postaci 1e3, to e zostanie pominięte (chyba, że zrobię wyjątek). Da radę coś z tym zrobić czy muszę pisać od nowa innym sposobem? Jestem początkujący, a ktoś zaawansowany pewnie poradziłby sobie bez problemu. //--------------------------------------------------------------------------- #include <vcl.h> //w Dev-C++ jest blad w tym miejscu (?), usunac #pragma hdrstop #include <conio.h> #include <iostream.h> #include <fstream.h> //--------------------------------------------------------------------------- #pragma argsused void zapis() { //zapisanie liczb rzeczywistych z pliku do nowego pliku char liczba; ofstream zapis; ifstream odczyt; odczyt.open("plik.txt",ios::in); //plik z zawartoscia, musi byc przed uruchomieniem zapis.open("liczby.txt",ios::out); //plik, w ktorym sa zapisywane liczby while ((liczba=odczyt.get())!=EOF) //dopoki wczytywany znak nie jest znakiem konca pliku { if ((liczba>=48) && (liczba<=57) || (liczba==46) || (liczba==45) || (liczba==32) || (liczba==10)) //jesli kod ASCII znaku jest kodem cyfry, -, ., spacji lub entera zapis<<liczba; //zapisanie do pliku } odczyt.close(); zapis.close(); } void odczyt() { //odczyt z pliku i wybranie liczb rzeczywistych char liczba1, liczba2; ofstream zapis; ifstream odczyt1,odczyt2; odczyt1.open("plik.txt",ios::in); //do odczytania calego pliku odczyt2.open("plik.txt",ios::in); //do odczytania liczb rzeczywistych zapis.open("liczby.txt",ios::out); //do zapisania liczb rzeczywistych if (!odczyt1) //sprawdzenie istnienia pliku do odczytu { cerr<<"\nBrak pliku do odczytu."; getch(); exit( 1 ); } cout<<"\n"<<"To jest zawartosc pliku:\n"; while ((liczba1=odczyt1.get())!=EOF) //dopoki wczytywany znak nie jest znakiem konca pliku cout<<liczba1; //wypisanie zawartosci pliku cout<<"\n\nTo sa liczby rzeczywiste z pliku:\n"; while ((liczba2=odczyt2.get())!=EOF) //dopoki wczytywany znak nie jest znakiem konca pliku if ((liczba2>=48) && (liczba2<=57) || (liczba2==46) || (liczba2==45)|| (liczba2==32) || (liczba2==10)) //jesli kod ASCII znaku jest kodem cyfry, -, ., spacji lub entera cout<<liczba2; //zapisanie liczb do pliku cout<<"\n\n"; odczyt1.close(); odczyt2.close(); zapis.close(); } int menu() { //menu glowne programu int o; cout<<"Wybieranie liczb rzeczywistych z pliku tekstowego\n\n"; cout<<"1: Odczyt z pliku\n0: Koniec\nWybieram: "; cin>>o; return o; } int main(int argc, char* argv[]) { int b, o=menu(); while (o!=0) { switch(o) // menu z opcja zapisu do pliku { case 1: { odczyt(); cout<<"Zapisac do pliku?\n1: tak\n0: nie\nWybieram: "; cin>>b; switch (b) { case 1: { zapis(); system("cls"); cout<<"Zapisano do pliku \"liczby.txt\"\n\n"; break; } case 0: system("cls"); break; } break; } } o=menu(); } return 0; } //--------------------------------------------------------------------------- Link to comment Share on other sites More sharing options...
[Ekspert] Mormegil Posted January 25, 2011 Report Share Posted January 25, 2011 Treść zadania? Link to comment Share on other sites More sharing options...
MatthewPL Posted January 25, 2011 Author Report Share Posted January 25, 2011 dokładnie tak jak w temacie Link to comment Share on other sites More sharing options...
[Ekspert] Mormegil Posted January 25, 2011 Report Share Posted January 25, 2011 Żartujesz? int wybierz_liczbe(std::fstream & plik, unsigned int indeks, double & wynik) { plik.seekg(0, std::fstream::end); const unsigned int rozmiar = plik.tellg(); plik.seekg(0, std::fstream::beg); const unsigned int pozycja = indeks * sizeof(double); if (rozmiar <= pozycja + sizeof(double)) { return -1; } plik.seekg(pozycja, std::fstream::beg); plik.read(&wynik, sizeof(double)); return 0; } Link to comment Share on other sites More sharing options...
MatthewPL Posted January 25, 2011 Author Report Share Posted January 25, 2011 co do treści zadania to jeszcze zapisywanie tych liczb do innego pliku, a w tej funkcji daje mi dwa błędy: Cannot convert 'double*' to 'char*' i Type mismatch in parameter '__s' (wanted 'char *', got 'double *') po za tym nie za bardzo wiem co z tym zrobić bo zbyt wiele ten kod mi nie mówi , jak wywołać funkcję (jakie parametry) i gdzie się określa wczytywany plik, no nie jestem w tym za bardzo biegły, ech (używam C++ Builder 6) Link to comment Share on other sites More sharing options...
[Ekspert] Mormegil Posted January 26, 2011 Report Share Posted January 26, 2011 Cannot convert 'double*' to 'char*' i Type mismatch in parameter '__s' (wanted 'char *', got 'double *')Metoda read przyjmuje parametr typu char *, a ja przekazałem double *. Trzeba zrobić rzutowanie typu wskaźnika: (char *) po za tym nie za bardzo wiem co z tym zrobić bo zbyt wiele ten kod mi nie mówi ,To jest odczyt wartości typu double znajdującej się na wskazanej pozycji w pliku binarnym. Skoro treść zadania nie narzuca formy pliku, to moim zdaniem najprościej jest używać właśnie plików binarnych. EDIT: Tak właśnie przeczytałem treść zadania drugi raz i jest wyraźnie podane, że ma być plik tekstowy. Tak, nie ma to jak uważne czytanie. W takim razie, trzeba będzie nieco inaczej to rozwiązać. END jak wywołać funkcję (jakie parametry) i gdzie się określa wczytywany plik,Parametry to chyba masz podane, prawda? 1. strumień pliku, w zasadzie mógłby tutaj być dowolny strumień wejściowy, 2. indeks/Pozycja/Numer liczby którą chcesz odczytać ze strumienia wejściowego, 3. zmienna typu double do której ma zostać zapisana odczytana z pliku wartość. Funkcja zwraca 0, gdy uda jej się odczytać zadaną wartość, w przeciwnym razie zwraca wartość nie zerową. co do treści zadania to jeszcze zapisywanie tych liczb do innego pliku,No przecież treść zadania brzmi: "Wybieranie z pliku tekstowego liczb rzeczywistych". Nie było mowy o zapisie. Zapis binarny jest podobny do odczytu. Zamiast obiektu std::istream i metody read potrzebujesz std::ostream i metody write. Do przesuwania i pobierania pozycji służą seekp i tellp. Jeżeli plik jest za krótki, to trzeba by go przed zapisem przedłużyć, myślę, że najlepiej wypełnić zerami. int zapisz_liczbe(std::ostream & plik, unsigned int indeks, double & wartosc) { plik.seekp(0, std::ostream::end); const unsigned int rozmiar = plik.tellp(); const unsigned int pozycja = indeks * sizeof(double); if (rozmiar <= pozycja) { double temp = 0; for (unsigned int i = rozmiar; i < pozycja; i += sizeof(double) ) { plik.write((char *) &temp, sizeof(double)); } } plik.seekp(pozycja, std::ostream::end); plik.write((char *) &wartosc, sizeof(double)); return 0; } Link to comment Share on other sites More sharing options...
[Ekspert] Mormegil Posted January 28, 2011 Report Share Posted January 28, 2011 Nagłówki#include <fstream> #include <iostream> #include <string> #include <sstream> Pobranie wskazanej wartości double ze strumieniaint GetDoubleValueFromStream(std::istream & in, unsigned int index, double & val) { std::string line; in.clear(); in.seekg(0, std::istream::beg); for (unsigned int i = 0; i <= index; ++i) { std::getline(in, line); if (false == in.good()) { return -1; } } std::stringstream str(line); str >> val; return 0; } Skopiowanie wartości double ze strumienia do strumieniaint CopyDoubleValuesFromStreamToStream(std::istream & in, std::ostream & out) { double val; std::string line; in.clear(); in.seekg(0, std::istream::beg); while (1) { std::getline(in, line); if (false == in.good()) { break; } std::stringstream str(line); str >> val; out << val << std::endl; } return 0; } Przykład użyciaint main() { //Open files std::fstream input("test.txt", std::fstream::in); if (false == input.is_open()) { system("pause"); return -1; } std::fstream output("out.txt", std::fstream::out); if (false == output.is_open()) { system("pause"); return -1; } //Show contents of input file int result = CopyDoubleValuesFromStreamToStream(input, std::cout); //Get first and second value from input double val; result = GetDoubleValueFromStream(input, 0, val); std::cout << val << "@" << result << std::endl; result = GetDoubleValueFromStream(input, 1, val); std::cout << val << "@" << result << std::endl; //Copy input file to output file CopyDoubleValuesFromStreamToStream(input, output); system("pause"); return 0; } Przykładowy plik z danymi-123.123 -123e-2 123.123 Link to comment Share on other sites More sharing options...