1.Odczyt danych z pliku i wyświetlenie, 2.Czyszczenie ostatniej linii w konsoli.

0

Witam!
Nie bardzo wiedziałem jaki tytuł nadać temu wątkowi.
Problem polega na tym że chciałbym zrobić tak:

  1. Wczytać dane z pliku.
  2. W pliku są trzy linie tekstu 1 to imię , a 2 to nazwisko 2 to nr konta.
  3. Jedną linię wczytać do tablicy char imie[20]
    4.Drugą linię do tablicy char nazwisko[50]
  4. Trzecią do tablicy char nr_konta[20]

Chciałbym żeby to było zrobione na klasie "konto".
Robię bankomat i ma opcje "dane konta"
W main.cpp chciałbym po prostu wpisać
cout<<imie<<endl;
cout<<nazwisko<<endl;
cout<<nr_konta<<endl;
i mieć wyświetlone na ekranie te dane.

Mam nadzieję, że dobrze wytłumaczyłem o co mi chodzi.

Mam jeszcze jedno pytanie czy jest możliwość czyszczenia ostatniej linii w konsoli.
[code]
int i,j;
std::cout<<"cos"<<std::endl;//chcę żeby po naciśnięciu enter ta linijka
std::cin>>i;//oraz ta została wyczyszczona
std::cout<<"cos2"<<std::endl;
std::cin>>j;
[/code]

1

Do operacji na plikach tekstowych wykorzystuje się bibliotekę "fstream".

http://www.cplusplus.com/reference/iostream/fstream/
http://cpp0x.pl/kursy/Kurs-C++/Obsluga-plikow/305
http://cppzone.host.sk/html/kursc++/lekcja14.html

#include <fstream>

Stwórz tablicę na tekst

char tekst[100];

Aby zapisać tekst do pliku:

int zapis_do_pliku()
{
     ofstream outFile; //outFile jest twoją własną nazwą (jest to twój uchwyt do pliku)
     outFile.open("plik.txt"); //plik.txt jest nazwą pliku. W przypadku gdy plik nie znajduje się w folderze z programem podać musisz pełną ścieżkę.
     outFile << tekst; //nadpisujesz plik podanym tekstem
     outFile.close(); //zwalniasz uchwyt
}

Aby odczytać z pliku całą linię:

int odczyt_z_pliku()
{
     ifstream inFile();
     inFile.open("plik.txt");
     inFile.getline(tekst,100); //wczyta z pliku do tablicy tekst do napotkania znaku '\n' lub wczytania 100 znakow.
     inFile.close();
}

cin >> tekst zapisze ci tekst do napotkania znaku ' ', natomiast jeżeli chcesz zapisać z wejścia całą linijkę to wtedy użyj getline()

cin.getline(Bufor, dlugosc);
//Bufor - tablica znakow
//dlugosc - rozmiar tej tablicy

I do czyszczenia całej konsoli: system("cls");

1

Co do pytania 1: fstream Twoim przyjacielem:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>

int main()
{
    std::vector<std::string> input;

    char[] fname = "plik.txt";
    std::ifstream fin("plik.txt");

    if (!fin.is_open())
    {
        std::cerr << "Nie mozna otworzyc pliku " << fname << " do odczytu.\n";
        return 1;
    }

    std::string line;
    while (std::getline(fin, line))
        input.push_back(line);
    fin.close();

    // w wektorze input znajduja sie kolejne linie z pliku

    // ...

    return 0;
}

W Twoim przypadku wektor jest niekoniecznie potrzebny, możesz zrobić po prostu tak:

std::string imie, nazwisko, nr_konta;

std::getline(fin, imie);
std::getline(fin, nazwisko);
std::getline(fin, nr_konta);

std::cout << imie << "\n";
std::cout << nazwisko << "\n";
std::cout << nr_konta << std::endl;

Co do pytania 2: Zainteresuj się biblioteką NCurses. Za pomocą samej biblioteki standardowej C++ nie da się tego zrobić. Ewentualnie możesz spróbować użyć znaku \b, kodujący Backspace. Na przykład:

std::cout << "012345";
std::cout << "\b\b  "; // cofamy sie o 2 znaki i nadpisujemy je spacjami
// wynik na ekranie: 0123

Niestety, sposób z Backspace nie działa po przejściu do nowej linii.

0

Mam jeszcze jedno pytanie czy jest możliwość czyszczenia ostatniej linii w konsoli.

int i,j;
std::cout<<"cos"<<std::endl;//chcę żeby po naciśnięciu enter ta linijka
std::cin>>i;//oraz ta została wyczyszczona
std::cout<<"cos2"<<std::endl;
std::cin>>j;

Według:

Mam jeszcze jedno pytanie czy jest możliwość czyszczenia ostatniej linii w konsoli.

użyj znaków '\b' aby cofnąć kursor do początku wiersza, a następnie wypełnij spacjami cały wiersz.
Natomiast według:

int i,j;
std::cout<<"cos"<<std::endl;//chcę żeby po naciśnięciu enter ta linijka
std::cin>>i;//oraz ta została wyczyszczona
std::cout<<"cos2"<<std::endl;
std::cin>>j;

powinieneś wstawić przed

std::cout<<"cos2"<<std::endl;

system("cls"); Wyczyści Ci to konsole i wykona operację std::cout :)
Powinno to wyglądać mniejwięcej tak:

cout<<"tekst1"<<endl;
system("cls"); // czyści konsolę
cout<<"tekst2"<<endl; // na ekranie będzie teraz widoczny tylko ten napis
0

Jeżeli chodzi o pytanie 2 może wytłumaczę jaśniej polecenie system("cls") znam ale nie chcę go użyć bo czyści całą konsolę, ja potrzebuję wyczyścić jedną linię.
To jest menu bankomatu
[code]

                                WITAJ


    1 - Wyplata gotowki                             2 - Stan konta

    3 - Wydruk                                      4 - Wpłatomat

    5 - Zmiana pin                                  6 - Dane konta

1
podaj kwote do wyplaty : 34
wyplacono
wybierz opcje
3
Wyplacono: 34 zl
Stan konta po wyplaceniu: 4940
2
Stan twojego konta wynosi : 4940

//jak widać wszystkie operacje które dokonałem zostają na konsoli.
// mi chodzi o to że po naciśnięciu enter np. wciskam 1 i daję enter to cyferka 1 znika a w jej miejsce ukazuję się napis "podaj kwote do wyplaty" wpisuję kwotę 34 i enter wtedy napis "podaj kwote do wyplaty : 34" znika i w jego miejsce pojawiają się
wyplacono
wybierz opcje
wybieram 3 i enter wtedy "wyplacono wybierz opcje" itd; Z TYM ,ŻE NAPIS "WITAJ" ORAZ TO MENU ZOSTAJĄ
[/code]
Jeżeli nie da się to zrobić prostym sposobem to nie będę się bawił , jak mówiłem to miało by za zadanie po porostu uestetyczniać wygląd.

Pytanie 2:
Sposób który podał kolega rincewind zrobiłem tak:
[code]
void main()
{
string imie, nazwisko, nr_konta;
fstream fin;
fin.open("dane1.txt");
getline(fin, imie);
getline(fin, nazwisko);
getline(fin, nr_konta);
cout << imie << "\n";
cout << nazwisko << "\n";
cout << nr_konta << std::endl;
getchar();
}
[/code]
Fajnie działa, próbowałem też zrobić tak jak pokazał kolega gswidwa bo chcę to zrobić na tablicy a nie na stringach.
[code]
int main()
{
char imie[50];
char nazwisko[50];
char nr_konta[50];
ifstream fin();
fin.open("dane1.txt");
fin.getline(imie, 50);
fin.getline(nazwisko, 50);
fin.getline(nr_konta, 50);
fin.close();
cout << imie << "\n";
cout << nazwisko << "\n";
cout << nr_konta << std::endl;
getchar();
}
[/code]

ale to nie idzie są błędy.
[code]
1>------ Build started: Project: kolko krzyzyk, Configuration: Debug Win32 ------
1>Compiling...
1>kolko.cpp
1>d:\projekt\kolko krzyzyk\kolko krzyzyk\kolko.cpp(13) : error C2228: left of '.open' must have class/struct/union
1>d:\projekt\kolko krzyzyk\kolko krzyzyk\kolko.cpp(14) : error C2228: left of '.getline' must have class/struct/union
1>d:\projekt\kolko krzyzyk\kolko krzyzyk\kolko.cpp(15) : error C2228: left of '.getline' must have class/struct/union
1>d:\projekt\kolko krzyzyk\kolko krzyzyk\kolko.cpp(16) : error C2228: left of '.getline' must have class/struct/union
1>Build log was saved at "file://d:\Projekt\kolko krzyzyk\kolko krzyzyk\Debug\BuildLog.htm"
1>kolko krzyzyk - 4 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

[/code]

Co robię źle??

No i jak wspomniałem chciałbym to zrobić na klasie(chyba że źle mówię), ale wyjaśnię o co mi chodzi.
Chcę dwa pliki konto.h i konto.cpp

W konto.h

 
#pragma once
#include<iostream>

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;

class konto
{
public:
	char nazwisko[20]; 
	char imie[20]; 
	char nr_konta[20]; 
	konto(char*nazw,char*im,char*nr); 
};

W konto.cpp

 
#include "konto.h"

konto::konto(char *nazw, char *im, char *nr)
{
	char imie[50];
	char nazwisko[50];
	char nr_konta[50];
	ifstream fin();
	fin.open("dane1.txt");
	fin.getline(imie, 50);
	fin.getline(nazwisko, 50);
	fin.getline(nr_konta, 50);
	fin.close();	
}

A w main.cpp po prostu odwołać się tak że konto u1; cout<<u1.im<<u1.nazw<<u1.nr<<endl;

Ale się spisałem mam nadzieję ,że to przybliży wam mój problem.

2
ifstream fin();

Właśnie tu masz błąd. W ten sposób deklarujesz bezargumentową funkcję zwracającą obiekt ifstream. Prawidłowo powinno być:

ifstream fin; // bez nawiasow

Nie wiem, w jaki sposób chcesz zrobić to "na klasie", ale moja sugestia to konstruktor przyjmujący nazwę pliku, z którego należy wczytać dane:

#include <iostream>
#include <fstream>
#include <cstring>

using namespace std;
 
class konto
{
public:
    char nazwisko[20]; 
    char imie[20]; 
    char nr_konta[20]; 
    explicit konto(const char* filename);
    konto(const char* imie_, const char* nazwisko_, const char* nr_konta_);
};

konto::konto(const char* filename)
{
    ifstream fin;
    fin.open(filename);
    fin.getline(imie, 20); // wczytuje pola klasy
    fin.getline(nazwisko, 20);
    fin.getline(nr_konta, 20);
    fin.close();
}

konto::konto(const char* imie_, const char* nazwisko_, const char* nr_konta_)
{
    strncpy(imie, imie_, 20);
    strncpy(nazwisko, nazwisko_, 20);
    strncpy(nr_konta, nr_konta_, 20);
}

Edit Właściwie jeszcze ładniejszym wyjściem byłby konstruktor przyjmujący referencję do obiektu istream, w celu odseparowania sposobu przechowywania danych od samej struktury -- przekazując istream klasa konto nie musi się martwić, czy dane pochodzą z dysku, strumienia wejścia czy może po prostu łańcucha znaków. Można też przeciążyć operator>>, żeby możliwe było wczytywanie ze strumienia w standardowy, STL-owy sposób.

0

Z klasami chodzi mi o to że:

mam 3 pliki:

konto.h w którym zawarte jest:

#include <iostream>
#include <fstream>
#include <cstring>
 
using namespace std;
 
class konto
{
public:
    char nazwisko[20]; 
    char imie[20]; 
    char nr_konta[20]; 
    explicit konto(const char* filename);
    konto(const char* imie_, const char* nazwisko_, const char* nr_konta_);
}; 

konto.ccp

 #include "konto.h"


 konto::konto(const char* filename)
{
    ifstream fin;
    fin.open("dane.txt");
    fin.getline(imie, 20); // wczytuje pola klasy
    fin.getline(nazwisko, 20);
    fin.getline(nr_konta, 20);
    fin.close();
}
konto::konto(const char* imie_, const char* nazwisko_, const char* nr_konta_)
{
    strncpy_s(imie, imie_, 20);
    strncpy_s(nazwisko, nazwisko_, 20);
    strncpy_s(nr_konta, nr_konta_, 20);
}

main.cpp
w nim chcę zrobić tak że:
void main()
{
konto zmienna;
cout<<zmienna.imie<<endl;

}

kiedy próbuję skompilować to otrzymuję błąd tej treśći:
1>d:\projekt\bank\bank\main.cpp(153) : error C2512: 'konto' : no appropriate default constructor available

0

Ok. Zrobiłem działa jak należy.

0

Mam jeszcze jedno i ostatnie pytanie:
Mam kod wydawania pieniędzy:

struct Banknoty
{
       int nominal;
       int ilosc;
};

void pobierz_z_pliku(Banknoty * tab)
{

//plik tekstowy wygląda tak:
// nominał i ilość nominałów.
1 5
2 5
5 5
10 5
20 5
50 5
100 5
////////////////////////////
  fstream plik;

  plik.open("D:\\Projekt\\Bank\\konto1\\plik.txt");

  for(int i=0;i<7;++i)
  {
	  plik>>tab[i].nominal;
	  plik>>tab[i].ilosc;
		  
  }

  plik.close();
}

void pobierz_pieniadze(Banknoty * tab,int ile_pieniedzy)
{
     int suma = 0;
     
     for(int i=8;i>-1;--i)
     {
             while(tab[i].nominal+suma <= ile_pieniedzy && tab[i].ilosc > 0)
             {
                   suma += tab[i].nominal;
                   tab[i].ilosc = tab[i].ilosc - 1;
				   
				   
             }
             if((&(tab[i]))==(&(tab[0])) && suma != ile_pieniedzy)
             {
                 cout<<"Nie udalo sie wyplacic kwoty z dostepnych nominalow\n\n";
             }
             if((&(tab[i]))==(&(tab[0])) && suma == ile_pieniedzy)
             {
                 cout<<"Wyplacono zadana kwote \n";
             }
  
     }
}

void wypisz(Banknoty *tab)
{
     for(int i=0;i<7;++i) cout<<tab[i].nominal<<" "<<tab[i].ilosc<<"\n";
}
void main()
{
Banknoty * tab = new Banknoty [8];
	
    int kwota;
    pobierz_z_pliku(tab);
    cout<<"\n\n Przed pobraniem \n\n";
    wypisz(tab);
    
    cout<<"\n\n Jaka kwote chcesz wyplacic ??\n\n";
    cin>>kwota;
    
    pobierz_pieniadze(tab,kwota);
    cout<<"\n\n Po pobraniu \n\n";
    wypisz(tab);
}
 

Moje pytanie brzmi co zrobić żeby wyświetlić ile banknotów wydano??
Bo w kodzie wyświetla ile banknotów pozostało

0

Do struktury Banknoty dodaj sobie jeszcze pole int wydano. Na początku ustaw je na 0, a potem podczas wydawania, zamiast zmniejszać ilosc, zwiększaj wydano. Warunek pętli też musisz zmienić z tab[i].ilosc > 0 na tab[i].wydano < tab[i].ilosc.

Poza tym, co to za dziwności w Twoim kodzie się panoszą? (&(tab[i]))==(&(tab[0])) -- przecież to jest bardzo zaciemniona wersja warunku i == 0. O_o

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