Witam mam na studiach za zadanie napisanie pewnego projektu którego polecenia wkleję niżej dla szerszego rozeznania w temacie:
Napisz program, który zawiera:
- Funkcję generującą przebieg funkcji matematycznej (będzie podany dla każdego indywidualnie).
Jako parametry wejściowe funkcji wchodzą: tablica współczynników funkcji, dwa parametry
określające dziedzinę, tablica wynikowa oraz wielkość tablicy wynikowej.
DLA AMBITNYCH: wygeneruj funkcję piłokształtną lub trójkątną; - Funkcję wczytującą z konsoli współczynniki funkcji (jako tablicę);
- Funkcję wczytującą zakres dziedziny;
- Funkcję generującą losowy szum (zakłócenia) na sygnale i zapisującą zaszumiony sygnał w
osobnej tablicy. Szum powinien być losowy w kilku dziedzinach, tzn. na przykład losowo wybrane
zaszumione próbki, losowa ilość zaszumionych próbek, losowa amplituda o określonych
granicach itp.; - Funkcję zapisującą tablicę wyników lub zaszumioną tablicę wyników do pliku .CSV z możliwością
otwarcia w arkuszu kalkulacyjnym; - Funkcję wczytującą rozmiar tablicy wynikowej;
- Dynamiczną alokację pamięci dla tablicy wynikowej za pomocą funkcji malloc() lub calloc().
- Funkcję odczytującą dane (sygnał) z pliku .CSV z użyciem funkcji realloc() – bez liczenia długości
pliku; - Funkcję filtrującą wygenerowany lub wczytany sygnał z szumu (filtr medianowy i średniej ruchomej).
DLA AMBITNYCH: okno filtra o dowolnej szerokości; - Zabezpieczenia programu przed błędnym wprowadzaniem danych;
- Menu użytkownika – możliwość generowania, wczytania, zaszumienia i filtracji sygnału, zapisania
sygnału w każdym z tych stanów itd.
Jak w temacie mam problem ze stworzeniem menu ponieważ w poniższym kodzie gdy w konsoli wejdę np w podawanie parametrów nie mogę wyjść z pętli i program ciągle prosi o wartości parametrów. Kolejny problem to zapis przefiltrowanych danych do pliku .csv. jeżeli dajmy na to rozmiar tablic to 50 to przefiltrowane wyniki zapisują się od 51. komórki w pliku excel. Kombinowałem coś fseek ale bezskutecznie. Będę wdzięczny za wszelką pomoc i rady.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <locale.h>
#include <time.h>
void parametry(float wspolczynniki[])
{
float parA, parB, parC, parD;
printf("Podaj parametr A: ");
scanf("%f", &parA); //pobranie parametrow od uzytkownika
printf("Podaj parametr B (nie 0): ");
scanf("%f", &parB);
while(parB == 0)
{
printf("Wprowadziles niepoprawna liczbe podaj liczbe > 0. Parametr B: ");
scanf("%f", &parB);
}
printf("Podaj parametr C: ");
scanf("%f", &parC);
while(parC < 0)
{
printf("Wprowadziles niepoprawna liczbe podaj liczbe >= 0. Parametr C: ");
scanf("%f", &parC);
}
printf("Podaj parametr D (nie 0): ");
scanf("%f", &parD);
while(parD == 0)
{
printf("Wprowadziles niepoprawna liczbe podaj liczbe > 0. Parametr D: ");
scanf("%f", &parD);
}
*(wspolczynniki) = parA; //przypisanie parametrow do odpowiednich miejsc w tablicy
*(wspolczynniki+1) = parB;
*(wspolczynniki+2) = parC;
*(wspolczynniki+3) = parD;
}
void dziedzina(float *dMin, float *dMax) //X ma nalezec do (-1 , 1)
{
printf("Podaj dolna granice dziedziny: ");
scanf("%f", dMin);
printf("Podaj gorna granice dziedziny: ");
scanf("%f", dMax);
while(*dMin > *dMax)
{
printf("Dolna granica jest wyzsza od gornej podaj nowe wartosci pamietajac ze dMin < dMax\n");
printf("Podaj dolna granice dziedziny: ");
scanf("%f", dMin);
printf("Podaj gorna granice dziedziny: ");
scanf("%f", dMax);
}
}
void rozmiar_tablic(int *rozmiar_tablicy)
{
printf("Podaj liczbe elementow funkcji: ");
scanf("%d", rozmiar_tablicy);
while(*rozmiar_tablicy < 0 || *rozmiar_tablicy == 0)
{
printf("Wprowadziles niepoprawna liczbe podaj liczbe > 0. Liczba elementow funkcji: ");
scanf("%d", rozmiar_tablicy);
}
}
void generator(float wspolczynniki[], float dMin, float dMax, float wyniki[], int rozmiar_tablicy)
{
float x;
int i;
float krok;
krok = (fabs(dMin) + fabs(dMax)) / rozmiar_tablicy;
for(i=0; i<rozmiar_tablicy; i++)
{
x = dMin + i * krok; //x jest wyliczany na biezaco
wyniki[i] = (*(wspolczynniki) * sin(x / *(wspolczynniki+1))) * cos((sqrt( *(wspolczynniki+2))/ *(wspolczynniki+3)) * x);
}
}
void zapisz(float wyniki[], int rozmiar_tablicy, float wyniki_szumu[], float wyniki_szumu_wlasciwa[])
{
FILE* arkusz;
arkusz = fopen("arkusz.CSV", "w");
if (arkusz == NULL)
{
printf("Ups, cos nie dziala! Nie udało się otworzyc pliku CSV. Sprawdz kod i sprobuj zresetowac program\n");
}
for(int i=0; i<rozmiar_tablicy; i++)
{
wyniki_szumu_wlasciwa[i] = wyniki[i] + wyniki_szumu[i]; //zapisanie zaszuminej tablicy(suma wynikow i szumow)
fprintf(arkusz,"%f; %f\n", wyniki[i], wyniki_szumu_wlasciwa[i]);
}
fclose(arkusz);
}
void szum (float wyniki[], int rozmiar_tablicy, float wyniki_szumu[])
{
srand(time(NULL));
int liczba_zaszumionych;
int max = (0.21*rozmiar_tablicy); //gorna granica losowania
int min = (0.1*rozmiar_tablicy); //dolna granica losowania
liczba_zaszumionych = (rand()%max+min);
printf("Liczba zaszumionych probek = %d\n", liczba_zaszumionych);
float amplituda;
float najwieksza = wyniki[0]; //ustalamy, że największą wartością jest (póki co) pierwszy element tablicy
float najmniejsza = wyniki[0]; //ustalamy, że najmniejszą wartością jest (póki co) pierwszy element tablicy
for( int i = 0; i < rozmiar_tablicy; i++ ) //szukanie amplitudy
{
if( wyniki[i] > najwieksza )
najwieksza= wyniki[i]; //jeśli sprawdzany element tablicy jest większy od tego (dotychczas) największego, to on staje się tym największym
if( wyniki[i] < najmniejsza )
najmniejsza = wyniki[i]; //jeśli sprawdzany element tablicy jest mniejszy od tego (dotychczas) najmniejszego, to on staje się tym najmniejszym
}
amplituda = fabs(najwieksza) + fabs(najmniejsza);
printf("Najwieksza wartosc funkcji to: %f\n", najwieksza);
printf("Najmniejsza wartosc funkcji to: %f\n", najmniejsza);
printf("Amplituda wynosi: %f\n", amplituda);
int i2;
float wartosc_szumu;
int max_szum = 31*amplituda*2;
int min_szum = -31*amplituda;
int numer_tablicy;
for(i2 = 0; i2 < liczba_zaszumionych; i2++)
{
numer_tablicy = (rand()%rozmiar_tablicy+1);
wartosc_szumu = rand()%max_szum/100.+min_szum/100.;
wyniki_szumu[numer_tablicy] = wartosc_szumu;
// wyniki_szumu_wlasciwa[numer_tablicy] = wyniki_szumu[numer_tablicy] + wyniki[numer_tablicy];
}
}
void otwarcie_pliku(float **wyniki, float **wyniki_szumu_wlasciwa, int rozmiar_tablicy)
{
float pierwsza_liczba;
float druga_liczba;
int nowy_rozmiar;
nowy_rozmiar = 1;
FILE* arkusz;
arkusz = fopen("arkusz.CSV", "r");
if (arkusz == NULL)
{
printf("Ups, cos nie dziala! Nie udalo sie otworzyc pliku CSV. Sprawdz kod i sprobuj zresetowac program\n");
}
printf("Wartosc prawdziwa: Wartosc po zaszumieniu:\n");
while (fgetc(arkusz) != EOF) //odczytuje znak i przesuwa kursor o 1
{
fseek(arkusz, -1, SEEK_CUR);
fscanf(arkusz, "%f ; ", &pierwsza_liczba);
*wyniki = realloc(*wyniki, nowy_rozmiar * sizeof(int));
printf("%f ", pierwsza_liczba); //dlaczego nie ma minusów, sprobowac cofnac o 1 fseek argument -1 seek cur
*(*wyniki + nowy_rozmiar - 1) = pierwsza_liczba;
fscanf(arkusz, "%f ; ", &druga_liczba);
*wyniki_szumu_wlasciwa = realloc(*wyniki_szumu_wlasciwa, nowy_rozmiar * sizeof(int));
printf("%f\n", druga_liczba);
*(*wyniki_szumu_wlasciwa + nowy_rozmiar - 1) = druga_liczba;
nowy_rozmiar++;
}
fclose(arkusz);
}
float sortowanie_babelkowe(float *tab, int szerokosc_okna_filtra)
{
float temp;
int i;
do
{
for(i = 0; i < szerokosc_okna_filtra - 1; i++) //x-1 zeby warunek mniejszosci j nie wyszedł do 6
{
if(tab[i] > tab[i+1])
{
temp = tab[i+1];
tab[i+1] = tab[i];
tab[i] = temp;
}
}
szerokosc_okna_filtra--;
}while(szerokosc_okna_filtra > 1);
return tab[2]; //zwracamy wyraz środkowy
}
void filtr_medianowy(float *wyniki, float *wyniki_szumu_wlasciwa,float *wyniki_po_medianowym, int rozmiar_tablicy)
{
float tab[5];
wyniki_po_medianowym[0] = wyniki_szumu_wlasciwa[0]; //przepisanie dwoch pierwszych i ostatnich wyrazow tabeli do tabeli przefiltrowanych danych
wyniki_po_medianowym[1] = wyniki_szumu_wlasciwa[1];
wyniki_po_medianowym[rozmiar_tablicy-1] = wyniki_szumu_wlasciwa[rozmiar_tablicy-1];
wyniki_po_medianowym[rozmiar_tablicy-2] = wyniki_szumu_wlasciwa[rozmiar_tablicy-2];
for (int j = 2; j < rozmiar_tablicy; j++) //j=2 bo olewamy pierwsze dwa przepisane wczesniej miejsca
{
tab[0] = wyniki_szumu_wlasciwa[j-2]; //przypisujemy wartosci do tablicy ktora potem sortujemy babelkowo
tab[1] = wyniki_szumu_wlasciwa[j-1];
tab[2] = wyniki_szumu_wlasciwa[j];
tab[3] = wyniki_szumu_wlasciwa[j+1];
tab[4] = wyniki_szumu_wlasciwa[j+2];
wyniki_po_medianowym[j] = sortowanie_babelkowe(tab, 5); //przypisanie wartosci przesortowanej babelkowo do itego miejsca w tablicy po filtrowaniu
}
FILE* arkusz;
arkusz = fopen("arkusz.CSV", "a"); //jak dopisac ta tablice od poczatku a nie tak na koncu
fseek(arkusz, 3, SEEK_SET );
if (arkusz == NULL)
{
printf("Ups, cos nie dziala! Nie udalo sie otworzyc pliku CSV. Sprawdz kod i sprobuj zresetowac program\n");
}
for(int j2 = 0; j2<rozmiar_tablicy; j2++)
{
fprintf(arkusz,";;%f\n", wyniki_po_medianowym[j2]);
}
fclose(arkusz);
}
float srednia_okna(float *tab)
{
float srednia;
srednia = (tab[0] + tab[1] + tab[2] + tab[3] + tab[4])/5;
return srednia; //zwracamy srednia 5 wyrazow
}
void filtr_srednia_ruchoma(float *wyniki, float *wyniki_szumu_wlasciwa,float *wyniki_po_sredniej, int rozmiar_tablicy)
{
float tab[5];
wyniki_po_sredniej[0] = wyniki_szumu_wlasciwa[0]; //przepisanie dwoch pierwszych i ostatnich wyrazow tabeli do tabeli przefiltrowanych danych
wyniki_po_sredniej[1] = wyniki_szumu_wlasciwa[1];
wyniki_po_sredniej[rozmiar_tablicy-1] = wyniki_szumu_wlasciwa[rozmiar_tablicy-1];
wyniki_po_sredniej[rozmiar_tablicy-2] = wyniki_szumu_wlasciwa[rozmiar_tablicy-2];
for (int j = 2; j < rozmiar_tablicy-2; j++) //j=2 bo olewamy pierwsze dwa przepisane wczesniej miejsca
{
tab[0] = wyniki_szumu_wlasciwa[j-2]; //przypisujemy wartosci do tablicy ktora potem sortujemy babelkowo
tab[1] = wyniki_szumu_wlasciwa[j-1];
tab[2] = wyniki_szumu_wlasciwa[j];
tab[3] = wyniki_szumu_wlasciwa[j+1];
tab[4] = wyniki_szumu_wlasciwa[j+2];
wyniki_po_sredniej[j] = srednia_okna(tab);
}
FILE* arkusz;
arkusz = fopen("arkusz.CSV", "a"); //jak dopisac ta tablice od poczatku a nie tak na koncu
fseek(arkusz, 4, SEEK_SET );
if (arkusz == NULL)
{
printf("Ups, cos nie dziala! Nie udalo sie otworzyc pliku CSV. Sprawdz kod i sprobuj zresetowac program\n");
}
for(int j2 = 0; j2<rozmiar_tablicy; j2++)
{
fprintf(arkusz,";;;%f\n", wyniki_po_sredniej[j2]);
}
fclose(arkusz);
}
int main()
{
setlocale(LC_ALL, "polish_poland");
float tablica_par[4]; //tablica_par to nazwa tablicy w ktorej sa parametry A B C D
//parametry(tablica_par); //wywo³anie funkcji wprowadzania parametrow
float dMin;
float dMax;
// dziedzina(&dMin, &dMax); //wywolanie funkcji okreslania granic x
int rozmiar_tablicy;
// rozmiar_tablic(&rozmiar_tablicy);
float *wyniki;
wyniki = malloc(rozmiar_tablicy * sizeof(*wyniki));
float *wyniki_szumu;
wyniki_szumu = malloc(rozmiar_tablicy * sizeof(*wyniki_szumu));
float *wyniki_szumu_wlasciwa;
wyniki_szumu_wlasciwa = malloc(rozmiar_tablicy * sizeof(*wyniki_szumu_wlasciwa));
// generator(tablica_par, dMin, dMax, wyniki, rozmiar_tablicy);
float *wyniki_po_medianowym;
wyniki_po_medianowym = malloc(rozmiar_tablicy * sizeof(*wyniki_po_medianowym));
float *wyniki_po_sredniej;
wyniki_po_sredniej = malloc(rozmiar_tablicy * sizeof(*wyniki_po_sredniej));
int wybor;
wybor = 0;
int wybor_filtra;
wybor_filtra = 0;
printf("1)Podaj wspolczynniki\n2)Podaj dziedzine x\n3)Podaj illosc probek\n4)Generuj funkcje\n5)Zapisz funkcje\n6)Zaszum\n7)Odczytaj z pliku\n8)Filtruj\n9)Zakoncz\n");
scanf("%d",&wybor);
while(wybor != 9)
{
switch(wybor)
{
case 1:
parametry(tablica_par);
break;
case 2:
dziedzina(&dMin, &dMax);
break;
case 3:
rozmiar_tablic(&rozmiar_tablicy);
break;
case 4:
generator(tablica_par, dMin, dMax, wyniki, rozmiar_tablicy);
break;
case 5:
zapisz(wyniki, rozmiar_tablicy, wyniki_szumu, wyniki_szumu_wlasciwa);
break;
case 6:
szum(wyniki, rozmiar_tablicy, wyniki_szumu);
break;
case 7:
otwarcie_pliku(&wyniki, &wyniki_szumu_wlasciwa, rozmiar_tablicy);
break;
case 8:
printf("Wybierz rodzaj filtra\n1)Filtr medianowy\n2)Filtr sredniej ruchomej\n");
scanf("%d",&wybor_filtra);
switch(wybor_filtra)
{
case 1:
filtr_medianowy(wyniki, wyniki_szumu_wlasciwa,wyniki_po_medianowym, rozmiar_tablicy);
break;
case 2:
filtr_srednia_ruchoma(wyniki, wyniki_szumu_wlasciwa,wyniki_po_medianowym, rozmiar_tablicy);
break;
}
break;
case 9:
exit( EXIT_SUCCESS );
break;
default:
while(wybor < 1 || wybor > 8)
{
printf("Nie udalo Ci sie wybrac poprawnej opcji sprobuj jeszcze raz :)");
scanf("%d",&wybor);
}
}
}
// szum(wyniki, rozmiar_tablicy, wyniki_szumu);
//zapisz(wyniki, rozmiar_tablicy, wyniki_szumu, wyniki_szumu_wlasciwa);
//otwarcie_pliku(&wyniki, &wyniki_szumu_wlasciwa, rozmiar_tablicy);
//filtr_medianowy(wyniki, wyniki_szumu_wlasciwa,wyniki_po_medianowym, rozmiar_tablicy);
//filtr_srednia_ruchoma(wyniki, wyniki_szumu_wlasciwa,wyniki_po_medianowym, rozmiar_tablicy);
//printf("Po filtrze: %f\n", wyniki_po_medianowym[0]); cos nie dziala
wyniki = NULL;
wyniki_szumu = NULL;
wyniki_szumu_wlasciwa = NULL;
wyniki_po_medianowym = NULL;
wyniki_po_sredniej = NULL;
free(wyniki);
free(wyniki_szumu);
free(wyniki_szumu_wlasciwa);
free(wyniki_po_medianowym);
free(wyniki_po_sredniej);
return 0;
}