Pomoc z projektem kalkulator pochodnych ( język C)

0

Witam,
Mam takie polecenie:
Napisz program, który drukuje na ekranie wzór na pierwszą pochodną funkcji zadanej w pliku. Załóż, że wzór funkcji w pliku jest postaci f(x)⋅g(x), gdzie funkcje f(x) i g(x) to jedno z wyrażeń typu x^n, sin(a⋅x) lub cos(b⋅x). Przykładowy wzór podany w pliku tekstowym to: x^7⋅cos(π⋅x).

Zrobiłem to w sposób łopatologiczny, tzn wczytywanie do tablicy znaków i analiza każdego znaku... Co nie było zrobione do końca tak jak trzeba, bo było ograniczone jedynie do tego, że w cos i sin mogły być liczby 0-9 i 'pi' a w potędze x 0-99 ... i to na tyle, a wymagania są takie, żeby np. jeśli w pliku pojawi się spacja to nic to nie zmieni, a u mnie by to już namieszało wszystko i liczby 'a' i 'b' mają być dowolnymi rzeczywistymi, po prostu wczytywane jako double :), wiem że trzeba kombinowac z fscanf :), a i dodam ze moze być 9 kombinacji w pliku (coscos, cossin, cosx,sinsin,sincos,sinx,xx,xcos,x*sin)

A tu mój kod...

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "winbgi2.h"

int main()
{
	FILE *plik;
	char s;
	char *w;
	int licznik = 0;
	plik = fopen("dane.txt", "r");
	if (plik == NULL)
	{
		printf("Blad");
		exit(1);
	}

	while (!feof(plik))
	{
		fscanf(plik, "%c", &s);
		licznik++;
	}
	licznik--;
	fclose(plik);
	plik = fopen("dane.txt", "r");
	if (plik == NULL)
	{
		printf("Blad");
		exit(1);
	}

	w = (char*)malloc(licznik*sizeof(char));
	printf("UWAGA!!!\nProgram liczy pochodne:\n -do sinusa i cosinusa mozna wstawic pi*x lub a*x, gdzie a nalezy do [0,9]\n -potegi x moga byc z przedzialu [0,99]\n -jesli chcesz policzyc dla dowolnej liczby rzeczywistej wstaw zamiast niej\n stala np. a i do koncowego wzoru wstaw a :)\n\n");
	printf("\nFunckja wyjsciowa: ");
	for (int i = 0; i < licznik; i++)
	{
		fscanf(plik, "%c", &w[i]);
		printf("%c", w[i]);

	}
	printf("\n");
	switch (w[0])
	{
	case 'x':
	{
				switch (w[3])
				{
				case '*':
				{
						  switch (w[4])
						  {
						  case's':
						  {
									 switch (w[8])
									 {
									 case 'p':
									 {
												 printf("pochodna funckji: %cx^%c*sin(pi*x)+x^%c*cos(pi*x)*pi\n", w[2], w[2] - 1, w[2]);
												 break;
									 }
									 case '0': {printf("pochodna funckji: 0\n"); break; }
									 default: {printf("pochodna funckji: %cx^%c*sin(%c*x)+x^%c*cos(%c*x)*%c\n", w[2], w[2] - 1, w[8], w[2], w[8], w[8]); break; }
								     }
									 break;
						  }
						  case'c':
						  {
									 switch (w[8])
									 {
									 case 'p':
									 {
												 printf("pochodna funckji: %cx^%c*cos(pi*x)-x^%c*sin(pi*x)*pi\n", w[2], w[2] - 1, w[2]);
												 break;
									 }
									 case '0': {printf("pochodna funckji : %cx^%c\n", w[2], w[2] - 1); break; }
									 default: {printf("pochodna funckji: %cx^%c*cos(%c*x)-x^%c*sin(%c*x)*%c\n", w[2], w[2] - 1, w[8], w[2], w[8], w[8]); break; }
									 
										 break;
									 }
						  }
						  case 'x':
						  {
									  switch (licznik)
									  {
									  case 7:
									  {
												  printf("pochodna funkcji: %c*x^%c*x^%c+x^%c*%c*x^%c", w[2], w[2] - 1, w[6], w[2], w[6], w[6] - 1);
												  break;
									  }
									  case 8:
									  {
												printf("pochodna funkcji: %c*x^%c*x^%c%c+x^%c*x^%c%c*%c%c", w[2], w[2] - 1, w[6], w[7], w[2], w[6], w[7] - 1, w[6], w[7]);
												break;
									  }
									  }
						  }
							  break;
						  }
				}
				default:
				{
						   switch (w[5])
						   {
						   case's':
						   {
									  switch (w[9])
									  {
									  case 'p':
									  {
												  printf("pochodna funckji: %c%cx^%c%c*sin(pi*x)+x^%c%c*cos(pi*x)*pi\n", w[2], w[3],w[2],w[3]-1, w[2],w[3]);
												  break;
									  }
									  case '0': {printf("pochodna funckji: 0\n"); break; }
									  default: {printf("pochodna funckji: %c%cx^%c%c*sin(%c*x)+x^%c%c*cos(%c*x)*%c\n", w[2], w[3], w[2], w[3] - 1, w[9], w[2], w[3], w[9], w[9]); break; }
									  }
									  break;
						   }
						   case'c':
						   {
									  switch (w[9])
									  {
									  case 'p':
									  {
												  printf("pochodna funckji: %c%cx^%c%c*cos(pi*x)-x^%c%c*sin(pi*x)*pi\n", w[2], w[3], w[2], w[3] - 1, w[2], w[3]);
												  break;
									  }
									  case '0': {printf("pochodna funckji: %c%cx^%c%c\n", w[2],w[3],w[2],w[3]-1); break; }
									  default: {printf("pochodna funckji: %c%cx^%c%c*cos(%c*x)-x^%c%c*sin(%c*x)*%c\n", w[2], w[3], w[2], w[3] - 1, w[9], w[2], w[3], w[9], w[9]); break; }
									  }
									  break;
							}
						   case 'x':
						   {
									   switch (licznik)
									   {
									   case 8:
									   {
												 printf("pochodna funkcji: %c%cx^%c%c*x^%c+x^%c%c*x^%c*%c", w[2], w[3], w[2], w[3] - 1, w[7], w[2], w[3], w[7]-1, w[7]);
												 break;
									   }
									   case 9:
									   {
												 printf("pochodna funkcji: %c%cx^%c%c*x^%c%c+x^%c%c*x^%c%c*%c%c", w[2], w[3], w[2], w[3] - 1, w[7], w[8], w[2], w[3], w[7], w[8], w[7], w[8] - 1);
												 break;
									   }
									   }
						   }
						   }
							   break;
						   }
				}
				
				

			
				break;
	}
	case's':
	{
			   switch (w[4])
			   {
			   case 'p':
				   switch (w[10])
				   {
				   case 'c':
				   {
							   switch (w[14])
							   {
							   case 'p':
							   {
										   printf("pochodna funkcji: pi*((cos(pi*x))^2-(sin(pi*x))^2)\n");
											   break;
							   }
							   default:
							   {
										  printf("pochodna funkcji: pi*cos(pi*x)*cos(%c*x)-sin(pi*x)*sin(%c*x)*%c\n",w[14],w[14],w[14]);
										  break;
							   }
							   }
				   }
				   case 's':
				   {
							   switch (w[14])
							   {
							   case 'p':
							   {
										   printf("pochodna funkcji: cos(pi*x)*pi*sin(pi*x)+sin(pi*x)*cos(pi*x)*pi\n");
										   break;
							   }
							   default:
							   {
										  printf("pochodna funkcji: pi*cos(pi*x)*sin(%c*x)+sin(pi*x)*cos(%c*x)*%c\n", w[14], w[14], w[14]);
										  break;
							   }
							   }
				   }
				   case 'x':
				   {
							   switch (licznik)
							   {
							   case 13:
							   {
										  printf("pochodna funckji: cos(pi*x)*pi*x^%c+sin(pi*x)*x^%c*%c\n", w[12], w[12] - 1, w[12]);
										  break;
							   }
							   case 14:
							   {
										  printf("pochodna funckji: cos(pi*x)*pi*x^%c%c+sin(pi*x)*x^%c%c*%c%c\n", w[12], w[13], w[12], w[13] - 1, w[12], w[13]);
										  break;
							   }

							   }
				   }

				   }
			   default:
			   {
						  switch (w[9])
						  {
						  case 'c':
						  {
									  switch (w[13])
									  {
									  case 'p':
									  {
												  printf("pochodna funkcji: cos(%c*x)*%c*cos(pi*x)-sin(%c*x)*sin(pi*x)*pi\n",w[4],w[4],w[4]);
												  break;
									  }
									  default:
									  {
												 printf("pochodna funkcji: sin(%c*x)*%c*cos(%c*x)-sin(%c*x)*sin(%c*x)*%c\n", w[4], w[4], w[13],w[4],w[13],w[13]);
												 break;
									  }
									  }
						  }
						  case 's':
						  {
									  switch (w[13])
									  {
									  case 'p':
									  {
												  printf("pochodna funkcji: cos(%c*x)*%c*sin(pi*x)+sin(%c*x)*cos(pi*x)*pi\n",w[4],w[4],w[4]);
												  break;
									  }
									  default:
									  {
												 printf("pochodna funkcji: cos(%c*x)*%c*sin(%c*x)+sin(%c*x)*cos(%c*x)*%c\n", w[4], w[4], w[13],w[4],w[13],w[13]);
												 break;
									  }
									  }
						  }
						  case 'x':
						  {
									  switch (licznik)
									  {
									  case 13:
									  {
												 printf("pochodna funckji: cos(%c*x)*%c*x^%c%c+sin(%c*x)*x^%c%c*%c%c\n", w[4], w[4], w[11],w[12],w[4],w[11],w[12]-1,w[11],w[12]);
												 break;
									  }
									  case 12:
									  {
												 printf("pochodna funckji: cos(%c*x)*%c*x^%c+sin(%c*x)*x^%c*%c\n", w[4], w[4], w[11], w[4], w[11]-1, w[11]);
												 break;
									  }

									  }
						  }

						  }
			   }
				   
			   }
	}
	case 'c':
	{
				switch (w[4])
				{
				case 'p':
					switch (w[10])
					{
					case 'c':
					{
								switch (w[14])
								{
								case 'p':
								{
											printf("pochodna funkcji: -sin(pi*x)*pi*cos(pi*x)-cos(pi*x)*sin(pi*x)*pi\n");
											break;
								}
								default:
								{
										   printf("pochodna funkcji: -sin(pi*x)*pi*cos(%c*x)-cos(pi*x)*sin(%c*x)*%c\n", w[14], w[14], w[14]);
										   break;
								}
								}
					}
					case 's':
					{
								switch (w[14])
								{
								case 'p':
								{
											printf("pochodna funkcji: -sin(pi*x)*pi*sin(pi*x)+cos(pi*x)*cos(pi*x)*pi\n");
											break;
								}
								default:
								{
										   printf("pochodna funkcji: -sin(pi*x)*pi*sin(%c*x)+cos(pi*x)*cos(%c*x)*%c\n", w[14], w[14], w[14]);
										   break;
								}
								}
					}
					case 'x':
					{
								switch (licznik)
								{
								case 13:
								{
										   printf("pochodna funckji: -sin(pi*x)*pi*x^%c+cos(pi*x)*x^%c*%c\n", w[12], w[12] - 1, w[12]);
										   break;
								}
								case 14:
								{
										   printf("pochodna funckji: -sin(pi*x)*pi*x^%c%c+cos(pi*x)*x^%c%c*%c%c\n", w[12], w[13], w[12], w[13] - 1, w[12], w[13]);
										   break;
								}

								}
					}

					}
				default:
				{
						   switch (w[9])
						   {
						   case 'c':
						   {
									   switch (w[13])
									   {
									   case 'p':
									   {
												   printf("pochodna funkcji: -sin(%c*x)*%c*cos(pi*x)-cos(%c*x)*sin(pi*x)*pi\n", w[4], w[4], w[4]);
												   break;
									   }
									   default:
									   {
												  printf("pochodna funkcji: -sin(%c*x)*%c*cos(%c*x)-cos(%c*x)*sin(%c*x)*%c\n", w[4], w[4], w[13], w[4], w[13], w[13]);
												  break;
									   }
									   }
						   }
						   case 's':
						   {
									   switch (w[13])
									   {
									   case 'p':
									   {
												   printf("pochodna funkcji: -sin(%c*x)*%c*sin(pi*x)+cos(%c*x)*cos(pi*x)*pi\n", w[4], w[4], w[4]);
												   break;
									   }
									   default:
									   {
												  printf("pochodna funkcji: -sin(%c*x)*%c*sin(%c*x)+cos(%c*x)*cos(%c*x)*%c\n", w[4], w[4], w[13], w[4], w[13], w[13]);
												  break;
									   }
									   }
						   }
						   case 'x':
						   {
									   switch (licznik)
									   {
									   case 13:
									   {
												  printf("pochodna funckji: -sin(%c*x)*%c*x^%c%c+cos(%c*x)*x^%c%c*%c%c\n", w[4], w[4], w[11], w[12], w[4], w[11], w[12] - 1, w[11], w[12]);
												  break;
									   }
									   case 12:
									   {
												  printf("pochodna funckji: -sin(%c*x)*%c*x^%c+cos(%c*x)*x^%c*%c\n", w[4], w[4], w[11], w[4], w[11] - 1, w[11]);
												  break;
									   }

									   }
						   }

						   }
				}

				}
	}

	break;
	}


	


	

		
		fclose(plik);
		return 0;
}

2

Litości, jeśli ty chcesz wykonać to zadanie: nie definiując ani jednej funkcji (wszystko masz w main), to przygotuj się na hemoroidy, bo będziesz nad tym długo siedział i nikt nie będzie ci z tym pomagał.

0

Ten program, to i tak muszę od nowa i tak 😑
Bo ten niestety raczej się do niczego nie przyda, liczę na wskazówki i kierunek działania nie gotowy program :)
A programuje od niedawna takze, proszę o wyrozumiałość :/

2

No teraz to jest lekka tragedia. Zastanów sie czy gdyby to miało działac dla większej liczby funkcji (np. dodatkowo tg, ctg, arcusy, logarytmy) to też byś to w ten sposób próbował zrobić...

  1. Rozłóż problem na podproblemy. Jeśli masz wyrażenie postaci f(x) * g(x) to przecież wiesz że potrzebujesz policzyć osobno pochodną dla f i dla g. Zacznij więc od napisania funkcji która wylicza pochodną dla jednej z tych twoich elementarnych funkcji. Na wejściu dostaje funkcje i zwraca jej pochodną.
  2. Gdyby to miał być jakiś "prawdziwy" program, to należałoby podzielić parsowanie danych od generacji wyników. Parser zwracałby jakąś strukturę opisującą dane wejściowe, a generator na jej podstawie tworzyłby wynik.
0

Najpierw potrzebuje wskazówki jak wczytać dane do tablic dwóch znaków które przechowuja po jednym pliku, nwm jak to zrobic żeby wczytywalo tylko po jednej fucnkji 😑

0

*po jednej funkcji, nie pliku

0

No C to średni język do pisania parsera ale mimo wszystko masz np. http://www.cplusplus.com/reference/cstring/strtok/ które dzieli ci stringa na kawałki względem podanych delimiterów. U ciebie delimiterem jest * bo ona łączy kolejne funkcje.

1

Domyślam się, że masz to na uczelni. Powiedz więc prowadzącemu, że jest taki moduł w Pythonie jak SymPy. Jak jest otwarty na "nie wynajdowanie koła na nowo", to powinien zaliczyć pracę domową, a nawet jeśli nie, to będzie to fajna ciekawostka. W Pythonie robi się to tak:

from sympy import *

x = Symbol('x')
diff(pow(x, 7)*cos(pi*x), x)

Wynik to:

-pi*x**7*sin(pi*x) + 7*x**6*cos(pi*x)

W ogólności nie powinno się importować z *, ale nie chciałem wprowadzać zamieszania z przestrzenią nazw. W każdym razie możesz ostatnią linijkę (z diff(...)) wkleić do Online Shella i samemu się pobawić. Nawet wynik masz wydrukowany w postaci czytelnej dla człowieka.

0

Zrobiłbym to w sympy.
https://mzucker.github.io/2018/04/11/sympy-case-studies-part-2-derivatives.html

Jeśli w C to możesz w C odpalić SymPy:
https://www.linuxjournal.com/article/8497

W gołym C to zapytałbym się prowadzącego czy na pewno. Najlepiej dwa razy.

0

@Pyxis @vpiot
On nie dostał tego zadania by się wykręcić: a to jest już zrobione w takiej a takiej bibliotece, w innym języku.

@topic
Poczytaj o Flex i/lub Bison - zdefiniujesz gramatykę, a te narzędzia wygenerują ci kod w C, który podzieli napis na tokeny.
Z analizy tokenów wygenerujesz drzewo reprezentujące wzór wyjściowy.
Potem napisz funkcję, która przekształci to drzewo, w nowe drzewo reprezentującą pochodną.
A na koniec coś co zmieni drzewo w coś strawnego dla użytkownika (napis, reprezentację graficzną).

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