Program statystyczny w C

MaciekMM
Użytkownik
Użytkownik
Posty: 9
Rejestracja: 6 lis 2007, o 20:02
Płeć: Mężczyzna
Lokalizacja: Warszawa

Program statystyczny w C

Post autor: MaciekMM »

Napisać program przetwarzający plik tekstowy podawany jako parametr wywołania i zapamiętujący wynik działania w pliku wyjściowym, również podawanym jako parametr wywołania.
Zadaniem programu jest zliczenie linii, słów i wystąpień poszczególnych znaków w pliku wejściowym. Wyniki te mają być wyświetlone na ekranie po zakończeniu działania programu. W pliku wyjściowym należy umieścić posortowane słowa z pliku wejściowego oraz liczbę wystąpień każdego wyrazu, wyrazy powtarzające się powinny być umieszczone tylko raz.

HELP!

PS. Pod Unix'a
Fibik
Użytkownik
Użytkownik
Posty: 971
Rejestracja: 27 wrz 2005, o 22:56
Płeć: Mężczyzna
Lokalizacja: Wrocław
Podziękował: 11 razy
Pomógł: 75 razy

Program statystyczny w C

Post autor: Fibik »

Czytasz po znaku.
Liczysz linie sprawdzając znak:
lub
(uwzględniając kombinacje:
lub

).

- idziesz tak i badasz, aż do pierwszej litery: isalpha
- teraz czytasz słowo, szukasz w tablicy, czy drzewie (np. vector lub coś tam z stl);
jeśli nie ma to wstawiasz i zerujesz licznik, po tym wszystkim zwiększasz licznik bezwarunkowo.

plik się skończy -> zamykasz i zapisujesz te słowa, licząc przy okazji litery.
smiechowiec
Użytkownik
Użytkownik
Posty: 374
Rejestracja: 21 cze 2007, o 11:28
Płeć: Mężczyzna
Lokalizacja: Łostowice
Pomógł: 146 razy

Program statystyczny w C

Post autor: smiechowiec »

Kod: Zaznacz cały

#include <stdio.h>
#include <stdlib.h>
#include <strings.h> 
#include <ctype.h>

/* Maksymalna długość linii */
#define MAXLINIA 5000
/* Maksymalna ilość słów */
#define MAXSLOW 5000
/* Maksymalna długość słowa */
#define MAXSLOWO 40

/*
Polskie znaki w kodzie WINDOWS-1250
LITERA ą Ą ć Ć ę Ę ł Ł ń Ń ó Ó ś Ś ż Ż ź Ź 
DEC 185 165 230 198 234 202 179 163 241 209 243 211 156 140 191 175 159 143 
Polskie znaki w kodzie ISO-8859-2
LITERA ą Ą ć Ć ę Ę ł Ł ń Ń ó Ó ś Ś ż Ż ź Ź 
DEC 177 161 230 198 234 202 179 163 241 209 243 211 182 166 191 175 188 172 
*/
char tipl[] = { '_', 140, 143, 156, 159, 161, 163, 165, 166, 172, 175, 
      177, 179, 185, 188, 191, 198, 202, 209, 211, 230, 234, 241, 243};


/* Wyświetleni informacji o programie */
int oprogramie() {
  static char sinfo[] = 
"*** Program Maciek MM\n\
 sposob wywolania\n\
 maciek plik_wejsciowy plik_wyjsciowy\n";
  fputs(sinfo, stderr);
  return 0;
}


/* dodaje znaki z lini do tablicy wystąpień */
int zlicznaki(char *s, int tiznakow[]) {
  int i; /* licznik pętli */
  if ((s != NULL) && (strlen(s) > 0)) {
    for(i = 0; i < strlen(s); i++)
      tiznakow[ (unsigned char) s[i] ]++;
  }
  return 0;
}

/* dodaje słowo do tablicy słów */
int dodajslowo(char *s, int tislow[], char tslowa[MAXSLOW][MAXSLOWO]) {
  int i; /* licznik pętli */
  int bdodano = 0;
  for(i = 0; (tislow[i] > 0) && !bdodano; i++)
    if (strcmp(s, tslowa[i]) == 0) {
      bdodano++;
      tislow[i]++;
    }
    if (!bdodano){
      if (i < MAXSLOW) {
        tislow[i]++;
        strcpy(tslowa[i], s);
      }
      else {
        printf("Przekroczono maksymalna liczbe slow");
        exit(1);
      }
    }
        
  return 0;
}

/* Sprawdza czy znak jest akceptowany jako element słowa */
int znakslowa(char c) {
  int i;
  if (isalnum(c))
    return 1;
  for(i = 0; i < sizeof(tipl); i++)
    if (c == tipl[i])
      return 1;
  return 0;
}

/* dodaje znaki z lini do tablicy wystąpień */
int zliczslowa(char *s, int tislow[], char tslowa[MAXSLOW][MAXSLOWO]) {
  int i; /* licznik pętli */
  int ipos = 0; /* pozycja w slowie */
  char slowo[MAXSLOWO];
  if ((s != NULL) && (strlen(s) > 0)) {
    for(i = 0; i < strlen(s); i++)
      if (znakslowa( (unsigned char) s[i] ))
        slowo[ipos++] = s[i];
      else 
        if (ipos > 0) {
          slowo[ipos] = 0; /* zakończ słowo */
          dodajslowo(slowo, tislow, tslowa);
          ipos = 0;
        }
  }
  return 0;
}

/* sortowanie */
int sortuj(int tislow[], char tslowa[MAXSLOW][MAXSLOWO]) {
  int i, j, k, inum;
  char slowo[MAXSLOWO];
  for(i = 0; tislow[i] > 0; i++) {
    strcpy(slowo, tslowa[i]);
    k = i; /* numer słowa */
    for(j = i + 1; tislow[j] > 0; j++)
      if (strcmpi(tslowa[j], tslowa[k]) < 0) {
        k = j;
        strcpy(slowo, tslowa[j]);
      }
    if (k > i) { /* zamiana miejscami pozycji k z pozycją i */
      inum = tislow[k];
      tislow[k] = tislow[i];
      tislow[i] = inum;
      strcpy(tslowa[k], tslowa[i]);
      strcpy(tslowa[i], slowo);
    }
  }
  return 0;
}
  

int main(int argc, char *argv[]) {
  FILE *pfilein;  /* Plik z danymi wejściowymi */
  FILE *pfileout; /* Plik z danymi wyjściowymi */
  char slinia[MAXLINIA];
  int i; /* licznik pętli */
  int ilinii = 0; /* liczba linii w pliku */
  int tiznakow[256]; /* Tablica zmiennych podliczjąca liczbę wystąpień poszczególnych znaków */ 
  static char tslowa[MAXSLOW][MAXSLOWO];
  static int tislow[MAXSLOW];

	if (argc != 3) {
    printf("podano niewlasciwa liczbe argumentow %i \n", argc - 1);
    oprogramie();
    exit(1);
  }
  
  if ( (pfilein = fopen(argv[1], "rt")) == NULL) {
    fprintf(stderr, "Nie udalo sie otworzyc pliku z danymi wejsciowymi %s\n", argv[1]);
    exit(1);
	}
  
  if ( (pfileout = fopen(argv[2], "wt")) == NULL) {
    fprintf(stderr, "Nie udalo sie otworzyc pliku dla danymych wyjsciowych %s\n", argv[2]);
    exit(1);
	}
  
  /* Wyzerowanie tablicy zliczjącej znaki */
  for(i = 0; i < 256; i++)
    tiznakow[i] = 0;
  /* Wyzerowanie tablicy zliczjącej słowa */
  for(i = 0; i < MAXSLOW; i++)
    tislow[i] = 0;
  
  while (!feof(pfilein)) {
    ilinii++;
    fgets(slinia, MAXLINIA, pfilein);
    zlicznaki(slinia, tiznakow);
    zliczslowa(slinia, tislow, tslowa);
  }
  printf("Plik %s zawiera %i linii.\n", argv[1], ilinii);
  printf("**************************\n");
  printf("Wystepowanie znakow\n");
  printf("Kod znak ilosc wystapien\n");
  for(i = 0; i < 32; i++)
    if (tiznakow[i]) printf("%3i       %i\n", i, tiznakow[i]);
  for(i = 32; i < 256; i++)
    if (tiznakow[i]) printf("%3i  %c    %i\n", i, i, tiznakow[i]);

  sortuj(tislow, tslowa);
  printf("**************************\n");
  printf("Wystepowanie slow\n");
  for(i = 0; tislow[i] > 0; i++)
    printf("%s : %i\n", tslowa[i], tislow[i]);
  printf("**************************\n");
  
  fprintf(pfileout, "slowo : ilosc wystpien\n");
  for(i = 0; tislow[i] > 0; i++)
    fprintf(pfileout, "%s : %i\n", tslowa[i], tislow[i]);
  
  fclose(pfileout);
  fclose(pfilein);
  return 0;
}

MaciekMM
Użytkownik
Użytkownik
Posty: 9
Rejestracja: 6 lis 2007, o 20:02
Płeć: Mężczyzna
Lokalizacja: Warszawa

Program statystyczny w C

Post autor: MaciekMM »

Dzięki ogromne - ratujesz mi życie


Mam jeszcze tylko problem przy kompilacji - wyrzuca ze sinfo z funkcji "oprogramie" oraz tipl z funkcji "znakslowa" nie są zadeklarowane. W czym problem?
smiechowiec
Użytkownik
Użytkownik
Posty: 374
Rejestracja: 21 cze 2007, o 11:28
Płeć: Mężczyzna
Lokalizacja: Łostowice
Pomógł: 146 razy

Program statystyczny w C

Post autor: smiechowiec »

Program sprawdziłem na dwóch różnych maszynach i kompiluje się i działa.
Przypuszczam, że podczas przenoszenia przez kopiuj/wklej do pliku zamiast polskich znaków pojawiają się znaki sterujące.
Dlatego usunąłem z kodu wszystkie polskie znaki.
Spróbuj teraz, a w przypadku błędu, wklej proszę komunikaty,
albo pokaż zrzut ekranu.

Kod: Zaznacz cały

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <ctype.h>

/* Maksymalna dlugosc linii */
#define MAXLINIA 5000
/* Maksymalna ilosc slow */
#define MAXSLOW 5000
/* Maksymalna dlugosc slowa */
#define MAXSLOWO 40

char tipl[] = { '_', 140, 143, 156, 159, 161, 163, 165, 166, 172, 175,
      177, 179, 185, 188, 191, 198, 202, 209, 211, 230, 234, 241, 243};


/* Wyswietleni informacji o programie */
int oprogramie() {
  static char sinfo[] =
"*** Program Maciek MM\n\
 sposob wywolania\n\
 maciek plik_wejsciowy plik_wyjsciowy\n";
  fputs(sinfo, stderr);
  return 0;
}


/* dodaje znaki z lini do tablicy wystapien */
int zlicznaki(char *s, int tiznakow[]) {
  int i; /* licznik petli */
  if ((s != NULL) && (strlen(s) > 0)) {
    for(i = 0; i < strlen(s); i++)
      tiznakow[ (unsigned char) s[i] ]++;
  }
  return 0;
}

/* dodaje slowo do tablicy slow */
int dodajslowo(char *s, int tislow[], char tslowa[MAXSLOW][MAXSLOWO]) {
  int i; /* licznik petli */
  int bdodano = 0;
  for(i = 0; (tislow[i] > 0) && !bdodano; i++)
    if (strcmp(s, tslowa[i]) == 0) {
      bdodano++;
      tislow[i]++;
    }
    if (!bdodano){
      if (i < MAXSLOW) {
        tislow[i]++;
        strcpy(tslowa[i], s);
      }
      else {
        printf("Przekroczono maksymalna liczbe slow");
        exit(1);
      }
    }
       
  return 0;
}

/* Sprawdza czy znak jest akceptowany jako element slowa */
int znakslowa(char c) {
  int i;
  if (isalnum(c))
    return 1;
  for(i = 0; i < sizeof(tipl); i++)
    if (c == tipl[i])
      return 1;
  return 0;
}

/* dodaje znaki z lini do tablicy wystapien */
int zliczslowa(char *s, int tislow[], char tslowa[MAXSLOW][MAXSLOWO]) {
  int i; /* licznik petli */
  int ipos = 0; /* pozycja w slowie */
  char slowo[MAXSLOWO];
  if ((s != NULL) && (strlen(s) > 0)) {
    for(i = 0; i < strlen(s); i++)
      if (znakslowa( (unsigned char) s[i] ))
        slowo[ipos++] = s[i];
      else
        if (ipos > 0) {
          slowo[ipos] = 0; /* zakoncz slowo */
          dodajslowo(slowo, tislow, tslowa);
          ipos = 0;
        }
  }
  return 0;
}

/* sortowanie */
int sortuj(int tislow[], char tslowa[MAXSLOW][MAXSLOWO]) {
  int i, j, k, inum;
  char slowo[MAXSLOWO];
  for(i = 0; tislow[i] > 0; i++) {
    strcpy(slowo, tslowa[i]);
    k = i; /* numer slowa */
    for(j = i + 1; tislow[j] > 0; j++)
      if (strcmpi(tslowa[j], tslowa[k]) < 0) {
        k = j;
        strcpy(slowo, tslowa[j]);
      }
    if (k > i) { /* zamiana miejscami pozycji k z pozycja i */
      inum = tislow[k];
      tislow[k] = tislow[i];
      tislow[i] = inum;
      strcpy(tslowa[k], tslowa[i]);
      strcpy(tslowa[i], slowo);
    }
  }
  return 0;
}
 

int main(int argc, char *argv[]) {
  FILE *pfilein;  /* Plik z danymi wejsciowymi */
  FILE *pfileout; /* Plik z danymi wyjsciowymi */
  char slinia[MAXLINIA];
  int i; /* licznik petli */
  int ilinii = 0; /* liczba linii w pliku */
  int tiznakow[256]; /* Tablica zmiennych podliczjaca liczbe wystapien poszczegolnych znakow */
  static char tslowa[MAXSLOW][MAXSLOWO];
  static int tislow[MAXSLOW];

    if (argc != 3) {
    printf("podano niewlasciwa liczbe argumentow %i \n", argc - 1);
    oprogramie();
    exit(1);
  }
 
  if ( (pfilein = fopen(argv[1], "rt")) == NULL) {
    fprintf(stderr, "Nie udalo sie otworzyc pliku z danymi wejsciowymi %s\n", argv[1]);
    exit(1);
    }
 
  if ( (pfileout = fopen(argv[2], "wt")) == NULL) {
    fprintf(stderr, "Nie udalo sie otworzyc pliku dla danymych wyjsciowych %s\n", argv[2]);
    exit(1);
    }
 
  /* Wyzerowanie tablicy zliczjacej znaki */
  for(i = 0; i < 256; i++)
    tiznakow[i] = 0;
  /* Wyzerowanie tablicy zliczjacej slowa */
  for(i = 0; i < MAXSLOW; i++)
    tislow[i] = 0;
 
  while (!feof(pfilein)) {
    ilinii++;
    fgets(slinia, MAXLINIA, pfilein);
    zlicznaki(slinia, tiznakow);
    zliczslowa(slinia, tislow, tslowa);
  }
  printf("Plik %s zawiera %i linii.\n", argv[1], ilinii);
  printf("**************************\n");
  printf("Wystepowanie znakow\n");
  printf("Kod znak ilosc wystapien\n");
  for(i = 0; i < 32; i++)
    if (tiznakow[i]) printf("%3i       %i\n", i, tiznakow[i]);
  for(i = 32; i < 256; i++)
    if (tiznakow[i]) printf("%3i  %c    %i\n", i, i, tiznakow[i]);

  sortuj(tislow, tslowa);
  printf("**************************\n");
  printf("Wystepowanie slow\n");
  for(i = 0; tislow[i] > 0; i++)
    printf("%s : %i\n", tslowa[i], tislow[i]);
  printf("**************************\n");
 
  fprintf(pfileout, "slowo : ilosc wystpien\n");
  for(i = 0; tislow[i] > 0; i++)
    fprintf(pfileout, "%s : %i\n", tslowa[i], tislow[i]);
 
  fclose(pfileout);
  fclose(pfilein);
  return 0;
}


[ Dodano: 7 Listopada 2007, 21:48 ]
MaciekMM pisze:A może nie chce sie skompilować bo nie robie tego bezpośrednio na komputerze z unixem tylko przez putty?
Nie, to nie ma znaczenia, ja też tak robię.
Powiedz w jaki sposób utworzyłeś plik maciek.c .
Być może linie zakończone są znakami 13 10, a powinny być tylko 10 dla unixa.
Sprobuj zrobić tak
zaznaczasz kod źródła bez polskich znaków w przeglądarce i robisz kopiuj czyli ^C
usuń plik maciek.c i zrób go w ten sposób w putty.
vi maciek.c
otwiera się nowy pusty plik,
wciskasz klawisz a - żeby przejść do dopisywania
wciskasz prawy klawisz myszy żeby cały tekst się wkleił
wciskasz Escape żeby zakończyć dopisywanie
wciskasz SHIFT-ZZ
i mamy plik maciek.c
i teraz skompiluj.

Na jednej maszynie jest nowsza funkcja w bibliotece zamiast
strcmpi
jest
strcasecmp
ale to tylko nowsza nazwa, działa identycznie, ale gdyby się pojawił błąd linkera odnośnie strcmpi zamień na strcasecmp
ODPOWIEDZ