Avatar
švrčajs
Člen
Avatar
švrčajs:

Zdarec,
potřeboval bych pomoct s jedním projektem. Jedná se o http://jazykc.inf.upol.cz/…lkulacka.htm

Mám již hotovou struktutu Matice a funkce na sčítání a násobení, i to mi dalo zabrat :D Problém je v tom, že jsem se zasekl, jak načíst to zadání. Načíst řetězec ze souboru není problém, ale tady si prostě nevím rady :/

Nějaké nápady ? :D
struktura matice

struct Matice
{
        int radky;
        int sloupce;
        size_t velikost;
        double data[];
};

typedef struct Matice *Matice;

///vytvoření nové matice
struct Matice *novaMatice(int radky, int sloupce)
{
        struct Matice *m;

        m = calloc(sizeof m + radky * sloupce * sizeof(double), 1);
        m->sloupce = sloupce;
        m->radky = radky;
        m->velikost = radky * sloupce;
        return m;
}

funkce, co mám:

struct Matice *novaMatice(int radky, int sloupce)
int sectiMatice(Matice A, Matice B, Matice *C)
int vynasobMatice(Matice A, Matice B, Matice *C)
void tisk(Matice A)
Editováno 8.4.2015 21:20
 
Odpovědět 8.4.2015 21:17
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na švrčajs
David Novák:

Tohle je projekt do programování v druhém semestru? :o :D
Jsou na vás nějak moc hodní..

No.. Co umíš? Dělal jsi nějaké I/O?
Před každou tou maticí máš zadané její rozměry.. Takže si je načteš, naalokuješ prostor a pak načteš jednotlivé řádky.. jelikož víš, kolik tam toho bude, tak to bude velmi jednoduchá funkce.
Jednotlivé hodnoty si převedeš pomocí strtod().. Hotovo ;)

Jo a jednotlivé matice jsou odděleny prázdnými řádky.. A navíc taky víš, kolik jich má být.. Ten vzorec na začátku musíš parsovat nebo je pevně zadaný? Asi parsovat, co? :)

Editováno 8.4.2015 23:50
Nahoru Odpovědět 8.4.2015 23:48
Chyba je mezi klávesnicí a židlí.
Avatar
švrčajs
Člen
Avatar
švrčajs:

Právě parsovat, napadlo mě, ten vzorec převést do pole charů a pak podle závorek udělat zásobník s výpočtama, ale to je jen můj teoretický odhad :D

 
Nahoru Odpovědět 9.4.2015 7:10
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na švrčajs
David Novák:

tak mohl bys udělat třeba pole struktur, ve kterých by byly operand1 a 2, operace a pořadí... :D
ale je to jedinná zajímavější věc, v tom zadání.. takže bys to měl udělat bez problému ;)

Nahoru Odpovědět 9.4.2015 8:21
Chyba je mezi klávesnicí a židlí.
Avatar
švrčajs
Člen
Avatar
švrčajs:

Sedím u toho skoro celý den :D a jediné co jsem vytvořil je rozpoznání, kdy se má vytvořit nová matice.. I když je to asi blbost...

char buffer[1024];
        //čtení jednotlivých řádků
        while (fscanf(psoubor, "\n", buffer) != EOF)
        {
                if (2 == sscanf(buffer, "%u %u", &radky, &sloupce))
                        {
                                Matice A;
                                A = novaMatice(radky, sloupce);


                        }
        }

To ostatní nemůžu nějak rozlousknout :/

 
Nahoru Odpovědět 9.4.2015 17:50
Avatar
Martin Dráb
Redaktor
Avatar
Martin Dráb:

Jestli to chápu dobře, tak vstupní soubor má následující formát:

<výraz>
<prázdný řádek>
<počet_řádků> <počet_sloupců>
<1. řádek matice>
....
<N. řádek matice>

Přičemž počet matic zjistíš z výrazu tak, že se podíváš, kolik různých písmen tam je (stačí projít ten řetězec a nepočítat znaky jako závorky, krát, plus...).

Můžeš si klidně načtení jedné matice zapouzdřit do funkce. Přes fscanf půjde načíst první řádek a zjistit počet sloupců a řádků oné matice. Pak je otázka, jak dál postupovat. Já bych asi jednotlivé řádky matice získal tak, že bych načetl celou řádku ze souboru, rozdělil na čísla podle mezer a přes atoi převedl (nebo možná atof, něco takového).

Tím získáš všechny matice a stačí jen provést výpočet, tedy vyhodnotit výraz. Možná by nebylo špatné použít převést jej do reverzní polské notace (postfix), pak se vyhodnocuje dobře.

Editováno 9.4.2015 18:48
Nahoru Odpovědět  +1 9.4.2015 18:48
2 + 2 = 5 for extremely large values of 2
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na Martin Dráb
David Novák:

jen k těm atoi, atof.. To jsou nebezpečné funkce.. Pokud opravdu neví, co dělá, tak by je neměl používat ;)

Předpokládám, že určitě budou chtít ošetření chybových stavů a neočekávaných vstupních dat.. takže by to měl asi zabít, kdyby mu tam napsali třeba písmeno.. A to pomocí atof snadno a spolehlivě nepoznáš

Nahoru Odpovědět  +1 9.4.2015 20:41
Chyba je mezi klávesnicí a židlí.
Avatar
švrčajs
Člen
Avatar
švrčajs:

takže dneska jsem udělal zjištění počtu matic, kde předám řádek a vyberu jen ty znaky..

int PocetMatic(char* radek[100])
{
        int i = 0, j = 0, pocet = 0;


        char znaky[10] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J' };
        for (i; i < 100; i++)
        {
                for (j; j < 10; j++)
                {
                        if(radek[i] == znaky[j])
                        {
                                pocet++;
                                znaky[j] = ' ';
                        }
                }
        }
        return pocet;
}

a taky plnění pole matice daty, to sice ještě nemám odzkoušené, ale...

int i = 0, j = 0, pocet, pruchod = -1, radky, sloupce, idmatice = -1, indexVradku = 0;
        char radek[100];
        Matice* poleMatic;

        //čtení jednotlivých řádků
        while (fscanf(psoubor, "\n", radek) != EOF)
        {
                //zadani
                if (pruchod == -1)
                {
                        pocet = (PocetMatic(radek));
                        poleMatic = (Matice*)malloc(pocet * sizeof(Matice));
                        pruchod = 0;
                        continue;
                }
                //prazdny radek
                else if (radek == NULL)
                {
                        pruchod = 0;
                        i = 0;
                        j = 0;
                        indexVradku = 0;
                        idmatice++;
                        continue;
                }

                else
                {
                        //pruchod = 0 značí, že jsem na řádku s rozměry => vytvoření nové matice
                        if (pruchod == 0)
                        {
                                radky = (int)radek[0];
                                sloupce = (int)radek[2];
                                poleMatic[idmatice] = novaMatice(radky, sloupce);
                                pruchod++;
                        }
                        //plnění matice
                        else
                        {

                                        for (i; i<poleMatic[idmatice]->sloupce; i++)
                                        {
                                                poleMatic[idmatice]->data[j * poleMatic[idmatice]->sloupce + i] = (double)radek[indexVradku];
                                                //zvětšení o 2, jelikoš mezery jsou liché znaky...
                                                indexVradku += 2;
                                        }
                                        //na jakém jsem řádku v dalším průchodu
                                        j++;
                                }
                        }
                }

ale s tím výpočtem bych potřeboval pomoct... popř, jak spustit konzolovku s parametry zadanýma v konzoli, neboli :D jak zjistím, co ze je za příkazem: aplikace.exe

Editováno 10.4.2015 22:04
 
Nahoru Odpovědět 10.4.2015 22:02
Avatar
David Novák
Tým ITnetwork
Avatar
David Novák:

To s těmi znaky máš zbytečně složité ;) A vůbec.. Nechápu moc, proč takhle.. :D Asi mi něco uniká.. máš to omezené na délku 100 znaků, což není úplně moc..

Kdybys to měl dovolené, řeknu, ať použiješ isalpha().. ale takhle si to budeš muset vytvořit.

Být tebou bych načítal prostě do konce řádku (po znacích) a uděláš jednoduchou podmínku:

if (znak >= 'A' && znak <= 'Z')
  // něco dělám - např. kontrola, jestli už takový znak znám, jestli ne, zvýší počet

A máš to ;) neomezené na délku výrazu.. a není to omezené jen na 10 různých písmen máš všech 26..

Nahoru Odpovědět 11.4.2015 1:21
Chyba je mezi klávesnicí a židlí.
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na David Novák
Martin Dráb:

jen k těm atoi, atof....

To máš pravdu, problém je v tom, že z návratové hodnoty se nedá poznat, zda-li se konverze povedla či ne. Bral jsem to spíš jako jednoduchý postup, jak celý ten příklad začít postupně rozcházet.

Nahoru Odpovědět  +1 11.4.2015 20:51
2 + 2 = 5 for extremely large values of 2
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na Martin Dráb
David Novák:

Jo, je mi to jasné.. ;)

A neměla to být kritika nebo tak.. Spíš jsem to řekl kvůli němu - je to začátečník, tak ať se neučí používat nebezpečné věci v reálných programech :)

Nahoru Odpovědět  +1 11.4.2015 20:55
Chyba je mezi klávesnicí a židlí.
Avatar
švrčajs
Člen
Avatar
Odpovídá na David Novák
švrčajs:

To s tím počtem matic upravím... Ale mám jiný problém, chci udělat funkci, která mi s daty předělá na double[], jako oddělovač bude logicky mezera :D ale problém je v tom, že nevím, jak to rozdělit... např. něco jako v c# string.split...

 
Nahoru Odpovědět 11.4.2015 21:26
Avatar
švrčajs
Člen
Avatar
švrčajs:
// KalkulackaZp2.cpp : Defines the entry point for the console application.
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define Nazev "nevim.txt"


struct Matice
{
        int radky;
        int sloupce;
        int pocetPrvku;
        double data[];
};

typedef struct Matice *Matice;

///vytvoření nové matice
struct Matice *novaMatice(int radky, int sloupce)
{
        struct Matice *m;

        m = calloc(sizeof m + radky * sloupce * sizeof(double), 1);
        m->sloupce = sloupce;
        m->radky = radky;
        m->pocetPrvku = radky * sloupce;
        return m;
}

//vrátí data z matice
double *VratData(Matice A)
{
        return A->data;
}


int sectiMatice(Matice A, Matice B, Matice *C)
{
        int i, pocetPrvku;
        double *ARadky, *BRadky, *CRadky;
pocetPrvku = A->radky * A->sloupce;

if ((*C)->pocetPrvku >= pocetPrvku)
{
        ARadky = A->data;
        BRadky = B->data;
        CRadky = (*C)->data;
}
else
{
        *C = novaMatice(A->radky, A->sloupce);
        ARadky = A->data;
        BRadky = B->data;
        CRadky = (*C)->data;
}

for (i = 0; i < pocetPrvku; i++)
{
        *CRadky++ = *ARadky++ + *BRadky++;
}

return 0;
}
int vynasobMatice(Matice A, Matice B, Matice *C)
{
        int i, j, k, pocetPrvku;
        double *ARadek, *BSloupec, *radek, *sloupec, *vystup, suma;
        if (A->sloupce == B->radky)
        {
                pocetPrvku = A->radky * B->sloupce;
                if (((*C)->pocetPrvku >= pocetPrvku))
                {
                        (*C)->radky = A->radky;
                        (*C)->sloupce = B->sloupce;
                }
                else
                {
                        *C = novaMatice(A->radky, B->sloupce);
                }

                vystup = (*C)->data;
                radek = ARadek = A->data;
                for (i = 0; i < A->radky; i++)
                {
                        sloupec = BSloupec = B->data;
                        for (k = 0; k < B->sloupce; k++, radek = ARadek, sloupec = ++BSloupec)
                        {
                                for (suma = 0, j = 0; j < A->sloupce; j++, radek++, sloupec += B->sloupce)
                                {
                                        suma += *radek * *sloupec;
                                }
                                *vystup++ = suma;
                        }
                        radek = (ARadek += A->sloupce);
                }
                return pocetPrvku;
        }
        return -1;
}

int PocetMatic(char *radek)
{
        int i, j, pocet = 0;


        char znaky[10] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J' };
        for (i = 0; i < 255; i++)
        {
                for (j = 0; j < 10; j++)
                {
                        if(radek[i] == znaky[j])
                        {
                                pocet++;
                                znaky[j] = '.';
                        }
                }
        }
        return pocet;
}


double* dataZtextu(char znaky[255], int sloupce)
{

}






void matice_print(Matice A)
{
        unsigned i, j;
        double *data;
        printf("%u %u\n", A->radky, A->sloupce);
        data = A->data;
        for (i = 0; i < A->radky; i++)
        {
                for (j = 0; j < A->sloupce; j++) {
                        printf("%g ", *data++);
                } putchar('\n');
        }
}

int main()
{

        int i = 0, j = 0, pocet, pruchod = -1, radky, sloupce, idmatice = -1, indexVradku = 0;
        char radek[255];
        Matice* poleMatic;
        FILE * psoubor;
        psoubor = fopen(Nazev, "r");
        if (psoubor == NULL)
        {
                printf("zadani je prazdne");
                return -1;
        }
        //čtení jednotlivých řádků
        //while (fscanf(psoubor, " %244[^\n]", radek) != EOF)

        while (fgets(radek, sizeof(radek), psoubor) != NULL)
        {
                //zadani
                if (pruchod == -1)
                {
                        pocet = (PocetMatic(radek));
                        poleMatic = (Matice*)malloc(pocet * sizeof(Matice));
                        pruchod++;
                        *radek = NULL;
                        continue;
                }
                //prazdny radek
                else if (radek[0] == '\n')
                {
                        pruchod = 0;
                        i = 0;
                        j = 0;
                        indexVradku = 0;
                        idmatice++;
                        *radek = NULL;
                        continue;
                }

                else
                {
                        //pruchod = 0 značí, že jsem na řádku s rozměry => vytvoření nové matice
                        if (pruchod == 0)
                        {
                                radky = (int)radek[0] - 48;
                                sloupce = (int)radek[2] - 48;
                                poleMatic[idmatice] = novaMatice(radky, sloupce);
                                pruchod++;
                                *radek = NULL;
                        }
                        //plnění matice
                        else
                        {

                                        for (i; i<poleMatic[idmatice]->sloupce; i++)
                                        {
                                                poleMatic[idmatice]->data[j * poleMatic[idmatice]->sloupce + i] = //pole pomocí dataZtextu (double)radek[indexVradku];
                                                //zvětšení o 2, jelikoš mezery jsou liché znaky...
                                                indexVradku += 2;
                                        }
                                        //na jakém jsem řádku v dalším průchodu
                                        j++;
                                        *radek = NULL;
                                }
                        }
                }












        system("pause");
        return 0;
}
 
Nahoru Odpovědět 11.4.2015 21:42
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na švrčajs
David Novák:

Tak buď použij funkci http://www.manpagez.com/man/3/strsep/ ;)

Nebo můžeš načítat po znacích do bufferu a ten pak převést pomocí strtod()

Nahoru Odpovědět 11.4.2015 21:58
Chyba je mezi klávesnicí a židlí.
Avatar
švrčajs
Člen
Avatar
Odpovídá na David Novák
švrčajs:

Díky..

Ještě jeden asi stupidní dotaz, pole struktur mám správně vytvořené ? Chyby mi to nehází, ale při debugu si procházím jednotlivé proměnné a po alokování pole matic se mi v tom poli zobrazí jen jedna matice, což neodpovídá počtu např. malloc(3*size­of(Matice))

Matice* poleMatic
poleMatic = (Matice*)malloc(pocet * sizeof(Matice));
 
Nahoru Odpovědět 12.4.2015 1:01
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na švrčajs
David Novák:

Debugger si s polem příliš nerozumí a pokud ho nenastavíš správně, získáš divné výsledky.. Doporučuju spíš vyzkoušet v praxi ;)

Ručně si to takhle naalokuj a nasypej tam požadovaný počet matic.. a pak to zkus z toho pole zase vypsat :)

Nahoru Odpovědět 12.4.2015 17:02
Chyba je mezi klávesnicí a židlí.
Avatar
švrčajs
Člen
Avatar
švrčajs:

Dodělal jsem to plnění dat a teď bych chtěl poprosit o pomoc s tím samotným počítáním. Vůbec nevím, jak na to, jediné co mě napadlo byla rekurze, ale...

 
Nahoru Odpovědět 14.4.2015 11:54
Avatar
David Novák
Tým ITnetwork
Avatar
Nahoru Odpovědět 14.4.2015 12:08
Chyba je mezi klávesnicí a židlí.
Avatar
švrčajs
Člen
Avatar
švrčajs:

napsat funkci, která přelouská to zadání(první řádek) a postupně zavolá, dle priority výpočtové funkce

 
Nahoru Odpovědět 14.4.2015 12:29
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na švrčajs
David Novák:

no.. to je jediná obtížnější věc v celém zadání.. ;)

Zkus popřemýšlet.. Vezmi papír a napiš si kroky, které bys jako člověk dělal, kdybys to měl zpracovat.

Nahoru Odpovědět 14.4.2015 12:52
Chyba je mezi klávesnicí a židlí.
Avatar
švrčajs
Člen
Avatar
švrčajs:

Tak já to beru tak, asi jako každý :D že se nejdřív podívám, jestli to obsahuje závorky, když jo, tak najdu to nejvnitřnější a pak to nabaluju, ale nevím, jak to naprogramovat :D

jinak tady ta funkce, která mi řádek převede na čísla..

double* dataZtextu(char* znaky, int sloupce)
{
        int i = 0, id = 0, ib = 0;
        double* data = (double *)malloc(sloupce * sizeof(double));
        char buffer[15];
        while (znaky[i] != NULL)
        {
                if (znaky[i] != ' ' && znaky[i] != '\n')
                {

                        buffer[ib] = znaky[i];
                        ib++;
                        i++;
                }
                else
                {
                        data[id] = (double)strtod(buffer, NULL);
                        ib = 0;
                        i++;
                        id++;
                        memset(buffer, ' ', sizeof(buffer));
                }

        }
        return data;

}
Editováno 14.4.2015 14:03
 
Nahoru Odpovědět 14.4.2015 14:02
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na švrčajs
David Novák:

Tak si to zkus rozepsat fakt po atomických krocích, co děláš (aniž si to uvědomuješ).. Např.

1. Podívám se na první znak
2. Je to levá závorka?
  ANO - Pamatuju si, že jsem ve výrazu.
3. Jdu na další znak.
4. Je to levá závorka?
  ANO - Jsem ve výrazu?
    ANO - Mám dva výrazy v sobě - musím najít dvě pravé závorky, abych měl kompletní výraz.
    NE - Jsem ve výrazu
5. Je to pravá závorka?
  ANO - Jsem ve výrazu?
    ANO - Potřebný počet pravých závorek k ukončení výrazu - 1; Je potřebný počet nulový?
      ANO - konec výrazu. Třeba si ho někam nakopíruju..
      NE - hledá se dál
    NE - pravá závorka a nejsem ve výrazu! Chyba!
atd.

Takhle nějak si to musíš rozložit na podproblémy.. ;) Všímej, že ty operace, co jsem prováděl jdou v C snadno napsat. Neber to ale, že by to muselo být tak, jak jsem řekl.. :D To jsem tu vymyslel během deseti minut jen tak.. Vůbec to nemusí fungovat.. A určitě je spousta dalších přístupů a nejspíš i nějaký lepší..

Prostě přemýšlej a zkoušej. Ber to tak, jako bys to parsování měl naučit někoho, kdo vůbec nic neumí. ;)

Nahoru Odpovědět 14.4.2015 14:32
Chyba je mezi klávesnicí a židlí.
Avatar
švrčajs
Člen
Avatar
švrčajs:

Jo, asi to bude hromada ifů :D... a když tak aplikace se má spouštět pomocí konzole (kalkulacka.exe vstup.txt vystup.txt), jak se dostanu k těm parametrům vstup a výstup ? Hledal jsem to na netu, ale docela z toho už chytám nervy :D tak jsem ni nenašel

 
Nahoru Odpovědět 14.4.2015 15:02
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na švrčajs
David Novák:

Podívej na seriál C a Linux - Filtry ;)

Nahoru Odpovědět 14.4.2015 15:06
Chyba je mezi klávesnicí a židlí.
Avatar
švrčajs
Člen
Avatar
švrčajs:

Nakonec to asi vyřeším pomocí Shunting-yard algoritmu

 
Nahoru Odpovědět 15.4.2015 15:50
Avatar
švrčajs
Člen
Avatar
švrčajs:

Takže, pokročil jsem, ale mám problém a nevím si s ním rady, když spustím program, tak mi to hodí error s přístupem do pamětiUnhandled exception at 0x00F516A1 in KalkulackaZp2.exe: 0xC0000005: Access violation reading location 0x00000041. u funkce sectiMatice(..)
Nemrkl by na to někdo ?
zde je celý kód programu

// KalkulackaZp2.cpp : Defines the entry point for the console application.
//

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

#define Nazev "nevim.txt"
#define POCETZNAKUNARADKU 255
///shunting-yard alg...

#define MAXOPSTACK 64
#define MAXNUMSTACK 64


enum { ASSOC_NONE = 0, ASSOC_LEFT, ASSOC_RIGHT };

struct Matice
{
        char* jmeno;
        int radky;
        int sloupce;
        int pocetPrvku;
        double data[];
};

typedef struct Matice *Matice;

///vytvoření nové matice
struct Matice *novaMatice(int radky, int sloupce, char jmeno)
{
        struct Matice *m;
        m = calloc(sizeof m + radky * sloupce * sizeof(double), 1);
        m->jmeno = jmeno;
        m->sloupce = sloupce;
        m->radky = radky;
        m->pocetPrvku = radky * sloupce;
        return m;
}

//vrátí data z matice
double *VratData(Matice A)
{
        return A->data;
}


double sectiMatice(Matice *A, Matice *B, Matice *C)
{
        int i, pocetPrvku;
        double *ARadky, *BRadky, *CRadky;
        pocetPrvku = (*A)->radky * (*A)->sloupce;

        if ((*C)->pocetPrvku >= pocetPrvku)
        {
                ARadky = (*A)->data;
                BRadky = (*B)->data;
                CRadky = (*C)->data;
        }
        else
        {
                *C = novaMatice((*A)->radky, (*A)->sloupce, 'X');
                ARadky = (*A)->data;
                BRadky = (*B)->data;
                CRadky = (*C)->data;
        }

        for (i = 0; i < pocetPrvku; i++)
        {
                *CRadky++ = *ARadky++ + *BRadky++;
        }

        return 0;
}
double vynasobMatice(Matice *A, Matice *B, Matice *C)
{
        /*int i, j, k, pocetPrvku;
        double *ARadek, *BSloupec, *radek, *sloupec, *vystup, suma;
        if ((*A)->sloupce == (*B)->radky)
        {
                pocetPrvku = (*A)->radky * (*B)->sloupce;
                if (((*C)->pocetPrvku >= pocetPrvku))
                {
                        (*C)->radky = (*A)->radky;
                        (*C)->sloupce = (*B)->sloupce;
                }
                else
                {
                        *C = novaMatice((*A)->radky, (*B)->sloupce, 'X');
                }

                vystup = (*C)->data;
                radek = ARadek = A->data;
                for (i = 0; i < A->radky; i++)
                {
                        sloupec = BSloupec = B->data;
                        for (k = 0; k < B->sloupce; k++, radek = ARadek, sloupec = ++BSloupec)
                        {
                                for (suma = 0, j = 0; j < A->sloupce; j++, radek++, sloupec += B->sloupce)
                                {
                                        suma += *radek * *sloupec;
                                }
                                *vystup++ = suma;
                        }
                        radek = (ARadek += A->sloupce);
                }
                return pocetPrvku;
        }*/
        return -1;
}

Matice EvalSoucet(Matice n, Matice m)
{
        Matice C = NULL;
        sectiMatice(n, m, &C);
        return C;
}

Matice EvalNasobeni(Matice n, Matice m)
{
        Matice C = NULL;
        vynasobMatice(n, m, &C);
        return C;
}



///předělat pomocí ifu...
int PocetMatic(char *radek)
{
        int i, j, pocet = 0;

        //dodělat na více znaků!
        char znaky[10] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J' };
        for (i = 0; i < POCETZNAKUNARADKU; i++)
        {
                for (j = 0; j < 10; j++)
                {
                        if(radek[i] == znaky[j])
                        {
                                pocet++;
                                znaky[j] = '.';
                        }
                }
        }
        return pocet;
}


double* dataZtextu(char* znaky, int sloupce)
{
        int i = 0, id = 0, ib = 0;
        double* data = (double *)malloc(sloupce * sizeof(double));
        char buffer[15];
        while (znaky[i] != NULL)
        {
                if (znaky[i] != ' ' && znaky[i] != '\n')
                {

                        buffer[ib] = znaky[i];
                        ib++;
                        i++;
                }
                else
                {
                        data[id] = (double)strtod(buffer, NULL);
                        ib = 0;
                        i++;
                        id++;
                        memset(buffer, ' ', sizeof(buffer));
                }

        }
        return data;

}

Matice vratMatici(char name, Matice pole[], int pocetMatic)
{
        int i = 0;


        for (i; i < pocetMatic;i++)
        {
                if (pole[i]->jmeno == name)
                {
                        return pole[i];
                        break;

                }

        }
        return 0;
}




void matice_print(Matice A)
{
        unsigned i, j;
        double *data;
        printf("%u %u\n", A->radky, A->sloupce);
        data = A->data;
        for (i = 0; i < A->radky; i++)
        {
                for (j = 0; j < A->sloupce; j++) {
                        printf("%g ", *data++);
                } putchar('\n');
        }
}



struct op_s {
        char op;
        int prec;
        int assoc;
        int unary;
        Matice (*eval)(Matice a1, Matice a2);

} ops[] = {
        { '*', 8, ASSOC_LEFT, 0, EvalNasobeni },
        { '+', 5, ASSOC_LEFT, 0, EvalSoucet },
        { '(', 0, ASSOC_NONE, 0, NULL },
        { ')', 0, ASSOC_NONE, 0, NULL }
};

struct op_s *getop(char ch)
{
        int i;
        for (i = 0; i < sizeof ops / sizeof ops[0]; ++i) {
                if (ops[i].op == ch) return ops + i;

        }
        return NULL;
}
struct op_s *opstack[MAXOPSTACK];
int nopstack = 0;

Matice numstack[MAXNUMSTACK];
int nnumstack = 0;

void push_opstack(struct op_s *op)
{
        if (nopstack>MAXOPSTACK - 1) {
                fprintf(stderr, "ERROR: Operator stack overflow\n");
                exit(EXIT_FAILURE);

        }
        opstack[nopstack++] = op;
}

struct op_s *pop_opstack()
{
        if (!nopstack) {
                fprintf(stderr, "ERROR: Operator stack empty\n");
                exit(EXIT_FAILURE);

        }
        return opstack[--nopstack];
}

void push_numstack(Matice M)
{
        if (nnumstack > MAXNUMSTACK - 1)
        {
                fprintf(stderr, "ERROR: Number stack overflow\n");
                exit(EXIT_FAILURE);

        }
        numstack[nnumstack++] = M;
}

Matice pop_numstack()
{
        if (!nnumstack) {
                fprintf(stderr, "ERROR: Number stack empty\n");
                exit(EXIT_FAILURE);

        }       return numstack[--nnumstack];
}


void shunt_op(struct op_s *op)
{
        struct op_s *pop;
        Matice n1, n2;
        if (op->op == '(')
        {
                push_opstack(op);
                return;

        }
        else if (op->op == ')')
        {
                while (nopstack > 0 && opstack[nopstack - 1]->op != '(') {
                        pop = pop_opstack();
                        n1 = pop_numstack();
                        if (pop->unary) push_numstack(pop->eval(n1, 0));
                        else
                        {
                                n2 = pop_numstack();
                                push_numstack(pop->eval(n2, n1));
                        }


                }
                if (!(pop = pop_opstack()) || pop->op != '(')
                {
                        fprintf(stderr, "ERROR: Stack error. No matching \'(\'\n");
                        exit(EXIT_FAILURE);

                }
                return;

        }

        if (op->assoc == ASSOC_RIGHT) {
                while (nopstack && op->prec < opstack[nopstack - 1]->prec)
                {
                        pop = pop_opstack();
                        n1 = pop_numstack();
                        if (pop->unary) push_numstack(pop->eval(n1, 0));
                        else
                        {
                                n2 = pop_numstack();
                                push_numstack(pop->eval(n2, n1));

                        }

                }

        }
        else
        {
                while (nopstack && op->prec <= opstack[nopstack - 1]->prec)
                {
                        pop = pop_opstack();
                        n1 = pop_numstack();
                        if (pop->unary) push_numstack(pop->eval(n1, 0));
                        else
                        {
                                n2 = pop_numstack();
                                push_numstack(pop->eval(n2, n1));

                        }

                }

        }
        push_opstack(op);
}












int main(int argc, char *argv[])
{

        int i = 0, j = 0, pocet, pruchod = -1, radky, sloupce, idmatice = -1, indexVpoli = 0, maticeJmeno = 'A';
        double* dataRadek;
        char radek[POCETZNAKUNARADKU];
        char zadani[POCETZNAKUNARADKU];
        Matice* poleMatic;
        FILE * psoubor;
        psoubor = fopen(Nazev, "r");
        if (psoubor == NULL)
        {
                printf("zadani je prazdne");
                return -1;
        }
        //čtení jednotlivých řádků
        //while (fscanf(psoubor, " %244[^\n]", radek) != EOF)

        while (fgets(radek, sizeof(radek), psoubor) != NULL)
        {
                //zadani
                if (pruchod == -1)
                {

                        memcpy(zadani, radek, strlen(radek) + 1);
                        pocet = (PocetMatic(radek));
                        poleMatic = (Matice*)malloc(pocet * sizeof(Matice));
                        pruchod++;
                        memset(radek, ' ', sizeof(radek));
                        continue;
                }
                //prazdny radek
                else if (radek[0] == '\n')
                {
                        pruchod = 0;
                        i = 0;
                        j = 0;
                        idmatice++;
                        memset(radek, ' ', sizeof(radek));
                        continue;
                }

                else
                {
                        //pruchod = 0 značí, že jsem na řádku s rozměry => vytvoření nové matice
                        if (pruchod == 0)
                        {
                                dataRadek = dataZtextu(radek, 2);
                                radky = (int)dataRadek[0];
                                sloupce = (int)dataRadek[1];
                                poleMatic[idmatice] = novaMatice(radky, sloupce, maticeJmeno);
                                maticeJmeno++;
                                pruchod++;
                                memset(dataRadek, 0, sizeof(dataRadek));
                                memset(radek, ' ', sizeof(radek));
                        }
                        //plnění matice
                        else
                        {
                                dataRadek = dataZtextu(radek, poleMatic[idmatice]->sloupce);

                                        for (i = 0; i<poleMatic[idmatice]->sloupce; i++)
                                        {
                                                poleMatic[idmatice]->data[j * poleMatic[idmatice]->sloupce + i] = dataRadek[i];


                                        }

                                        j++;
                                        memset(radek, ' ', sizeof(radek));

                                }
                        }
                }

        ///průběh výpočtu
        Matice *tstart = NULL;
        struct op_s startop = { 'X', 0, ASSOC_NONE, 0, NULL };
        struct op_s *op = NULL;
        Matice n1, n2;
        struct op_s *lastop = &startop;

        int indexwhile = 0;

        //printf("%i", zadani[0]);

        while (zadani[indexwhile] != '\n')
        {
                indexwhile++;
                if (!tstart)
                {

                        if ((op = getop(zadani[indexwhile-1]))) {
                                if (lastop && (lastop == &startop || lastop->op != ')'))
                                {

                                        if (op->op != '(')
                                        {
                                                fprintf(stderr, "ERROR: Illegal use of binary operator (%c)\n", op->op);
                                                exit(EXIT_FAILURE);

                                        }

                                }
                                shunt_op(op);
                                lastop = op;


                        }
                        else if (zadani[indexwhile-1] >= 'A' && zadani[indexwhile-1] <= 'Z')
                        {
                                tstart = vratMatici(zadani[indexwhile-1], poleMatic, pocet);///funkci, která vrátí matici, dle jména!!!!!!;
                                i++;
                        }
                        else if (!isspace(zadani[indexwhile-1]))
                        {
                                i++;
                                fprintf(stderr, "ERROR: Syntax error\n");
                                return EXIT_FAILURE;

                        }

                }
                else
                {
                        if (isspace(zadani[indexwhile-1]))
                        {
                                push_numstack(*tstart);
                                tstart = NULL;
                                lastop = NULL;
                                i++;
                        }
                        else if ((op = getop(zadani[indexwhile-1])))
                        {
                                push_numstack(*tstart);
                                tstart = NULL;
                                shunt_op(op);
                                lastop = op;
                                i++;
                        }
                        else if (!zadani[indexwhile-1] >= 'A' && zadani[indexwhile-1] <= 'Z')
                        {
                                fprintf(stderr, "ERROR: Syntax error\n");
                                i++;
                                return EXIT_FAILURE;

                        }

                }

        }
                if (tstart) push_numstack(*tstart);

                while (nopstack) {
                        op = pop_opstack();
                        n1 = pop_numstack();
                        if (op->unary) push_numstack(op->eval(n1, 0));
                        else {
                                n2 = pop_numstack();
                                push_numstack(op->eval(n2, n1));

                        }

                }
                        if (nnumstack != 1) {
                                fprintf(stderr, "ERROR: Number stack has %d elements after evaluation. Should be 1.\n", nnumstack);
                                return EXIT_FAILURE;

                        }
                matice_print(numstack[0]);









        system("pause");
        return 0;
}

a zadání:
(A + B)

2 3
1.1 1 2
4 5 6

3 4
1 2 3 4
5 6 7 8
9 0 1 2

 
Nahoru Odpovědět 22.4.2015 14:57
Avatar
švrčajs
Člen
Avatar
švrčajs:

takže :D tohle jsem si už vyřešil... Ale vyskytl se další problém, kalkulačka funguje, tak jak má, ovšem, když jí spustím pomocí konzole, předám vstupní a výstupní soubor, tak přestane pracovat... Dal jsem ladit a hodilo mi to ve VS error: Unhandled exception at 0x77165624 (ntdll.dll) in KalkulackaZp2.exe: 0xC0000374: Halda byla poškozena (parameters: 0x77181378). Chyba je v souboru malloc.c

takhle otevírám soubory...

FILE *s_vstup, *s_vystup;
s_vstup = fopen(*argv[0], "r");
s_vystup = fopen(*argv[1], "a+");

Neví někdo, kde by mohl být problém?

Editováno 24.4.2015 13:37
 
Nahoru Odpovědět  +1 24.4.2015 13:35
Avatar
Jakub Horák
Člen
Avatar
Odpovídá na švrčajs
Jakub Horák:

Pokud vím, tak v argv[0] je první věc na příkazovém řádku = jméno programu, který spouštíš. Parametry jsou až od argv[1].

 
Nahoru Odpovědět  +1 24.4.2015 14:43
Avatar
švrčajs
Člen
Avatar
švrčajs:

to jsem upravila na agrv[1], argv[2]... Kalkulačka se při spuštění pomocí cmd, dostane až k cyklu, kde se provádí samotný výpočet a tam spadne se stejným errorem :/ ale to už fakt nevím, co s tím, protože když do těch souborů dám napevno název a spustím ve visual studiu, tak to běží...

Editováno 25.4.2015 12:34
 
Nahoru Odpovědět 25.4.2015 12:34
Avatar
Odpovídá na švrčajs
Libor Šimo (libcosenior):

FILE *s_vstup, *s_vystup;
s_vstup = fopen(*argv[0], "r");
s_vystup = fopen(*argv[1], "a+");

Nemas to osetrene.

Nahoru Odpovědět  +1 25.4.2015 15:46
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
švrčajs
Člen
Avatar
Odpovídá na Libor Šimo (libcosenior)
švrčajs:

Tady v tom problém asi nebude.. Nebo spíše, co nemám ošetřené ? když je argv = NULL ?

 
Nahoru Odpovědět 25.4.2015 16:17
Avatar
Odpovídá na švrčajs
Libor Šimo (libcosenior):

Asi tak. Druha vec, ked ti toidevo VS av conzole nie, skes to v code blocks a daj si tam volby, ako pisal david novak v clanku o nom. Malby ti vypisat chyby.

Nahoru Odpovědět 25.4.2015 16:25
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Libor Šimo (libcosenior):

Boze, samy preklep :O

Nahoru Odpovědět 25.4.2015 16:26
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Libor Šimo (libcosenior):

Boze, samy preklep :O

Nahoru Odpovědět 25.4.2015 16:26
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
švrčajs
Člen
Avatar
Odpovídá na Libor Šimo (libcosenior)
švrčajs:

No :D v CodeBlocku se mi to ani nespustí :D ale určitě to bude nějaká kravinka :D asi se poptám učitele :D

 
Nahoru Odpovědět 25.4.2015 17:11
Avatar
Odpovídá na švrčajs
Libor Šimo (libcosenior):

Urcite sa neda skompilovat a vypisuje chyby ...

Nahoru Odpovědět 25.4.2015 17:15
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
švrčajs
Člen
Avatar
švrčajs:

no error list mám čistý, tak nevím no... Jinak na linku je celá appka (http://leteckaposta.cz/908170318) kdyby se někdo nudil a nešel by ten problém, byl bych hodně vděčný :D

 
Nahoru Odpovědět 25.4.2015 18:24
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na švrčajs
David Novák:

No.. Nevím, jestli je to tím, ale před argv se typicky hvězdička nedává :)

Navíc to rozhodně ošetři.. Nějak takhle:

if (!(s_vstup = fopen(argv[1], "r")))
{
   fprintf(stderr, "File cannot be open\n");
   return 1;
}

Pokud to problém neřeší, můžeš zkusit dosadit místo argv přímo název tvého souboru. Pokud to ani pak nebude fungovat, problém je jinde.. ;)

PS: Pokud bys sem znova dával celý kód, tak kdyžtak jen odkaz na nějaký pastebin nebo tak.. ;)

Nahoru Odpovědět  +1 25.4.2015 20:14
Chyba je mezi klávesnicí a židlí.
Avatar
švrčajs
Člen
Avatar
Odpovídá na David Novák
švrčajs:

No, když tam dosadím soubory ručně, tak se to vypočítá, vypíše se výsledná matice na konzoli, ale neuloží do souboru... Když to pustím pomocí cmd s parametrama, tak se jen načte zadání, vytvoří matice a pak to spadne, což je divné..

 
Nahoru Odpovědět 25.4.2015 20:23
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na švrčajs
David Novák:

tak to je problém asi s přístupovými právy k zápisu do souboru.. ;)

když ten soubor (do kterého chceš zapisovat) normálně otevřeš v notepad a změníš, jde bez problému uložit?

Nahoru Odpovědět 25.4.2015 20:27
Chyba je mezi klávesnicí a židlí.
Avatar
švrčajs
Člen
Avatar
švrčajs:

Jojo, normál ctrl+s a žádný message box.. bez problémů..

 
Nahoru Odpovědět 25.4.2015 20:29
Avatar
švrčajs
Člen
Avatar
švrčajs:

problém při tisknutí matice do souboru je v této funkci v souboru output.c

#else  /* _UNICODE */
                if (flags & (FL_LONG|FL_WIDECHAR)) {
                    if (text.wz == NULL) /* NULL passed, use special string */
                        text.wz = __wnullstring;
                    bufferiswide = 1;
                    pwch = text.wz;
                    while ( i-- && *pwch )
                        ++pwch;
                    textlen = (int)(pwch - text.wz);
                    /* textlen now contains length in wide chars */
                } else {
                    if (text.sz == NULL) /* NULL passed, use special string */
                        text.sz = __nullstring;
                    p = text.sz;
                    while (i-- && *p) //přesněji tady...
                        ++p;
                    textlen = (int)(p - text.sz);    /* length of the string */
                }

v mé funkci:

void uloz_matici_do_souboru(Matice A, char *soubor)
{
        printf("Uklada se matice do vystupniho souboru...");
        int i, j;
        double *data;
        fprintf(soubor,"%u u%\n", A->radky, A->sloupce);
        data = A->data;
        for (i = 0; i < A->radky; i++)
        {
                for (j = 0; j < A->sloupce; j++) {
                        fprintf(soubor, "%g ", *data++);

                }
                if (i < A->radky - 1) fprintf(soubor, "\n", NULL);
        }
}

Jakmile se projedou fory a funkce má končit, vyhodí to error... Zkoušel jsem i založit nový projekt, jestli jsem nepřepsal omylem vnitřní soubory, ale to taky nepomohlo.. Fakt už nevím, co s tím..

 
Nahoru Odpovědět 25.4.2015 20:54
Avatar
švrčajs
Člen
Avatar
Odpovídá na David Novák
švrčajs:

Překvapivě jednoduché řešení bylo místo fopen použit freopen, s tím to jede bez problémů... Ale furt je problém s tím, když to spustím pomocí té konzole, že mi to spadne a hodí to error s porušenou haldou ve funkci

__forceinline void * __cdecl _heap_alloc (size_t size)

{

    if (_crtheap == 0) {
#if !defined (_CRT_APP) || defined (_DEBUG)
        _FF_MSGBANNER();    /* write run-time error banner */
        _NMSG_WRITE(_RT_CRT_NOTINIT);  /* write message */
#endif  /* !defined (_CRT_APP) || defined (_DEBUG) */
        __crtExitProcess(255);  /* normally _exit(255) */
    }

    return HeapAlloc(_crtheap, 0, size ? size : 1);
}

v souboru malloc.c...

hledal jsem na netu i jiné způsoby, jak otevřít soubory pomocí te konzole, ale nic jsem nenašel...

Když to spustím konzolí, tak se načtou matice do pole, zadání do charu, ale samotný výpočet se již neprovede... Docela z toho chytám nervy, když ve VS to jde, ale pomocí konzole ne :D

// KalkulackaZp2.cpp : Defines the entry point for the console application.
//

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

#define Nazev "nevim.txt"
#define POCETZNAKUNARADKU 255
///shunting-yard alg...

#define MAXOPSTACK 64
#define MAXNUMSTACK 64


enum { ASSOC_NONE = 0, ASSOC_LEFT, ASSOC_RIGHT };

struct Matice
{
        char* jmeno;
        int radky;
        int sloupce;
        int pocetPrvku;
        double data[];
};

typedef struct Matice *Matice;

///vytvoření nové matice
struct Matice *novaMatice(int radky, int sloupce, char jmeno)
{
        struct Matice *m;
        m = calloc(sizeof m + radky * sloupce * sizeof(double), 1);
        m->jmeno = jmeno;
        m->sloupce = sloupce;
        m->radky = radky;
        m->pocetPrvku = radky * sloupce;

        return m;
}

//vrátí data z matice
double *VratData(Matice A)
{
        return A->data;
}

void matice_print(Matice A)
{
        int i, j;
        double *data;
        printf("%u %u\n", A->radky, A->sloupce);
        data = A->data;
        for (i = 0; i < A->radky; i++)
        {
                for (j = 0; j < A->sloupce; j++) {
                        printf("%d ", *data++);
                } putchar('\n');
        }
}
double sectiMatice(Matice A, Matice B, Matice *C)
{
        int i, pocetPrvku;
        double *ARadky, *BRadky, *CRadky;
        pocetPrvku = A->radky * A->sloupce;


        if ((*C)->pocetPrvku >= pocetPrvku)
        {
                ARadky = A->data;
                BRadky = B->data;
                CRadky = (*C)->data;
        }
        else
        {
                (*C) = novaMatice(A->radky, B->sloupce, ' ');
                ARadky = A->data;
                BRadky = B->data;
                CRadky = (*C)->data;
        }

        for (i = 0; i < pocetPrvku; i++)
        {
                *CRadky++ = *ARadky++ + *BRadky++;
        }

        return 0;
}
double vynasobMatice(Matice A, Matice B, Matice *C)
{
        int i, j, k, pocetPrvku;
        double *ARadek, *BSloupec, *radek, *sloupec, *vystup, suma;
        if (A->sloupce == B->radky)
        {
                pocetPrvku = A->radky * B->sloupce;
                if (((*C)->pocetPrvku >= pocetPrvku))
                {
                        (*C)->radky = A->radky;
                        (*C)->sloupce = B->sloupce;
                }
                else
                {
                        *C = novaMatice(A->radky, B->sloupce, 'X');
                }

                vystup = (*C)->data;
                radek = ARadek = A->data;
                for (i = 0; i < A->radky; i++)
                {
                        sloupec = BSloupec = B->data;
                        for (k = 0; k < B->sloupce; k++, radek = ARadek, sloupec = ++BSloupec)
                        {
                                for (suma = 0, j = 0; j < A->sloupce; j++, radek++, sloupec += B->sloupce)
                                {
                                        suma += *radek * *sloupec;
                                }
                                *vystup++ = suma;
                        }
                        radek = (ARadek += A->sloupce);
                }
                return pocetPrvku;
        }

}

Matice EvalSoucet(Matice n, Matice m)
{
        Matice C = novaMatice(0, 0, ' ');

        sectiMatice(n, m, &C);
        return C;
}

Matice EvalNasobeni(Matice n, Matice m)
{
        Matice C = novaMatice(0, 0, ' ');
        vynasobMatice(n, m, &C);
        return C;
}



///předělat pomocí ifu...
int PocetMatic(char *radek)
{
        int i, j, pocet = 0;

        //dodělat na více znaků!
        char znaky[12] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L' };
        for (i = 0; i < POCETZNAKUNARADKU; i++)
        {
                for (j = 0; j < 10; j++)
                {
                        if(radek[i] == znaky[j])
                        {
                                pocet++;
                                znaky[j] = '.';
                        }
                }
        }
        return pocet;
}


double* dataZtextu(char* znaky, int sloupce)
{
        int i = 0, id = 0, ib = 0;
        double* data = (double *)malloc(sloupce * sizeof(double));
        char buffer[15];
        while (znaky[i] != NULL)
        {
                if (znaky[i] != ' ' && znaky[i] != '\n')
                {

                        buffer[ib] = znaky[i];
                        ib++;
                        i++;
                }
                else
                {
                        data[id] = (double)strtod(buffer, NULL);
                        ib = 0;
                        i++;
                        id++;
                        memset(buffer, ' ', sizeof(buffer));
                }

        }
        return data;

}

Matice vratMatici(char name, Matice pole[], int pocetMatic)
{
        int i = 0;


        for (i; i < pocetMatic;i++)
        {
                if (pole[i]->jmeno == (char)name)
                {
                        return pole[i];
                }

        }
        return 0;
}

void uloz_matici_do_souboru(Matice A, char *soubor)
{
        printf("Uklada se matice do vystupniho souboru...");
        FILE *s_vystup;
        s_vystup = freopen(soubor, "w", stdout);


        int i, j;
        double *data;
        fprintf(s_vystup, "%i ", A->radky);
        fprintf(s_vystup, "%i\n", A->sloupce);
        data = A->data;
        for (i = 0; i < A->radky; i++)
        {
                for (j = 0; j < A->sloupce; j++) {
                        fprintf(s_vystup, "%.2f ", *data++);

                }
                fprintf(s_vystup, "\n", NULL);
        }


        fclose(s_vystup);
}







struct op_s {
        char op;
        int prec;
        int assoc;
        int unary;
        Matice (*eval)(Matice a1, Matice a2);

} ops[] = {
        { '*', 8, ASSOC_LEFT, 0, EvalNasobeni },
        { '+', 5, ASSOC_LEFT, 0, EvalSoucet },
        { '(', 0, ASSOC_NONE, 0, NULL },
        { ')', 0, ASSOC_NONE, 0, NULL }
};

struct op_s *getop(char ch)
{
        int i;
        for (i = 0; i < sizeof ops / sizeof ops[0]; ++i) {
                if (ops[i].op == ch) return ops + i;

        }
        return NULL;
}
struct op_s *opstack[MAXOPSTACK];
int nopstack = 0;
/////////////////
Matice numstack[MAXNUMSTACK];
int nnumstack = 0;

void push_opstack(struct op_s *op)
{
        if (nopstack>MAXOPSTACK - 1) {
                fprintf(stderr, "ERROR: Operator stack overflow\n");
                exit(EXIT_FAILURE);

        }
        opstack[nopstack++] = op;

}

struct op_s *pop_opstack()
{
        if (!nopstack) {
                fprintf(stderr, "ERROR: Operator stack empty\n");
                exit(EXIT_FAILURE);

        }
        return opstack[--nopstack];
}

void push_numstack(Matice M)
{
        if (nnumstack > MAXNUMSTACK - 1)
        {
                fprintf(stderr, "ERROR: Number stack overflow\n");
                exit(EXIT_FAILURE);

        }
        numstack[nnumstack++] = M;
}

Matice pop_numstack()
{
        if (!nnumstack) {
                fprintf(stderr, "ERROR: Number stack empty\n");
                exit(EXIT_FAILURE);

        }       return numstack[--nnumstack];
}


void shunt_op(struct op_s *op)
{
        struct op_s *pop;
        Matice n1, n2;
        if (op->op == '(')
        {
                push_opstack(op);
                return;

        }
        else if (op->op == ')')
        {
                while (nopstack > 0 && opstack[nopstack - 1]->op != '(') {
                        pop = pop_opstack();
                        n1 = pop_numstack();
                        if (pop->unary) push_numstack(pop->eval(n1, 0));
                        else
                        {
                                n2 = pop_numstack();

                                push_numstack(pop->eval(n1, n2));
                        }


                }
                if (!(pop = pop_opstack()) || pop->op != '(')
                {
                        fprintf(stderr, "ERROR: Stack error. No matching \'(\'\n");
                        exit(EXIT_FAILURE);

                }
                return;

        }

        if (op->assoc == ASSOC_RIGHT) {
                while (nopstack && op->prec < opstack[nopstack - 1]->prec)
                {
                        pop = pop_opstack();
                        n1 = pop_numstack();
                        if (pop->unary) push_numstack(pop->eval(n1, 0));
                        else
                        {
                                n2 = pop_numstack();
                                push_numstack(pop->eval(n2, n1));

                        }

                }

        }
        else
        {
                while (nopstack && op->prec <= opstack[nopstack - 1]->prec)
                {
                        pop = pop_opstack();
                        n1 = pop_numstack();
                        if (pop->unary) push_numstack(pop->eval(n1, 0));
                        else
                        {
                                n2 = pop_numstack();
                                push_numstack(pop->eval(n2, n1));

                        }

                }

        }
        push_opstack(op);
}












int main(int argc, char *argv[])
{
        //if (argv[1] = NULL || argv[2] = NULL) return EXIT_FAILURE;
        int i = 0, j = 0, pocet, pruchod = -1, radky, sloupce, idmatice = -1, indexVpoli = 0, maticeJmeno = 'A';
        double* dataRadek;
        char radek[POCETZNAKUNARADKU];
        char zadani[POCETZNAKUNARADKU];
        Matice* poleMatic;
        FILE *s_vstup;
        s_vstup = freopen(argv[1], "r", stdin);

        if (s_vstup == NULL)
        {
                printf("Zadani je prazdne...\n");
                return -1;
        }
        //čtení jednotlivých řádků
        //while (fscanf(s_vstup, " %244[^\n]", radek) != EOF)
        printf("Probiha nacteni zadani a vytoreni matic...\n");
        while (fgets(radek, sizeof(radek), s_vstup) != NULL)
        {
                //zadani
                if (pruchod == -1)
                {

                        memcpy(zadani, radek, strlen(radek) + 1);
                        pocet = (PocetMatic(radek));
                        poleMatic = (Matice*)malloc(pocet * sizeof(Matice));
                        pruchod++;
                        memset(radek, ' ', sizeof(radek));
                        continue;
                }
                //prazdny radek
                else if (radek[0] == '\n')
                {
                        pruchod = 0;
                        i = 0;
                        j = 0;
                        idmatice++;
                        memset(radek, ' ', sizeof(radek));
                        continue;
                }

                else
                {
                        //pruchod = 0 značí, že jsem na řádku s rozměry => vytvoření nové matice
                        if (pruchod == 0)
                        {
                                dataRadek = dataZtextu(radek, 2);
                                radky = (int)dataRadek[0];
                                sloupce = (int)dataRadek[1];
                                poleMatic[idmatice] = novaMatice(radky, sloupce, maticeJmeno);
                                maticeJmeno++;
                                pruchod++;
                                memset(dataRadek, 0, sizeof(dataRadek));
                                memset(radek, ' ', sizeof(radek));
                        }
                        //plnění matice
                        else
                        {
                                dataRadek = dataZtextu(radek, poleMatic[idmatice]->sloupce);

                                        for (i = 0; i<poleMatic[idmatice]->sloupce; i++)
                                        {
                                                poleMatic[idmatice]->data[j * poleMatic[idmatice]->sloupce + i] = dataRadek[i];


                                        }

                                        j++;
                                        memset(radek, ' ', sizeof(radek));

                                }
                        }
                }

        ///průběh výpočtu
        Matice tstart = NULL;
        struct op_s startop = { 'X', 0, ASSOC_NONE, 0, NULL };
        struct op_s *op = NULL;
        Matice n1, n2;
        struct op_s *lastop = &startop;

        int indexwhile = 0;

        printf("Probiha vypocet...\n");

        while (zadani[indexwhile] != '\n')
        {
                indexwhile++;
                if (!tstart)
                {

                        if ((op = getop(zadani[indexwhile-1]))) {
                                if (lastop && (lastop == &startop || lastop->op != ')'))
                                {

                                        if (op->op != '(')
                                        {
                                                fprintf(stderr, "ERROR: Illegal use of binary operator (%c)\n", op->op);
                                                exit(EXIT_FAILURE);

                                        }

                                }
                                shunt_op(op);
                                lastop = op;


                        }
                        else if (zadani[indexwhile-1] >= 'A' && zadani[indexwhile-1] <= 'Z')
                        {
                                tstart = vratMatici(zadani[indexwhile-1], poleMatic, pocet);///funkci, která vrátí matici, dle jména!!!!!!;
                                i++;
                        }
                        else if (!isspace(zadani[indexwhile-1]))
                        {
                                i++;
                                fprintf(stderr, "ERROR: Syntax error\n");
                                return EXIT_FAILURE;

                        }

                }
                else
                {
                        if (isspace(zadani[indexwhile-1]))
                        {
                                push_numstack(tstart);
                                tstart = NULL;
                                lastop = NULL;
                                i++;
                        }
                        else if ((op = getop(zadani[indexwhile-1])))
                        {
                                push_numstack(tstart);
                                tstart = NULL;
                                shunt_op(op);
                                lastop = op;
                                i++;
                        }
                        else if (!zadani[indexwhile-1] >= 'A' && zadani[indexwhile-1] <= 'Z')
                        {
                                fprintf(stderr, "ERROR: Syntax error\n");
                                i++;
                                return EXIT_FAILURE;

                        }

                }

        }
                if (tstart) push_numstack(tstart);

                while (nopstack) {
                        op = pop_opstack();
                        n1 = pop_numstack();
                        if (op->unary) push_numstack(op->eval(n1, 0));
                        else {
                                n2 = pop_numstack();
                                push_numstack(op->eval(n2, n1));

                        }

                }
                        if (nnumstack != 1) {
                                fprintf(stderr, "ERROR: Number stack has %d elements after evaluation. Should be 1.\n", nnumstack);
                                return EXIT_FAILURE;

                        }
                matice_print(numstack[0]);
                uloz_matici_do_souboru(numstack[0], argv[2]);

                return EXIT_SUCCESS;








        system("pause");
        return 0;
}
 
Nahoru Odpovědět 28.4.2015 17:32
Avatar
švrčajs
Člen
Avatar
švrčajs:

je to celé nějaké divné :D

Editováno 28.4.2015 21:21
 
Nahoru Odpovědět 28.4.2015 21:18
Avatar
Odpovídá na švrčajs
Libor Šimo (libcosenior):

A ko posledné je celý program, dal som to do Code:Blocks a nastavil:
gcc -std=c99 -Wall -Wextra -pedantic
Vyhodilo to 8 warningov a každý z nich môže spôsobovať problém. Tak sa najprv zbav warningov.
V prílohe.

Nahoru Odpovědět  +1 30.4.2015 7:46
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Odpovídá na švrčajs
Libor Šimo (libcosenior):

Začal som pomaly odstraňovať warningy a ukazujú sa stále nové errory aj warningy. Už sa mi nechce, je to na dlho.
VS podľa všetkého nedostatky v kóde odstráni sám, ale conzola nie. To musíš sám, ale odporúčam v Code:Blocks a pridaj si do volieb ešte aj -Werror, aby si to nemohol scompilovať, kým nebudú všetky warningy odstránené.
Voľby teda budú:
gcc -std=c99 -Wall -Wextra -Werror -pedantic

Navyše by si mal program písať ako projekt a podeliť ho na malé kompaktné časti, bude to podstatne prehľadnejšie.

Editováno 30.4.2015 12:27
Nahoru Odpovědět  +1 30.4.2015 12:25
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na švrčajs
David Novák:

hlavně mrkni na chyby na řádcích 34, 169, 199, 253.. to jsou obvykle největší "střelby do nohy".. jestli tam někde pracuješ s ukazatelem jako s číslem, nemůžeš se divit, že to nefunguje ;)

Nahoru Odpovědět  +1 30.4.2015 12:40
Chyba je mezi klávesnicí a židlí.
Avatar
Odpovídá na David Novák
Libor Šimo (libcosenior):

Presne tútu chybu som zanamenal niekoľko krát.

Nahoru Odpovědět 30.4.2015 12:42
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
švrčajs
Člen
Avatar
Odpovídá na Libor Šimo (libcosenior)
švrčajs:

Díky za rady, opravil jsem, co se dalo snad :D... Bohužel v CodeBlocku si to nespustím, jelikož mi háže error, že mu chybí GCC, i po doinstalování... a ve virtuálu je to strašně pomalé.. :(

 
Nahoru Odpovědět 30.4.2015 14:33
Avatar
švrčajs
Člen
Avatar
švrčajs:

Tak CodeBlock už jsem opravil :D ale teď mám problém, přidám si v CB do projektu txt soubory a když je chci otevřít, hodí to error s tím, že soubor nebyl nalezen..
cestu k souboru mám dobře...

s_vstup = freopen("C:\Users\Havana\Desktop\kalkulacka\vstup.txt", "r", stdin);
 
Nahoru Odpovědět 30.4.2015 15:10
Avatar
Jakub Horák
Člen
Avatar
Odpovídá na švrčajs
Jakub Horák:

V tom řetezci musíš místo "\" napsat "\\", protože "\" má v řetězci speciální funkci.

 
Nahoru Odpovědět 30.4.2015 16:51
Avatar
Odpovídá na švrčajs
Libor Šimo (libcosenior):

subor vstup.txt si uloz do zlozky, v ktorej mas exe subor

Nahoru Odpovědět 30.4.2015 18:26
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
švrčajs
Člen
Avatar
švrčajs:

tak jsem v cestě napsal všude \\ a i tak to nejde... Soubory bych si rád vložit, tam kde mám .exe, ale když to chci pustit pomocí codeblocku, tak se mi exe ani nevytvoří, protože nemůže najít soubor.. :D

 
Nahoru Odpovědět 30.4.2015 22:07
Avatar
Odpovídá na švrčajs
Libor Šimo (libcosenior):

ak sa ti program scompiluje, subor exe sa vytvori, asi ho nevies najst.

Nahoru Odpovědět 1.5.2015 7:55
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
švrčajs
Člen
Avatar
Odpovídá na Libor Šimo (libcosenior)
švrčajs:

No, projížděl jsem několikrát složku celého projektu, co vytvořil codeblock, a nic s příponou exe jsem nenašel...

Asi to stejně projedu ve virtuálu(linux), vygooglil jsem, že na chyby s mallocem.c je dobré použít valgrind...

 
Nahoru Odpovědět 1.5.2015 10:58
Avatar
švrčajs
Člen
Avatar
švrčajs:

Tak už asi vím, kde je chyba

struct Matice *novaMatice(int radky, int sloupce, char jmeno)
{
        //
        struct Matice *m;
        m = calloc(sizeof m + radky * sloupce * sizeof(double), 1); //tady se to zasekne, ale nevím,, co mu tam vadí :D
        m->jmeno = jmeno;
        m->sloupce = sloupce;
        m->radky = radky;
        m->pocetPrvku = radky * sloupce;

        return m;
}
 
Nahoru Odpovědět 1.5.2015 13:24
Avatar
Nahoru Odpovědět 1.5.2015 15:14
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 57 zpráv z 57.