witam, mam pytanie czemu nie zczytuje mi z pliku tekstowego.txt
w którym jest x^3*sin(2*x)
poprawnie współczynniku przy x
w sin
w konsoli pokazują mi się 0
. Czy tutaj leży problem?
sscanf(buffer, "x^%d* %1c (%lfx)", &potęga, &typ, &kąt);
witam, mam pytanie czemu nie zczytuje mi z pliku tekstowego.txt
w którym jest x^3*sin(2*x)
poprawnie współczynniku przy x
w sin
w konsoli pokazują mi się 0
. Czy tutaj leży problem?
sscanf(buffer, "x^%d* %1c (%lfx)", &potęga, &typ, &kąt);
Elementarz elementarza, to korzystanie w liczby zwracanej przez sscanf
Po drugie, kod nie jest pełny.
Mimo ... "kliku" lat z C, nie ośmieliłbym się aż tak ambitnego stringa sterującego użyć.
Pamiętam, że kiedyś na studiach też myślałem, że można tak zrobić. Niestety format string dla scanfa to nie wyrażenie regularne. Z resztą, nawet gdyby był, to masz tam w nim spacje, których nie ma w dopasowywanym tekście. Niestety scanf raczej nie pomoże ci z tym w ogóle, bo nawet %d chyba będzie próbował dopasowywać aż do spcji, i zignoruje wszystko poza cyframi… Napisz może konkretnie co chcesz osiągnąć i pokaż więcej kodu, bo tak w oderwaniu od kontekstu trudno coś poradzić. Jeśli chcesz parsować dowolne wyrażenia, pewnie powinieneś zainteresować się flexem i bisonem, ale to sporo zabawy. Lepiej byłoby zrobić to w jakimś bardziej zaawansowanym języku.
elwis napisał(a):
Niestety scanf raczej nie pomoże ci z tym w ogóle, bo nawet %d chyba będzie próbował dopasowywać aż do spcji, i zignoruje wszystko poza cyframi… Napisz może konkretnie co chcesz osiągnąć i pokaż więcej kodu, bo tak w oderwaniu od kontekstu trudno coś poradzić. Jeśli chcesz parsować dowolne wyrażenia, pewnie powinieneś zainteresować się flexem i bisonem, ale to sporo zabawy. Lepiej byłoby zrobić to w jakimś bardziej zaawansowanym języku.
Ja bym szkolnym algorytmem przesuwał *s
tworząc "ręczny parser", wielokrotnie tak skanuję np znajdując przy liczbach realne jednostki miary w biznesie (mogą być legalne, pól-legalne (siedem pisowni sztuki)i zupełnie dziwne - akceptuję wg wymogów)
pewnie powinieneś zainteresować się flexem i bisonem, ale to sporo zabawy.
Oj , jest jazda, co więcej to tylko write-only, w razie niepowodzenie skanowania jest a-debugowalne, zostaje palenie kadzideł przed świętymi figurami
Osobiście wolę Antlr (ale to nie niżej niż C++). A dla takich prostych - skanowanie ręczne pętlą.
AnyKtokolwiek napisał(a):
Ja bym szkolnym algorytmem przesuwał
*s
tworząc "ręczny parser", wielokrotnie tak skanuję np znajdując przy liczbach realne jednostki miary w biznesie (mogą być legalne, pól-legalne (siedem pisowni sztuki)i zupełnie dziwne - akceptuję wg wymogów)
Dla prostej składni to można rzeczywiście użyć funkcji strtok()
dla porządku i parsować na piechotę. Liczby można sobie parsować atoi()
/atof()
, jakaś tablica ze zmiennymi i tyle. Tylko dla bardziej skomplikowanej składni to już będzie raczej kłopot.
pewnie powinieneś zainteresować się flexem i bisonem, ale to sporo zabawy.
Oj , jest jazda, co więcej to tylko write-only, w razie niepowodzenie skanowania jest a-debugowalne, zostaje palenie kadzideł przed świętymi figurami
No tak, dlatego przestrzegam przed czymś takim :)
Polecam czytać dokumneację: https://en.cppreference.com/w/c/io/fscanf
Wersja naprawiona:
int power = 0;
char type = ' ';
double angle = -1.0;
int count = sscanf(buffer, "x^%d* %1c%*3[a-z] (%lfx)", &power, &type, &angle);
Demo testami: https://godbolt.org/z/vsqhvGn7r (testy są w c++).
elwis napisał(a):
Pamiętam, że kiedyś na studiach też myślałem, że można tak zrobić. Niestety format string dla scanfa to nie wyrażenie regularne. Z resztą, nawet gdyby był, to masz tam w nim spacje, których nie ma w dopasowywanym tekście. Niestety scanf raczej nie pomoże ci z tym w ogóle, bo nawet %d chyba będzie próbował dopasowywać aż do spcji, i zignoruje wszystko poza cyframi… Napisz może konkretnie co chcesz osiągnąć i pokaż więcej kodu, bo tak w oderwaniu od kontekstu trudno coś poradzić. Jeśli chcesz parsować dowolne wyrażenia, pewnie powinieneś zainteresować się flexem i bisonem, ale to sporo zabawy. Lepiej byłoby zrobić to w jakimś bardziej zaawansowanym języku.
Tutaj jest cały program ma liczyć pochodną funkcji zadanej w pliku w moim przypadku to x^3sin(2x) (program liczy pochodną iloczynu tylko funkcji x^n, sin(ax) lub cos(bx))
typedef struct {
char typ;
int potenga;
double kat;
} funkcja;
void pochodna(funkcja term);
int main() {
FILE* file;
char buffer[100];
file = fopen("nazwa_pliku.txt", "r");
if (file == NULL) {
printf("Błąd otwarcia pliku");
return 1;
}
if (fgets(buffer, sizeof(buffer), file) == NULL) {
printf("Błąd odczytu z pliku");
fclose(file);
return 1;
}
fclose(file);
funkcja term;
sscanf(buffer, "x^%d*%c(%lfx)", &term.potenga, &term.typ, &term.kat);
printf("Wzór pierwszej pochodnej: ");
pochodna(term);
return 0;
}
void pochodna(funkcja term) {
switch (term.typ) {
case 'x':
printf("%dx^%d\n",term.potenga, term.potenga - 1);
break;
case 's':
printf("%dx^%d*sin(%lfx) + x^%d*%lfx*cos(%lfx)\n",
term.potenga, term.potenga - 1, term.kat, term.potenga, term.kat, term.kat);
break;
case 'c':
printf("%dx^%d*cos(%lfx) - x^%d*%lfx*sin(%lfx)\n",
term.potenga, term.potenga -1, term.kat,term.potenga, term.kat, term.kat);
break;
default:
printf("Bledny typ funkcji\n");
break;
}
}