Walidator NIPów

0

Napisałem walidator NIPów, który powinien działać, jednak ma następujące problemy:

  • NIP to liczba 10-cyfrowa, a więc nie wiem jak zmieścić ją w jakiejkolwiek zmiennej liczbowej (największa jaką znam to long, ale zakres musi być przynajmniej od 1000000000 do 9999999999)
  • prawdopodobnie zrobiłem coś nie tak z warunkami

Bardzo proszę, by ktoś znający się na rzeczy przejrzał ten kod i powiedział mi co poprawić (zwłaszcza jak zapisać ten NIP w zmiennej)

// Walidator NIPów
#include <iostream>
using namespace std;
bool validate(long nip)
{
 int wagi[9]={7,6,5,4,3,2,7,5,6}; // Wagi do sprawdzania, podane w odwróconej kolejności
 int cyfry[10]; //Tablica dla cyfr NIPu
 int i,suma=0; // Zmienna pomocnicza, Suma ilorazu wag i cyfr nipu
 for (i=0;i==8;i++) // Zapisywanie cyfr NIPu do tablicy
 {
     cyfry[i]=nip%10; // Dodaje do tablicy pierwszą z prawej cyfrę NIPu,
                      // pierwsza cyfra NIPu jest cyfrą kontrolną, czyli cyfry[0] to cyfra kontrolna
     nip/=10; // Odcina dodanę liczbę z NIPu
 }
 for (i=1;i==8;i++) suma=suma+(wagi[i]*cyfry[i]); // Sumowanie, z pominięciem liczby kontrolnej
 if((suma%11)==cyfry[0]) return true;
 else return false;
}

int main () {
    long nip;
    cout<<"Podaj numer NIP: ";
    cin>>nip;
    if(validate(nip)==true) cout<<endl<<"Podany NIP "<<nip<<" jest poprawny.\n\n";
    else cout<<endl<<"Podany NIP "<<nip<<" NIE jest poprawny.\n\n";
system("pause");
}
0

użyj string'a do zapisu nipu , każdy znak traktuj jako (int)(string[znak]-'0'), a reszte licz wedlug algorytmu - chyba tyle

0

Na razie doszedłem do takiej formy programu, została mi do zrobienia część z obróbką linijki - niestety tej części już nie wiem jak zrobić, mam nadzieję, że ktoś pomoże, bo ja dopiero raczkuję w C :)

// Walidator NIPów v0.2
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
bool validate(long long nip)
{
 long long nip2=nip;
 int wagi[]={7,6,5,4,3,2,7,5,6}; // Wagi do sprawdzania, podane w odwróconej kolejności
 int cyfry[9]; //Tablica dla cyfr NIPu
 int i=0,ck,dlugosc=0,suma=0; // Zmienna pomocnicza, Cyfra kontrolna, Dlugosc NIPu, Suma iloczynow wag i cyfr NIPu
 while(nip2>0) // Sprawdzanie dlugosci NIPu
 {   nip2/=10;     dlugosc++; }
if(dlugosc!=10) { cout<<"Podany NIP jest za krotki badz za dlugi (musi miec 10 cyfr.)\n";
} 
 ck=nip%10; nip/=10; // Odcinianie cyfry kontrolnej z NIPu
 while(i<9)
 {
     cyfry[i]=(nip%10);                  
     nip=(nip/10); 
     suma=suma+(wagi[i]*cyfry[i]); 
     i++;
 }
 if((suma%11)==ck) return true;
 else return false;
}

int main () {
    float wersja=0.2;  // Wersja programu
    string nazwaPliku="NIP.txt"; string nip[256]; // Deklaracja zmiennych
    string id[256]; string line;  
    int i=0, linijki=0;
    int bledy_licznik=0; int bledy_ktore[256];
    
    cout<<"Walidator NIP'ow, wersja v"<<wersja<<endl;
    cout<<"Domyslna nazwa pliku do analizy do analizy to: "<<nazwaPliku<<endl<<endl;
    
    ifstream plik("NIP.txt");  // Otwieranie strumienia pliku
    if (plik.is_open())  // Sprawdzenie czy plik jest otwarty
    {
      while (getline(plik,line)) linijki++;  // Zliczanie linijek w pliku
      while (!plik.eof() ) // Pętla, dopóki nie osiągnie końca pliku
      {
        getline(plik,line);
        if(line.size()==21)
        {
        /*
        
        Tutaj musi znaleźć się: 
        - Dzielenie linijki na dwa tokeny - id i nip
        - dodanie id do tablicy id[i] oraz dodanie nip do tablicy nip[i]
        - sprawdzenie nip[i] za pomocą funkcji validate(nip)
        - jeśli NIP jest niepoprawny, dodanie jego numeru do tablicy bledy_ktore[i]
          i zwiększenie bledy_licznik o 1.    
        
        */
        }
      }
      plik.close();
    } 
    if(bledy_licznik>0)
    {
      i=0;
      ofstream plik2("NIP_bledne.txt");
      if (plik2.is_open())
      {
        plik2<<"Znaleziono "<<bledy_licznik<<" blednych numery/ow NIP:\nID        NIP\n";
        while(i<=bledy_licznik) { plik2<<id[i]<<"  "<<nip[i]<<"\n"; i++ }
        plik2.close();   
      }
    cout<<"Znaleziono "<<bledy_licznik<<" blednych numery/ow NIP.\n";
    cout<<"Bledne numery zostaly zapisane do pliku NIP_bledne.txt\n\n";
    }
    else cout<<"Nie znaleziono blednych numerow NIP\n\n";
system("pause");
}

Przykładowy plik, który program powinien przerobić, wygląda tak:

07.05.2010 Dynamiczne wyprowadzanie listy 1


|Nr osob.|NIP |

|00353840|7691202654|
|00353863|7691192306|
|00353868|7731997141|
|00353877|7720024739|
|00353886|7711732243|

0
bool validate(char nip[]) {  // parametrem jest cała linijka
    int wagi[]={7,6,5,4,3,2,7,5,6}; // sprawdź kolejność
    // sprawdź długość
    int s=0;
    for(i=0;i<9;i++)
        s=(s+(nip[i+10]-48)*wagi[i])%11;
    return s==nip[i]-48;
}
0

Sprawdziłem cały program i błąd leży w funkcji, która teoretycznia miała zamienić string na integer, ale wychodzą baardzo dziwne liczby (całkiem inne). Jeśli ktoś mógłby w tym pomóc, byłbym bardzo wdzięczny.

...
 nip = atoi(nip_string.c_str());
...
// Walidator NIPów v0.4
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib> 
using namespace std;
bool validate(string nip_string)
{
 long long nip, nip2;
 nip = strtol(nip_string.c_str(),NULL,10);
 nip2 = nip;
 int wagi[]={7,6,5,4,3,2,7,5,6}; // Wagi do sprawdzania, podane w odwróconej kolejności
 int cyfry[9]; //Tablica dla cyfr NIPu
 int i=0,ck,dlugosc=0,suma=0; // Zmienna pomocnicza, Cyfra kontrolna, Dlugosc NIPu, Suma iloczynow wag i cyfr NIPu
 while(nip2>0) // Sprawdzanie dlugosci NIPu
 {   nip2/=10;     dlugosc++; }
if(dlugosc!=10) return false;
 ck=nip%10; nip/=10; // Odcinianie cyfry kontrolnej z NIPu
 while(i<9)
 {
     cyfry[i]=(nip%10);                  
     nip=(nip/10); 
     suma=suma+(wagi[i]*cyfry[i]); 
     i++;
 }
 if((suma%11)==ck) return true;
 else return false;
}


int main () {
    float wersja=0.4;  // Wersja programu
    string nip[256]; string id[256]; string line; 
    int numer_bledne[256];
    int licznik=0, ilosc, i=0, x=0;
    cout<<"Walidator NIP'ow, wersja v"<<wersja<<" by SwK."<<endl<<endl;
    cout<<"Zadaniem programu jest przeanalizowanie pliku tekstowego, "<<endl;
    cout<<"wczytanie numerow NIP (10-znakowych) i sprawdzenie ich poprawnosci "<<endl;
    cout<<"odpowiednim algorytmem, a nastepnie wypisanie do pliku listy niepoprawnych"<<endl;
    cout<<"numerow, wraz z odpowiadajacymi im numerami osob."<<endl<<endl;
    cout<<"Program moze wczytac liste do 256 numerow NIP. "<<endl;
    cout<<"Domyslna nazwa pliku do analizy do analizy to: NIP.txt"<<endl<<endl;
    
    ifstream plik("NIP.txt");  // Otwieranie strumienia pliku
    if (plik.is_open())  // Sprawdzenie czy plik jest otwarty
    {
      while (!plik.eof()) 
      {  
             getline(plik,line,'|');
             if(line.size()==10&&line!="NIP       ") 
             {
               nip[i]=line; i++;
             }
             if(line.size()==8&&line!="Nr osob.") id[i]=line;             
      }
      plik.close(); 
    }
         
    ilosc=i; // Ilosc NIPow;
    i=0;
    while(i<ilosc)  // Sprawdzanie poprawnosci NIPow  
    {
      if(!validate(nip[i]))
      {
        licznik++;
        numer_bledne[x]=i;
        x++;
      }
      i++;
    }
     
  cout<<"Wczytano "<<ilosc<<" numerow NIP, ";  // Podanie wynikow analizy
  if(licznik>0)
    { i=0;
      ofstream wynik("NIP_bledne.txt");
      if (wynik.is_open())
      {
        wynik<<"Znaleziono "<<licznik<<" blednych numery/ow NIP:\nID        NIP\n";
        while(i<licznik) { wynik<<id[numer_bledne[i]]<<"  "<<nip[numer_bledne[i]]<<"\n"; i++; }
        wynik.close();   
      }
      cout<<"w tym "<<licznik<<" blednych numery/ow.\n";
      cout<<"Bledne numery zostaly zapisane do pliku NIP_bledne.txt\n\n";
    }
    else cout<<"wszystkie sa poprawne.";
getchar();
}

0

Liczby wychodziły dziwne, bo zmienna była za mała. W jaki sposób mogę zmieścić duże liczby takie jak NIP (zakres od 0 do (10^10)-1)? Nie mogę zastosować zmiennej typu long long, bo przy deklarowaniu wartości musiałbym do liczby dodać suffix LL, a zamiast liczby mam zmienną strtol();

0

zero) wiec sprawdz swoj libstd czy aby nie masz strtoll
uno) strtol to FUNKCJA
zwei) jestes w C++, użyj więc iostream'ó i ostringstream aby przerabiac liczby<>stringi, nie bedziesz mial problemow z brakujacymi funkcjami od "LL"
san) jak juz wspomnial po krotce dobrowolski, bez sensu jest przerabiac nip na liczbe, majac string'a. cyfry masz juz wszystkie pod reka. po co przerabiac na liczbe i wyodrebniac cyfry przez %10?

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