Jak wczytać formułę matematyczną z pliku tekstowego?

0

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);
1

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ć.

1

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.

0
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ą.

0
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 :)

1

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++).

0
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;
    }
}

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