Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Problem z zadaniem z kwotami rozliczeń

Ostatnio zmodyfikowano 2023-09-10 22:11
Autor Wiadomość
tybik843
Temat założony przez niniejszego użytkownika
Problem z zadaniem z kwotami rozliczeń
» 2023-09-07 15:18:18
Cześć mam problem z zadaniem oto jego treść,,
Organizacja plików: Wszystkie pliki oddawane do sprawdzenia należy zapisać we wspólnym folderze o nazwie będącej
numerem indeksu, umieszczonym na pulpicie. Oddajemy tylko źródła programów (pliki o rozszerzeniach .cpp i .h)!!!
Napisać pomocnicze biblioteki oraz program główny dla następującego zadania:
Centralna Policja Podatkowa raz w roku kontroluje zeznania podatkowe obywateli Fiskustanu. Lista
podatników nazywa się "podatnicy.txt" i zawiera ich dane uporządkowane rosnąco wg nazwiska
i dalej imienia w formacie (kolejne linie):
C/C++
NIP( 10 - cyfrowy numer identyfikacji podatkowej )
Nazwisko Imie( oddzielone odstepem )
< /
pusta linia >
Plik z rozliczeniami podatników nazywa się "rozliczenia.txt" i zawiera liczbę linii zgodną z liczbą
podatników. Każda linia zawiera kwotę rozliczenia odpowiadającego jej podatnika zapisaną
z dokładnością do 2 miejsc dziesiętnych, np.:
C/C++
195.67
0.00
- 312.50
Kwoty rozliczeń mogą być liczbami dodatnimi (niedopłaty podatku), ujemnymi (nadpłaty) lub
zerami (podatek rozliczony). Należy wydrukować do pliku "wyniki.txt" listę zawierającą dane
podatników wraz z odpowiadającymi im kwotami rozliczenia, uporządkowaną malejąco wg
nazwiska i dalej imienia podatnika, w następującym formacie (kolejne linie):
C/C++
Nazwisko
Imie
NIP( numer identyfikacji podatkowej )
Kwota rozliczenia( zaokraglona doliczby calkowitej )
Wymagania formalne:
Program powinien być zapisany w trzech plikach: kontener.h, dane.h i glowny.cpp (wolno rozbić
kontener na kontener.h i kontener.cpp, podobnie z dane.h i dane.cpp).
W pliku dane.h należy umieścić strukturę implementującą dane przetwarzane w programie,
przechowywane w kontenerze, wraz z odpowiednimi metodami. Tu powinny znaleźć się też
wszystkie pomocnicze funkcje, sprawdzające poprawność danych (na przykład poprawność numeru
NIP). Nie należy umieszczać w tym pliku funkcji formatujących dane do wydruku, ani żadnych
innych funkcji używających operacji wejścia-wyjścia.
W pliku kontener.h należy umieścić strukturę odpowiadającą użytemu abstrakcyjnemu typowi
danych. Można użyć szablonu lub konkretnej struktury z typem elementu odpowiadającym
strukturze zbudowanej w pliku dane.h. Należy umieścić w kontenerze i implementować tylko te
metody, które będą używane w programie głównym. Implementacja nie może zależeć od typu
elementu, powinna działać tak samo po zmianie tego typu na jakikolwiek inny. Nie może też być tu
żadnych operacji wejścia wyjścia ani formatowania wydruku kontenera.
W pliku glowny.cpp umieszczamy program główny korzystający z plików kontener.h i dane.h oraz
funkcje formatujące wydruk i inne funkcje korzystające z operacji wejścia-wyjścia.
Niedozwolone jest korzystanie z kontenerów i algorytmów z biblioteki standardowej C++.
Zapisu do pliku wynikowego nie wolno rozpocząć przed odczytaniem całości plików
wejściowych.

Dodatkowe punkty:
Za obsługę wejścia odporną na błędy użytkownika i za poprawne komentarze, w tym w
bibliotekach pomocniczych: cel funkcji, warunki wstępne, warunki końcowe, sytuacje wyjątkowe
i ewentualnie zwracany wynik, przyznawane będą dodatkowe punkty. Obsługa wejścia odporna na
błędy użytkownika powinna wyglądać następująco:
• w przypadku gdy niepoprawne są dane podatnika (czyli nieprawidłowość wystąpiła w pliku
podatnicy.txt), podatnik ten nie jest wpisywany do plik wynikowego, a odpowiadająca mu
linia w pliku rozliczenia.txt jest pomijana,
• w przypadku gdy dane podatnika są poprawne, a niepoprawna jest kwota rozliczenia (czyli
nieprawidłowość wystąpiła w pliku rozliczenia.txt), podatnik jest wpisywany do pliku
wynikowego, przy czym zamiast kwoty rozliczenia pojawia się adnotacja „DO
WERYFIKACJI”.
Kolejne punkty podwyższające ocenę można uzyskać zapewniając w programie obsługę
nieograniczonej liczby podatników zapisanych w plikach wejściowych oraz obsługę wielu imion
podatników podanych z odstępami w linii za nazwiskiem.
Dodatkowe punkty będą również przyznane za weryfikację poprawności numeru NIP. Ostatnia,
dziesiąta cyfra NIP jest cyfrą kontrolną obliczaną według poniższego algorytmu:

Pomnożyć każdą z pierwszych dziewięciu cyfr odpowiednio przez wagi: 6, 5, 7, 2, 3, 4, 5, 6, 7.
Zsumować wyniki mnożenia.
Obliczyć resztę z dzielenia przez 11 – powinna być ona zgodna z cyfrą kontrolną.
NIP jest tak generowany, aby nigdy w wyniku tego dzielenia nie wyszła liczba 10."

Oto mój kod
nip.h
C/C++
#ifndef NIP_H_INCLUDED
#define NIP_H_INCLUDED
#include<iostream>
#include<fstream>
#include<sstream>
#include<cstdlib>
#include<string>
#include<exception>
#include<stdexcept>
#include"kontener.h"
#include<algorithm>
#include<cmath>
#include<math.h>
using namespace std;
struct Podatnik
{
   
private:
   
   
string nazwisko;
   
string imie;
   
string NIP;
   
double kwota;
   
bool do_weryfiacji = false;
public:
   
   
Podatnik( string naz = " ", string im = " ", string p = " ", double k = 0.0, bool w = false )
   
{
       
nazwisko = naz;
       
imie = im;
       
NIP = p;
       
kwota = k;
       
do_weryfiacji = w;
   
}
   
   
void wstawPodatnika( string a, string b, string c, double d, bool e )
   
{
       
nazwisko = a;
       
imie = b;
       
NIP = c;
       
kwota = d;
       
do_weryfiacji = e;
   
}
   
   
void wypiszPodatnika()
   
{
       
cout << imie << " " << nazwisko << " " << NIP << " " << kwota << " " << do_weryfiacji << " , ";
   
}
   
string getNazwisko() { return nazwisko; }
   
string getImie() { return imie; }
   
string getNIP() { return NIP; }
   
double getKwota() { return kwota; }
   
bool getDoWeryfiacji() { return do_weryfiacji; }
   
bool operator <( const Podatnik & other ) const {
       
if( nazwisko == other.nazwisko )
           
 return imie < other.imie;
       
       
return nazwisko > other.nazwisko;
   
}
   
   
   
bool sumaKontrolna()
   
{
       
int pomoc = 0, suma = 0;
       
int pomocnicza[ 9 ] = { 6, 5, 7, 2, 3, 4, 5, 6, 7 };
       
for( int i = 0; i <= 9; i++ )
       
{
           
pomoc = NIP[ i ] * pomocnicza[ i ];
           
suma += pomoc;
           
pomoc = 0;
       
}
       
if( suma % 11 != 10 )
       
{
           
return true;
       
}
       
else
       
{
           
return false;
       
}
    }
}
;

struct Lista {
   
private:
   
   
struct Node {
       
       
Podatnik dane;
       
Node * nast;
       
Node( Podatnik d, Node * N = nullptr )
       
{
           
dane = d;
           
nast = N;
       
}
    }
;
   
   
Node * pocz;
   
   
int ileJest;
   
public:
   
Lista()
   
{
       
pocz = nullptr;
       
ileJest = 0;
   
}
   
   
~Lista()
   
{
       
Node * nowy = pocz;
       
while( nowy != nullptr )
       
{
           
Node * szuk;
           
szuk = nowy->nast;
           
delete nowy;
           
nowy = szuk;
       
}
    }
   
   
void wypisz()
   
{
       
Node * nowy = pocz;
       
while( nowy != nullptr )
       
{
           
nowy->dane.wypiszPodatnika();
           
nowy = nowy->nast;
       
}
    }
   
   
void wstaw( Podatnik p )
   
{
       
Node * nowy;
       
nowy = new Node( p );
       
if( pocz == nullptr )
       
{
           
pocz = nowy;
           
return;
       
}
       
else
       
{
           
Node * szuk = pocz;
           
while( szuk->nast != nullptr )
           
{
               
szuk = szuk->nast;
           
}
           
szuk->nast = nowy;
       
}
       
ileJest++;
   
}
   
   
void zapisz() {
       
ofstream wyniki_plik( "wyniki.txt" );
       
Node * nowy = pocz;
       
       
while( nowy != nullptr ) {
           
wyniki_plik << nowy->dane.getNazwisko() << endl;
           
wyniki_plik << nowy->dane.getImie() << endl;
           
wyniki_plik << nowy->dane.getNIP() << endl;
           
           
double roundedKwota = round( nowy->dane.getKwota() );
           
           
if( nowy->dane.getDoWeryfiacji() )
           
{
               
wyniki_plik << "Do weryfikacji: " << endl;
           
}
           
else
           
{
               
wyniki_plik << roundedKwota << endl;
           
}
           
wyniki_plik << endl;
           
           
nowy = nowy->nast;
       
}
       
       
wyniki_plik.close();
   
}
}
;
#endif  // NIP_H_INCLUDED
main.cpp
C/C++
#include"nip.h"
#include<iostream>
#include<fstream>
#include<sstream>
#include<istream>
#include<cstdlib>
#include<exception>
#include<stdexcept>
#include<string>
#include<math.h>
using namespace std;

int main()
{
   
   
string nazwa;
   
cout << "Podaj nazwe pliku: " << endl;
   
cin >> nazwa;
   
try {
       
ifstream plik;
       
plik.open( nazwa.c_str(), ios::in );
       
if( !plik.good() )
       
{
           
throw logic_error( "Plik nie dziala" );
       
}
       
string linia;
       
Lista lista;
       
while( getline( plik, linia ) ) {
           
Podatnik os;
           
string nazwisko = os.getNazwisko();
           
string imie = os.getImie();
           
string nip = os.getNIP();
           
double kwota = os.getKwota();
           
bool do_weryfiacji = os.getDoWeryfiacji();
           
nip = linia;
           
getline( plik, linia );
           
size_t pozycja = linia.find( ' ' );
           
nazwisko = linia.substr( 0, pozycja );
           
imie = linia.substr( pozycja + 1 );
           
getline( plik, linia ); // pusta linia
           
getline( plik, linia );
           
try {
               
kwota = stod( linia );
               
if( os.sumaKontrolna() ) {
                   
os.wstawPodatnika( nazwisko, imie, nip, kwota, do_weryfiacji );
               
}
            }
catch( invalid_argument ) {
               
if( os.sumaKontrolna() ) {
                   
kwota = 0;
                   
do_weryfiacji = true;
                   
os.wstawPodatnika( nazwisko, imie, nip, kwota, do_weryfiacji );
               
}
            }
        }
       
lista.wypisz();
       
lista.zapisz();
       
plik.close();
   
}
   
catch( exception & e )
   
{
       
cout << e.what() << endl;
   
}
   
   
return 0;
}
Powiem tak nie wiem gdzie się zgubiłem problem polega na tym iż po wpisaniu nazwy pliku np.podatnicy.txt nie wyświetla się jego zawartość przy podaniu nazwy błednej np podatnik.txt reaguje dobrze że plik nie działa na dodatek jak się wyświetli to pokazuje wartości na przykładzie podatnicy.txt np jan kowalski jakiś nip kwota i 1.e344242,1.e45353
(coś w tym stylu) jak to zrobić żeby 1.e344242,1.e45353 się nie wyświetlało nawet takich wartości w pliku nie ma więc nie wiem skąd one się biorą proszę o pomoc sprawdzeniu mojego kodu gdzie może być ten błąd i czy zrozumiałem zgodnie z treścią zadanie chce wiedzieć czy gdzieś w kodzie popełniłem błędy z góry dziękuje
P-180354
DejaVu
» 2023-09-07 17:06:53
C/C++
while( getline( plik, linia ) ) {
   
//...
   
Wewnątrz tego while na początku pętli wypisz na ekran zawartość zmiennej 'linia'. Wtedy będziesz widział czy cokolwiek z pliku się odczytuje czy nie i będziesz mógł szukać sobie miejsca błędu.

W każdym razie błąd widać na pierwszy rzut oka, tj. odczytujesz z obiektu 'os' dane podatnika, natomiast nie napisałeś kodu, który by wczytał najpierw dane do obiektu 'os' zanim zaczniesz je odczytywać.
P-180355
tybik843
Temat założony przez niniejszego użytkownika
» 2023-09-08 17:18:40
Poprawiłem co nieco i kod wygłada tak
C/C++
main.cpp
bool sumaKontrolna( string NIP );
int main()
{
   
string nazwa;
   
cout << "Podaj nazwe pliku: " << endl;
   
cin >> nazwa;
   
ifstream plik;
   
plik.open( nazwa.c_str(), ios::in );
   
Podatnik os;
   
Lista lista;
   
try {
       
if( !plik.good() )
       
{
           
throw logic_error( "Plik nie dziala" );
       
}
       
string nazwisko = os.getNazwisko();
       
string imie = os.getImie();
       
string nip = os.getNIP();
       
double kwota1 = os.getKwota();
       
string kwota = to_string( kwota1 );
       
bool do_weryfiacji = os.getDoWeryfiacji();
       
size_t counter = 0;
       
string linia;
       
while( getline( plik, linia ) ) {
           
getline( plik, linia );
           
size_t pozycja = linia.find( ' ' );
           
nazwisko = linia.substr( 0, pozycja );
           
imie = linia.substr( pozycja + 1 );
           
getline( plik, linia ); // pusta linia
           
getline( plik, linia );
           
switch( counter ) {
           
case 0: imie = linia; break;
           
case 1: nazwisko = linia; break;
           
case 2: nip = linia; break;
           
case 3: kwota = linia; break;
           
default:
               
break;
           
}
           
counter++;
           
if( counter > 3 )
               
 counter = 0;
           
           
try {
               
kwota = stod( linia );
               
if( sumaKontrolna( nip ) ) {
                   
os.wstawPodatnika( nazwisko, imie, nip, kwota1, do_weryfiacji );
                   
lista.wstaw( os );
               
}
            }
catch( invalid_argument ) {
               
if( sumaKontrolna( nip ) ) {
                   
kwota1 = 0;
                   
do_weryfiacji = true;
                   
os.wstawPodatnika( nazwisko, imie, nip, kwota1, do_weryfiacji );
                   
lista.wstaw( os );
               
}
            }
        }
       
lista.wypisz();
       
lista.zapisz();
       
plik.close();
   
}
   
catch( exception & e )
   
{
       
cout << e.what() << endl;
   
}
   
return 0;
}
bool sumaKontrolna( string NIP )
{
   
int pomoc = 0, suma = 0;
   
int pomocnicza[ 9 ] = { 6, 5, 7, 2, 3, 4, 5, 6, 7 };
   
for( int i = 0; i <= 9; i++ )
   
{
       
pomoc = NIP[ i ] * pomocnicza[ i ];
       
suma += pomoc;
       
pomoc = 0;
   
}
   
if( suma % 11 != 10 )
   
{
       
return true;
   
}
   
else
   
{
       
return false;
   
}
}

co prawda on odczytuje zawartość pliku ale po odczytaniu pliku dodatkowo wyświetla 0 i 1 pytanie gdzie jeszcze mogłem popełnić błąd??
P-180365
pekfos
» 2023-09-10 22:11:31
Jeśli wczytanie danych podatnika wymaga 4 obiegów pętli, czemu próbujesz dodać podatnika przy każdym obiegu?
P-180373
« 1 »
  Strona 1 z 1