Program rozpoznający liczby - problem ze sortowaniem i fscanf.

0

Do napisania program typu "baza danych" wykorzystujący struktury i plik tekstowy. W pliku (np. o nazwie "liczby.txt") przechowujemy tylko teksty (które mogą być liczbami w różnych systemach). Do pliku można wpisać dane przy pomocy edytora tekstu.
Program ma działać następująco:
Po uruchomieniu wyświetlone zostaną użytkownikowi wszystkie teksty z pliku (odczytać dane z pliku można tylko jednokrotnie) wraz z komentarzem, np. "0xF089 jest liczbą w systemie szesnastkowym", "0b0012 nie jest liczbą".
Następnie zostaną wyświetlone tylko teksty będące liczbami posortowane (obojętnie rosnąco czy malejąco) wraz z ich wartością w systemie dziesiętnym, czyli:
1 0b001
8 010
10.5
15 0x00F
Na koniec program zapyta, czy dodać nowy tekst do "bazy danych". Przed zakończeniem działania program powinien uaktualnić dane w pliku (jeśli oczywiście pojawiły się nowe dane).

Tak wygląda to wszystko w moim wykonaniu. Zamienianie na dziesiętne działa, tylko przy sortowaniu wychodzą dziwne liczby. I jeszcze podstawowa rzecz, że nie wyświetla wszystkich liczb z pliku, bo nie potrafię zapętlić funkcji fscanf przy odczytywaniu. Może ktoś wie, jak to naprawić? Z góry bardzo dziękuję.

#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#include <math.h>
#include <string.h>

struct Liczba {
    char tekst[100];
    char bity;
    };
    
    
   int CzyLiczba(char*wskT,int d)
{
    int i, k=0;
    for(i=0;i<d;i++)
    {
        if (wskT[i]==' ')
            k=k+1;
    }
    if (k==0)
        return 1;
    else
        return 0;
}



int CzyDziesietna(char *wskT,int d)
{
    int i,k=0;
    if (wskT[0]!='0')
    {
         for(i=0;i<d;i++)
        {
            if (isdigit(wskT[i])!=0)
                k=k+1;
            if (wskT[i]=='.')
                k=k+1;
            if (wskT[i]=='e' || wskT[i]=='E')
                k=k+1;
            if (wskT[i]=='+' || wskT[i]=='-')
                k=k+1;
        }
    }
    else
        return 0;
    if (k==d)
        return 1;
    else
        return 0;
}



int CzyDwojkowa(char *wskT, int d)
{
    int i,k=2;
    if (wskT[0]=='0' && wskT[1]=='b')
    {
        for(i=2;i<d;i++)
        {
            if (wskT[i]=='0' || wskT[i]=='1')
                k=k+1;
        }
    }
    else
        return 0;
    if (k==d)
        return 1;
    else
        return 0;
}



int CzyOsemkowa(char *wskT, int d)
{
    int i, k=1;
    if (wskT[0]=='0')
    {
        for(i=1; i<d; i++)
        {
            if (isdigit(wskT[i])!=0 && wskT[i]<'8')
                k=k+1;
        }
    }
    else
        return 0;
    if (k==d)
        return 1;
    else
        return 0;
}



int CzySzesnastkowa(char *wskT, int d)
{
    int i,k=2;
    if ((wskT[1]=='x' || wskT[1]=='X') && wskT[0]=='0')
    {
        for(i=2;i<d;i++)
        {
            if (isdigit(wskT[i])!=0)
                k=k+1;
            if (wskT[i]=='a' || wskT[i]=='A')
                k=k+1;
            if (wskT[i]=='b' || wskT[i]=='B')
                k=k+1;
            if (wskT[i]=='c' || wskT[i]=='C')
                k=k+1;
            if (wskT[i]=='d' || wskT[i]=='D')
                k=k+1;
            if (wskT[i]=='e' || wskT[i]=='E')
                k=k+1;
            if (wskT[i]=='f' || wskT[i]=='F')
                k=k+1;
        }
    }
    else
        return 0;
    if (k==d)
        return 1;
    else
        return 0;
} 


int DwojDzies(char *wskT,int d)
{
	int wartosc=0,i;
   for(i=2; i<d; i++)
    {
        wartosc=wartosc*2+(wskT[i]-'0');
    }
    return wartosc;
}
 
 
int OsemDzies(char *wskT,int d)
{
    int wartosc=0,i;
   for(i=1; i<d; i++)
    {
        wartosc=wartosc*8+(wskT[i]-'0');
    }
    return wartosc;
    }
    
 
int SzesnDzies(char *wskT,int d)
{
    int wartosc=0,i;
   for(i=2; i<d; i++)
    {
        switch(wskT[i])
        {
           
            case 'a': wskT[i]=10; break;
            case 'A': wskT[i]=10; break;
            case 'b': wskT[i]=11; break;
            case 'B': wskT[i]=11; break;
            case 'c': wskT[i]=12; break;
            case 'C': wskT[i]=12; break;
            case 'd': wskT[i]=13; break;
            case 'D': wskT[i]=13; break;
            case 'e': wskT[i]=14; break;
            case 'E': wskT[i]=14; break;
            case 'f': wskT[i]=15; break;
            case 'F': wskT[i]=15; break;
        }
    
        wartosc=wartosc*16+(wskT[i]-'0');
    }
    return wartosc;
        
}
    



void OdczytajzPlikuTekstowego(struct Liczba *wsk)
{
    FILE *plik;
    plik=fopen("liczby.txt","r");

    if(plik == NULL)
    {
        printf("Nie można otworzyć pliku.\n");
        exit(1);
    }
   

    fscanf(plik, "%s", wsk->tekst);
        
    

    
   
    fclose(plik);
}





void DodajDoPlikuTekstowego(struct Liczba l)
{
    FILE *plik;
    plik=fopen("liczby.txt","a");

    if(plik==NULL)
    {
        printf("Nie można otworzyć pliku.\n");
        exit(1);
    }
    printf("Podaj tekst: ");
    scanf("%s",l.tekst);
    fprintf(plik,"%s\n",l.tekst);
    fclose(plik);
}



int PobierzLiczbe(struct Liczba *wsk)
{
    int d;
    OdczytajzPlikuTekstowego(wsk);
    d=strlen(wsk->tekst);


    if (CzyLiczba(wsk->tekst,d)==1)
    {
        if (CzyDziesietna(wsk->tekst,d)==1)
            wsk->bity=0b11;

        if (CzySzesnastkowa(wsk->tekst,d)==1)
            wsk->bity=0b101;

        if (CzyOsemkowa(wsk->tekst,d)==1)
            wsk->bity=0b1001;

        if (CzyDwojkowa(wsk->tekst,d)==1)
            wsk->bity=0b10001;
    }

    if ((CzyDwojkowa(wsk->tekst,d)==0 && CzyDziesietna(wsk->tekst,d)==0) && (CzyOsemkowa(wsk->tekst,d)==0 && CzySzesnastkowa(wsk->tekst,d)==0))
        wsk->bity=0b00;

    return wsk->bity;
}


void ZamienNaSystemDziesietny(struct Liczba *wsk)
{
	int d;
    OdczytajzPlikuTekstowego(wsk);
    d=strlen(wsk->tekst);
    
if (CzyLiczba(wsk->tekst,d)==1)
    {
      if (CzySzesnastkowa(wsk->tekst,d)==1)
          SzesnDzies(wsk->tekst,d);
      if (CzyOsemkowa(wsk->tekst,d)==1)
          OsemDzies(wsk->tekst,d);
      if (CzyDwojkowa(wsk->tekst,d)==1)
          DwojDzies(wsk->tekst,d);
    }
    
   
}



void WyswietlLiczbe(struct Liczba l)
{
    switch(PobierzLiczbe(&l))
    {
      case 0b11:
           printf("%s jest liczbą w systemie dziesiętnym.\n",l.tekst);
           break;
       case 0b101:
           printf("%s jest liczbą w systemie szesnastkowym.\n",l.tekst);
           break;
        case 0b1001:
           printf("%s jest liczbą w systemie ósemkowym.\n",l.tekst);
           break;
       case 0b10001:
            printf("%s jest liczbą w systemie dwójkowym.\n",l.tekst);
         break;
       case 0b00:
            printf("%s nie jest liczbą.\n",l.tekst);
            break;
   }
}



void OdczytajzKomentarzem(struct Liczba *wsk)
{
	struct Liczba l;
    FILE *plik;
    plik=fopen("liczby.txt","r");

    if(plik == NULL)
    {
        printf("Nie można otworzyć pliku.\n");
        exit(1);
    }
    do
    {
    fscanf(plik, "%s", wsk->tekst);
    WyswietlLiczbe(l);
    }while(feof(plik)==0);
    fclose(plik);
}


void Sortuj(int *tab,struct Liczba *wsk)
{
	int d,n=0;
	struct Liczba l;
    OdczytajzPlikuTekstowego(wsk);
    d=strlen(wsk->tekst);
	 ZamienNaSystemDziesietny(&l);
	if (CzyLiczba(wsk->tekst,d)==1) n++;
            
 int i,j,t;
 
 for(i=1;i<=n;i++)
 {
	 j=i;
	 t=tab[i];
	 while (tab[j-1]>t && j>0)
	 {
		 tab[j]=tab[j-1];
		 j--;
	 }
	 tab[j]=t;
 }
     
     printf("%d   %s\n",t,l.tekst);   
  
}



int main(int argc, char** argv)
{   
	int decyzja,tab[8];
	while(1)
    {
    struct Liczba l;
    OdczytajzKomentarzem(&l);
    Sortuj(tab,&l);
    printf("\n\nCzy dodać nowy tekst do bazy danych?\ntak-1  nie-0\n");
    scanf("%d",&decyzja);
    if (decyzja==0) break;
    DodajDoPlikuTekstowego(l);
    }
  
	return 0;
}
0
  1. Wczytywanie while(fscanf(plik,"%99s",wsk->tekst)==1) {}
  2. Wczytujesz dwa razy, a miało być tylko raz.
  3. Sortujesz tablice tab do której nić przed tym nie wpisałeś, więc nawet nie rozumiem czego oczekujesz po takim sortowaniu.
  4. Twoje sprawdzenie na liczbę dziesiętną uzna za liczbę nawet taki coś: e-+-.....+E0Eee....eeEE---e+++e-+1e1234
  5. Konwersje na system dziesiętny z dowolnego systemu da się napisać w jednej funkcji
0

Napisałem jeszcze coś takiego. Wydaje mi się, że jak wpiszę ZamienNaSystemDziesietny(&l) to wpisze mi do tej tablicy wartosc. Ale pewnie tez zle:(

void Sortuj(int **tab,struct Liczba *wsk)
{

 int i,j,t,d,n=0,wartosc;
struct Liczba l;
OdczytajzPlikuTekstowego(wsk);
ZamienNaSystemDziesietny(&l);

d=strlen(wsk->tekst);
ZamienNaSystemDziesietny(&l);
if (CzyLiczba(wsk->tekst,d)==1) n++;
 tab=(int**)malloc(n*sizeof(int*));
	for(i=0;i<=n;i++)
	tab[i]=(int*)malloc(1*sizeof(int));
    for(i=0;i<=n;i++)
    }	
        tab[i][0]= wartosc;
    }

for(i=1;i<=n;i++)
{
j=i;
t=tab[i][0];
while (tab[j-1][0]>t && j>0)
{
tab[j][0]=tab[j-1][0];
j--;
}
tab[j][0]=t;
}

 printf("%d   %s\n",t,l.tekst);   
 for(i=0;i<=n;i++)free (tab[i]);
	free (tab);

}

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