Avatar
Michal Kuba
Redaktor
Avatar
Michal Kuba:

Ahoj.
Mám vytvořit program, který bude zpracovávat vstupy (ať už přímo v těle programu pomocí scanf a nebo argumenty napsané před zapnutím programu) a bude jednotlivé vstupy hodnotit, zda to jsou čísla, kalendářní datum, test na prvočíslo a detekci palindromu.

S céčkem víceméně začínám, i když už mám nějaké základy z Pascalu a poměrně slušnou zkušenost s PHP. Jenže s tímto problémem si nevím stoprocentně rady a než se pustím do psaní programu, rád bych měl nějaký začáteční impuls, jak se do něj pustit.

Budu rád za jakékoliv nápady, doporučení, kousky kódu atd :)

 
Odpovědět 31.10.2015 21:15
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na Michal Kuba
David Novák:

VUT FIT prvák? :D

Letos máte ten projekt nějaký jednoduchý.. Jinak bacha na používání jakéhokoliv cizího kódu.. Plagiátorství může být docela dost velký průser..

Co se týče implementace, tak se prvně zamysli nad tím, jak bys mohl definovat formát těch jednotlivých možností. Otázka - máte zakázané nějaké funkce?

Nahoru Odpovědět 31.10.2015 21:24
Chyba je mezi klávesnicí a židlí.
Avatar
Michal Žůrek (misaz):

doporučuji začít mainem a pak prostě zjišťovat co by to mohlo být. Začít nejkonktrétnějšími.

Nahoru Odpovědět 31.10.2015 21:41
Nesnáším {}, proto se jim vyhýbám.
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na David Novák
Michal Kuba:

Jojo, FITko :-D
Musím nějak rozlišit v těle programu rozlišit, že když se jedná o zapnutí programu bez argumentu, aby se zapnul například

int main()
{
}

a pokud budou zadány argumenty, tak nějaká jiná metoda?

Co se týče omezení, nemsíme používat hlavičkový soubor string.h, volání z rodiny malloc a free - práce s dynamickou pamětí, a potom volání z rodiny fopen, fclose, fscanf, ... - práce se soubory (dočasnými) není v tomto projektu žádoucí

 
Nahoru Odpovědět 31.10.2015 21:57
Avatar
Jozef
Člen
Avatar
Odpovídá na Michal Kuba
Jozef:

nie, stále ide o všetko v main, avšak musíš mu dať argumenty:

int main(int argc, char **argv)

a v prípade, že argumenty budeš brať pri zapnutí programu, nebudeš spracúvať text pomocou scanf, lebo jednotlivé vstupy budú už v argumente funkcie main char **argv

Nahoru Odpovědět 31.10.2015 22:04
I'm not afraid to die on a treadmill
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na Jozef
Michal Kuba:

Takže můžu na začátku mainu dát třeba podmínku

if(argc)
...

a vykonat tedy program pokud jsou zadané argumenty při spuštění a potom dám větev else, která bude mít totožné funkce na test čísla, palindromu atd, ale jen pro scanf?
takže spíš to nebude else ale

if(!argc)
{
}
 
Nahoru Odpovědět 31.10.2015 22:13
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na Michal Kuba
David Novák:

argc je vždy minimálně 1 - první argument (v argv[0]) je název programu.

Jinak alternativa k scanf je sscanf, která bere vstup ze stringu (přesněji pole znaků zakončené \0). Zapřemýšlel bych ale, jestli by nebylo lepší použít getc a řešit to po znacích (možná konečný automat?).

Nahoru Odpovědět 31.10.2015 22:25
Chyba je mezi klávesnicí a židlí.
Avatar
Jozef
Člen
Avatar
Odpovídá na Michal Kuba
Jozef:

Áno, niečo také. Ak v argc je číslo väčšie ako 1, použiješ metódy spracovania textu na jednotlivé položky char **argv . Dôležité je vedieť, že prvý argument, argv[0] je meno programu.
O zadávaní argumentov v C-éčku si môžeš prečítať napr. tu alebo prvých pár odsek ov tu

Editováno 31.10.2015 22:30
Nahoru Odpovědět 31.10.2015 22:27
I'm not afraid to die on a treadmill
Avatar
David Novák
Tým ITnetwork
Avatar
Nahoru Odpovědět  +1 31.10.2015 23:35
Chyba je mezi klávesnicí a židlí.
Avatar
Jozef
Člen
Avatar
Odpovídá na David Novák
Jozef:

to bude asi jednoduchšie :-D už je to asi zvyk, na všetko vyhľadávať anglické stránky

Nahoru Odpovědět  +2 31.10.2015 23:49
I'm not afraid to die on a treadmill
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na Jozef
Jan Vargovský:

To je normální, to dělají všichni :)

 
Nahoru Odpovědět  +1 1.11.2015 0:00
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na David Novák
Michal Kuba:

Joo, to je dobrý, tam jsem už koukal dřív :-)
Teď mě napadá, existují už nějaké "hotové" funkce, které když napíšu tak tím programu přímo říkám, že chci vědět, zda třeba argv[i] je číslo,znak nebo datum?

 
Nahoru Odpovědět 1.11.2015 10:39
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na Michal Kuba
David Novák:

Jsme v C... :D :D
Ne nadarmo se používá na výuku - skoro všechno si musíš udělat sám ;) A kdybys měl takové fce, tak by ten projekt byl na půl hodiny práce.. Na FITu se učí programovat, ne jak poskládat už hotové celky ;)

mrkni ale do ctype.h - tam jsou makra jako isdigit(), isalpha() apod. Pracují ovšem s jediným znakem, ne stringem.

Nahoru Odpovědět 1.11.2015 10:46
Chyba je mezi klávesnicí a židlí.
Avatar
Nahoru Odpovědět 1.11.2015 10:57
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na Libor Šimo (libcosenior)
Michal Kuba:

Asi zase triviální dotaz, ale lze bez knihovny string.h nějak každý argument rozložit na znaky, které potom porovnám, zda to jsou čísla, písmena atd..? program mi nechce běžet, protože funkce z ctype.h jsou na znaky a já tomu vkládám celé řetězce, byť to má jeden znak..

 
Nahoru Odpovědět 1.11.2015 11:47
Avatar
Jozef
Člen
Avatar
Odpovídá na Michal Kuba
Jozef:

máš dvojrozmetné pole znakov - keď použiješ argv[i] - tak berieš celý "riadok" znakov. Ak chceš iba jeden znak, musíš použiť toto: argv[i][j]

Nahoru Odpovědět 1.11.2015 11:50
I'm not afraid to die on a treadmill
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na Jozef
Michal Kuba:

jen pro ujasnění, celou dobu beru to, že jakoby argc je počet slov (argumentu) které zadám do terminálu a argv[i] potom reprezentuje každý argument.. jinak s tím přidáním "j" bude určitě správná cesta :) jen tam dám další cyklus for :)

 
Nahoru Odpovědět  +1 1.11.2015 11:52
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na Michal Kuba
David Novák:

Akorát je třeba počítat s tím, že první argument je název - takže začneš od i = 1 a jedeš dokud je i < argc..

Nahoru Odpovědět 1.11.2015 12:20
Chyba je mezi klávesnicí a židlí.
Avatar
Odpovídá na Michal Kuba
Libor Šimo (libcosenior):

Nemôžeš použiť funkciu strlen() z knižnice string.h, tak si ju napíšeš, napríklad:

#include <stdio.h>

int strlen(char *slovo)
{
    int velkost = 0;

    while (*slovo++ != '\0')
        velkost++;

    return velkost;
}

int main()
{
    char *slovo = "125485";

    printf("%d\n", strlen(slovo));

    return 0;
}
Nahoru Odpovědět 1.11.2015 12:47
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Libor Šimo (libcosenior):

Malý nástrel:

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

/** vrati pocet znakov v retazci */
int strlen(char *slovo)
{
    int velkost = 0;

    while (*slovo++ != '\0')
        velkost++;

    return velkost;
}

/** skontroluje ci je to cele cislo, ak ano, vrati ho, ank nie, vrati 0 */
int je_cislo(char *slovo)
{
    int i, vysledok = 0;
    char buffer[128] = "";

    for (i = 0; i < strlen(slovo); i++) {
        if (isdigit(slovo[i]))
            buffer[i] = slovo[i];
        else {
            break;
        }
    }
    if (strlen(buffer) == strlen(slovo)) {
        buffer[i + 1] = 0;
        vysledok = atoi(buffer);
    }
    return vysledok;
}

int main()
{
    char *slovo1 = "125485", *slovo2 = "125,485";

    printf("Slovo %s je cele cislo %d.\n", slovo1, je_cislo(slovo1));
    printf("Slovo %s je cele cislo %d.\n", slovo2, je_cislo(slovo2));

    return 0;
}
Nahoru Odpovědět 1.11.2015 13:07
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na Libor Šimo (libcosenior)
David Novák:

K čemu strlen?

for (i = 0; slovo[i] != '\0'; i++) {

Taky je naprosto zbytečné používat nějaký buffer a atoi... Jo a obecně používat buffer o pevné délce je problém - nevíš, jak dlouhé to může být.

int je_cislo(char *slovo)
{
  for (int i = 0; slovo[i] != '\0'; i++) {
    if (!isdigit(slovo[i])
      return 0;  // false
  }
  return 1;  // true
}
Nahoru Odpovědět  +2 1.11.2015 13:18
Chyba je mezi klávesnicí a židlí.
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na David Novák
Michal Kuba:

Dá se celej ten program napsat pouze v mainu? Nebo to je sebevražda? A délku řetězce znát nepotřebuju, abych určil číslo, nebo snad jo?

 
Nahoru Odpovědět 1.11.2015 13:40
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na David Novák
Michal Kuba:

Co dělám špatně, když se mi nedaří uložit hodnotu daného argumentu do proměnné číslo, pokud to číslo je?

for(i=1;i < argc; i++)
        {
         for(j=0; argv[i][j] != '\0'; j++)
         {
          if(isdigit(argv[i][j]))
          {
          cislo=argv[i];
          }
         }

Potom tam je podmínka, že jestli je číslo, tak se provede test na prvočíslo, ale to už by fungovat mělo..

 
Nahoru Odpovědět 1.11.2015 13:42
Avatar
Odpovídá na Michal Kuba
Libor Šimo (libcosenior):

Ja si robim testy, teda vypisal by som si vysledok casti kodu.

Nahoru Odpovědět 1.11.2015 13:58
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na Michal Kuba
David Novák:

cislo je int?

Doporučuji se trochu zaměřit na teorii polí a stringů v C.. argv[i] je první znak v i-tém argumentu. Takže ti to do cislo vždy dá první znak. Ale nechápu, co tím sleduješ..??

Je to ASCII znak.. Jestli s tím chceš pracovat jako s číslem, musíš to na číslo převést - doufám, že víš, jak se ascii znak číslice převádí na číslo.. Jestli ne, tak doporučuji urychleně studovat (např. Učebnice jazyka C od Herouta je dobrá).

Nahoru Odpovědět 1.11.2015 13:59
Chyba je mezi klávesnicí a židlí.
Avatar
Sony Nguyen
Redaktor
Avatar
Sony Nguyen:

Pokud je cislo typu int, tak se ti tam neuloží požadované číslo, ale ASCII číslo cisla, 0 má třeba hodnotu 0x30.

 
Nahoru Odpovědět 1.11.2015 13:59
Avatar
Odpovídá na Michal Kuba
Libor Šimo (libcosenior):

Myslim, ze toto
cislo=argv[i];
nebude fungovat.
Asi je treba to prekopirovat po jednom znaku a ukoncit znakom '\0'.

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

David mas pravdu, zbytocne som to komplikoval.

Editováno 1.11.2015 14:09
Nahoru Odpovědět  +1 1.11.2015 14:07
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na David Novák
Michal Kuba:

argv je snad celý argument, dokud není mezera, ne? protože když procházím argument znak po znaku tak [i] značí číslo argumentu a [j] potom pořadí znaku v celém řetězci, ne?

Takže snazší jak převod je nezavádět si vůbec cislo typu int?

 
Nahoru Odpovědět 1.11.2015 14:07
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na Michal Kuba
David Novák:

Délku řetězce znát nepotřebuješ.. Každý program se dá napsat jen do mainu.. Ale smrčka by ti utrhl hlavu.. :D

A navíc by se v tom nedalo vyznat. Pravidlo zní - kdykoliv se ti někde vyskytne stejný blok kódu vícekrát, udělej z toho funkci.

Nahoru Odpovědět 1.11.2015 14:08
Chyba je mezi klávesnicí a židlí.
Avatar
Odpovídá na Michal Kuba
Libor Šimo (libcosenior):

Sorry, neuvedomil som si, ze mas len vyhodnotit druh slova. Jasne, ze nepotrebujes nic prevadzat.

Nahoru Odpovědět 1.11.2015 14:12
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na Michal Kuba
David Novák:

argv je pole argumentů oddělených mezerami, ano. A s i a j máš také pravdu.. Proč to tedy v kódu tak nemáš? :)

Převod je jednoduchý.. A na ověřování prvočísla to asi budeš potřebovat.. Takže převést budeš muset. Jestli máte povoleno strtol, tak použij to, jinak si to udělej ručně. ze znaku uděláš číslo takto:

cislo = argv[i][j] - '0';

Pokud chceš převést řetězec, tak nejjednodušší je toto:

cislo = cislo*10 + (argv[i][j] - '0');
Nahoru Odpovědět  +2 1.11.2015 14:14
Chyba je mezi klávesnicí a židlí.
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na David Novák
David Novák:

(samozřejmě v cyklu - zkontroluješ zda je konkrétní znak číslice a provedeš tenhle převod. když narazíš na nečíslici, tak skončíš a vrátíš chybu)

Nahoru Odpovědět 1.11.2015 14:16
Chyba je mezi klávesnicí a židlí.
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na David Novák
Michal Kuba:

Nějak jsem to aspon trošku dokázal spustit, ale i tak - nedokáže to vypsat to číslo a na konec to ještě hodí tuto chybu: Neoprávněný přístup do paměti (SIGSEGV)

Tohle je prozatimní kód, ve kterém musím mít nějakou chybu, ale asi i díky malým zkušenostem ji nenajdu :(

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
 int i;
 int j;
 char *znak;
 char *cislice;
 int cislo;
 int prvocislo;
    if(argc > 1)
    {
        for(i=1;i < argc; i++)
        {
         for(j=0; argv[i][j] != '\0'; j++)
         {
          if(isdigit(argv[i][j]))
          {
        cislo=cislo*10 + (argv[i][j] - '0');
        printf("cislo: \n",&cislo);
         }
        }}
      if(cislo)
        {
         for(i=2; i < cislo; i++)
         {
          if(cislo % i)
           prvocislo=0;
           break;
         }
        if(prvocislo)
        printf("Number: %s (prvocislo) \n",cislo);
        else
        printf("Number: %s \n",cislo);
        }
}

Máte nějaký nápady někdo? :)
Vím že je to moje blbost, ale měl jsem kopu věcí a najednou musím rychle tenhle první program splácat a odevzdat..

 
Nahoru Odpovědět 1.11.2015 14:37
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na David Novák
Michal Kuba:

Nějak jsem to aspon trošku dokázal spustit, ale i tak - nedokáže to vypsat to číslo a na konec to ještě hodí tuto chybu: Neoprávněný přístup do paměti (SIGSEGV)

Tohle je prozatimní kód, ve kterém musím mít nějakou chybu, ale asi i díky malým zkušenostem ji nenajdu :(

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
 int i;
 int j;
 char *znak;
 char *cislice;
 int cislo;
 int prvocislo;
    if(argc > 1)
    {
        for(i=1;i < argc; i++)
        {
         for(j=0; argv[i][j] != '\0'; j++)
         {
          if(isdigit(argv[i][j]))
          {
        cislo=cislo*10 + (argv[i][j] - '0');
        printf("cislo: \n",&cislo);
         }
        }}
      if(cislo)
        {
         for(i=2; i < cislo; i++)
         {
          if(cislo % i)
           prvocislo=0;
           break;
         }
        if(prvocislo)
        printf("Number: %s (prvocislo) \n",cislo);
        else
        printf("Number: %s \n",cislo);
        }
}

Máte nějaký nápady někdo? :)
Vím že je to moje blbost, ale měl jsem kopu věcí a najednou musím rychle tenhle první program splácat a odevzdat..

 
Nahoru Odpovědět 1.11.2015 14:37
Avatar
Sony Nguyen
Redaktor
Avatar
Odpovídá na Michal Kuba
Sony Nguyen:
printf("Cislo: %d", &cislo);

To by mělo vyřešit problém s nevypsáním čísla :)
A taky bych raději dal na začátku do cisla nulu.

Editováno 1.11.2015 14:47
 
Nahoru Odpovědět  -1 1.11.2015 14:44
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na Michal Kuba
David Novák:

co má být tady toto?

printf("cislo: \n",&cislo);

&cislo ti vrátí adresu proměnné cislo a navíc printf neříkáš, že bys chtěl vypisovat proměnnou..

printf("cislo: %d\n",cislo);

Jinak tohle ti bude vypisovat hodnotu proměnné cislo po každém kroku převodu..

Další zásadní problém je, že nikde neinicializuješ prvocislo, takže je možné, že se do něj budeš dívat a bude tam blbost.
Je třeba int prvocislo = 1;

Jo a to stejné s cislo.. Tu k němu přistupuješ, aniž by tam byla rozumná hodnota..

cislo=cislo*10...;
int cislo = 0; // treba deklarovat takto

Tu ti chybí závorky - break se tak provede pokaždé..

if(cislo % i)
{
  prvocislo=0;
  break;
}

A tu se snažíš vypisovat int jako string:

printf("Number: %s \n",cislo);
printf("Number: %d \n",cislo); // spravne
Nahoru Odpovědět  +1 1.11.2015 14:48
Chyba je mezi klávesnicí a židlí.
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na David Novák
David Novák:

Jo a ještě:

if(cislo % i)
if(cislo % i == 0) // takhle

Modulo vrací nulu, když je zbytek nula (tedy cislo je delitelne i).

Nahoru Odpovědět 1.11.2015 14:49
Chyba je mezi klávesnicí a židlí.
Avatar
Sony Nguyen
Redaktor
Avatar
Odpovídá na Michal Kuba
Sony Nguyen:

Ještě bys měl mít na začátku

int prvocislo = 1;

Když ho kontroluješ jestli není.

 
Nahoru Odpovědět  +1 1.11.2015 14:49
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na David Novák
Michal Kuba:

No fakt že jo, dělalo tam spoustu věcí neplechu, díky :) Aspon už mi část toho funguje.. jen mi to ještě lepí všechny argumenty jako jeden.. když napíšu ./proj1 857 tak to správně vypíše že se jedná o prvočíslo, ale když napíšu ./proj1 8 57 tak to znovu napíše že 857 je prvočíslo.. řekl bych, že všechno dohromady lepím zde

if(isdigit(argv[i][j]))
         {
       cislo=cislo*10 + (argv[i][j] - '0');
        }

nebo ne?
Proč se mi to ukládá jako jedno číslo, když jsou argumenty odděleny mezerama?

 
Nahoru Odpovědět 1.11.2015 15:17
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na Michal Kuba
David Novák:

Po každém průchodu musíš číslo přirozeně vynulovat... :D

a tady v tomto cyklu bys to měl mít celé - včetně ověření prvočísla a vypsání výsledku:

for(i=1;i < argc; i++)
{
...
}

Nejlepší by bylo to pak rozsekat na funkce ;)

Nahoru Odpovědět 1.11.2015 15:25
Chyba je mezi klávesnicí a židlí.
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na David Novák
Michal Kuba:

jojo, na ten cyklus jsem hned po odeslání komentáře přišel, ale vynulovat jsem to zapomněl :-D Já to asi nechám až na příští projekt to rozsekávání na funkce, te´d bych se v tom ještě zamotal..

 
Nahoru Odpovědět 1.11.2015 15:28
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na Michal Kuba
David Novák:

Koho máš jako cvičícího?

Každopádně fakt doporučuji si máknout.. Máš půlku semestru a nevím, jak bys teď byl úspěšný v psaní něčeho podobného na papír.. Pujč si tu učebnici, zahoď IDE a programuj v texťáku a každý den aspoň několik hodin denně programuj.. Tyhle základy se budeš muset naučit ;)

Nahoru Odpovědět 1.11.2015 15:33
Chyba je mezi klávesnicí a židlí.
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na David Novák
Michal Kuba:

Na cvika mám Očenáška.
Já vím že čas kvapí, je to boj no.. Jinak k tomu psaní na papír - to se taky v prváku dělá? Třeba jako písemka?

jinak ten projekt dělám normálně v terminálu ve Vi editoru. Rozsekám to teď na ty funkce, ať je to snazší a přehlednější..

 
Nahoru Odpovědět 1.11.2015 15:35
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na Michal Kuba
David Novák:

Za vim máš mé úznání.. :D

No celý bakalář se dělají písemné zkoušky.. Je příliš mnoho studentů, aby byli zkoušeni ústně. Prakticky bys měl být schopen sednout a napsat program, který by měl fungovat. Nějaké drobné syntaktické chyby se tolik neřeší, ale určitě za ně jdou body dolů.

Z IZP je zkouška ve formě několika otázek typu "co tento kód udělá", pak nějaké deklarace většinou - "nadeklaruj ukazatel na pole ukazatelů na funkce vracející int" (toto je teda extrémní zadání.. bývají jednodušší :D

Dále tam najdeš nějaké zadání typu: "napiš program dělající xyz" nebo "doplň tělo funkce tak, aby ...." Plus i nějaké teoretické otázky.. Takže radím u smrčky dávat pozor ;)

Ale zas abych tě nevystrašil moc, tak průměrný programátor to v klidu dá na to E. Já jsem tehdy uměl o dost méně než teď a na zkoušku se mi nechtělo připravovat, takže jsem to dal na D.. :)

Nahoru Odpovědět 1.11.2015 15:44
Chyba je mezi klávesnicí a židlí.
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na David Novák
Michal Kuba:

To vím že je všechno písemně, což mě trošku uklidňuje..
Chtěl jsem nějaký lepší editor na terminálu než vim, který nám ukazují, ale žádný jiný z asi 15 co jsem našel není na merlinovi.

 
Nahoru Odpovědět 1.11.2015 15:47
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na Michal Kuba
David Novák:

Když se naučíš používat vim (zabere pár hodin), tak je to pak jednoznačně nejlepší editor.. ;)

Jinak to klidně můžeš dělat i u sebe (jestli linux nemáš jako hlavní OS nebo aspoň dualboot, tak stejně to tak budeš muset udělat příští semestr, kde se v něm bude dělat hodně.. A merlin bývá okolo deadline projektů dosti zasekaný, takže se na něm blbě tvoří.

Nahoru Odpovědět 1.11.2015 15:53
Chyba je mezi klávesnicí a židlí.
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na David Novák
Michal Kuba:

Tak deadline je až někdy za týden, tak zatím to teď jede dobře.. :-D

Ještě mě teď pořád trápí ten cyklus, že vypisuje jen jedno číslo a ne všechny z argumentů.. a to vždycky to cislo dám rovno nule, ale to se mi nezdá že by to mělo uplně na 100% fungovat..

for(i=1;i < argc; i++)
       {
        for(j=0; argv[i][j] != '\0'; j++)
        {
         if(isdigit(argv[i][j]))
         {
       cislo=cislo*10 + (argv[i][j] - '0');
        }
       }
     if(cislo)
       {
        for(i=2; i < cislo; i++)
        {
         if(cislo % i==0)
         {
          prvocislo=0;
          break;
         }
        }
       if(prvocislo){
       printf("Number: %d (prvocislo) \n",cislo);
       cislo=0;}
       else{
       printf("Number: %d \n",cislo);
       cislo=0;}
       }
       }
 
Nahoru Odpovědět 1.11.2015 15:56
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na Michal Kuba
Michal Kuba:

A když zadám více argumentů (okolo 6) tak to zacyklí celej program a furt dokola to vypisuje 1-3 čísla (argumenty).. jsem z toho úplně zmatenej :-D

 
Nahoru Odpovědět 1.11.2015 16:00
Avatar
tomisoka
Redaktor
Avatar
Odpovídá na Michal Kuba
tomisoka:

No tohle určitě není moc dobré:

for(i=1;i < argc; i++)
for(i=2; i < cislo; i++)
 
Nahoru Odpovědět  +1 1.11.2015 16:12
Avatar
Jan Vargovský
Redaktor
Avatar
Jan Vargovský:

Nauč se využívat debugger a pak tu nemusíš mít takové zmatené dotazy.

 
Nahoru Odpovědět  +2 1.11.2015 16:13
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na tomisoka
Michal Kuba:

No tak v prvním případě to počítá počet projitých argumentů a druhý je pro to prvočíslo, protože když to dám i=1 tak vše se dá dělit jedničkou, takže existuje víc jak 0 dělitelů - tudíž to není prvočíslo..

 
Nahoru Odpovědět 1.11.2015 16:20
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na Michal Kuba
David Novák:

Jde o to, že tam máš jednu proměnnou, kterou si přepisuješ tím druhým cyklem... ;)

Nahoru Odpovědět 1.11.2015 17:09
Chyba je mezi klávesnicí a židlí.
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na David Novák
Michal Kuba:

Joo, jasně. Ať už je to céčko nebo dřív když jsem začínal s PHP tak já vždy prehlidnu nějakou takovou defacto drobnost. Jak budu zase u pc tak to opravím a snad se zase pohnu dal. :-)

 
Nahoru Odpovědět 1.11.2015 17:40
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na David Novák
Michal Kuba:

Čím může být způsobena chyba SIGSEGV? Takhle - vše s čísly funguje, když chci zkusit ale zadat znak, vyhodí to chybu neoprávněného přístupu do paměti SIGSEGV.
Pro určení znaku mám zatím tento kus kódu, navíc se jen snažím vypsat, zda-li ho opravdu mám:

else if(isalpha(argv[i][j]))
         {
          printf("Word: %s \n", argv[i][j]);
         }
 
Nahoru Odpovědět 1.11.2015 20:12
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na Michal Kuba
Michal Kuba:

A na začátku mainu si definuji:

char znak;
 
Nahoru Odpovědět 1.11.2015 20:12
Avatar
Jozef
Člen
Avatar
Odpovídá na Michal Kuba
Jozef:

daj sem celý kód - už upravený, predpokladám, že nebude úplne rovnaký ako ten čo si sem dával predtým.

Nahoru Odpovědět 1.11.2015 20:37
I'm not afraid to die on a treadmill
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na Jozef
Michal Kuba:

Už to vypisuje, jde o to, že jsem to vypisoval jako string %s, stačilo to dát jako %c :)

Teď se spíš snažím nějak všechny ty znaky zadané v jednom argumentu nějak "slepit" dohromady jako jedno slovo.. Jdu dobrým směrem, když jsem si dal

char znak[100];

??

 
Nahoru Odpovědět 1.11.2015 20:42
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na Michal Kuba
Michal Kuba:

A potom se to snažím nějak vkládat do toho pole:

znak[j]=argv[i][j];
 
Nahoru Odpovědět 1.11.2015 20:44
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na Michal Kuba
David Novák:

Ano :)

Jinak sigsegv je neoprávněný přístup do paměti.. ;)

Nahoru Odpovědět 1.11.2015 20:52
Chyba je mezi klávesnicí a židlí.
Avatar
Jozef
Člen
Avatar
Odpovídá na Michal Kuba
Jozef:

áno, takto to môžeš spraviť, len nesmieš zabudnúť ako posledný člen poľa znak dať '\0'.
teda predpokladajme, že znak[posledne], je posledný člen, ktorému si už nejakú hodnotu zadal. Potom musiš spraviť toto:

znak[posledne + 1] = '\0';
Nahoru Odpovědět 1.11.2015 20:53
I'm not afraid to die on a treadmill
Avatar
Jozef
Člen
Avatar
Odpovídá na David Novák
Jozef:

On to aj sám napísal :)

vyhodí to chybu neoprávněného přístupu do paměti

Nahoru Odpovědět 1.11.2015 20:54
I'm not afraid to die on a treadmill
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na Jozef
David Novák:

Aha :D
Já jen viděl SIGSEGV a tak jsem dál nečetl..

Nahoru Odpovědět 1.11.2015 21:02
Chyba je mezi klávesnicí a židlí.
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na Jozef
Michal Kuba:

A jak v tom cyklu řeknu, že už je poslední a má to přidat ten koncový znak? Resp. ten znak "slepuje" celé slovo argumentu?

 
Nahoru Odpovědět 1.11.2015 21:05
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na Michal Kuba
David Novák:

napiš to prostě za ten cyklus :)

Nahoru Odpovědět 1.11.2015 21:08
Chyba je mezi klávesnicí a židlí.
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na David Novák
Michal Kuba:

No asi se mi to podařilo přidat za to, když zadám jeden znak, tak o to vypíše, ale když více, tak to vypíše pouze první..

if(znak)
             {
              znak[j+1]='\0';
              printf("Word: %c \n",*znak);
             }
 
Nahoru Odpovědět 1.11.2015 21:17
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na Michal Kuba
David Novák:

vypisuje to jeden znak, protože tomu říkáš, že chceš jeden znak.. :D

a proč tam máš tu dereferenci? o.O

Nahoru Odpovědět 1.11.2015 21:24
Chyba je mezi klávesnicí a židlí.
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na David Novák
Michal Kuba:
  1. Je tam dobře přidaný ten koncový znak? Je to až mimo ten cyklus, takže by to mělo k tomu "j" přičíst jedničku a dát třeba 4 a ne 1.
  2. Když tam není před tím znakem * nebo něco tak to nevypisuje to co chci. Hvězdičkou to dává aspoň jeden znak :-D
 
Nahoru Odpovědět 1.11.2015 21:34
Avatar
Jozef
Člen
Avatar
Odpovídá na Michal Kuba
Jozef:

keď už máš pole znakov null-terminated, tak používaj %s, teda

printf("Word: %s \n",znak);
Nahoru Odpovědět 1.11.2015 21:35
I'm not afraid to die on a treadmill
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na Jozef
Michal Kuba:

jj, došlo mi potom, že vypisuju znak :-D
Jen mi to v případě čtyřpísmenného slova dá nakonec jakýsi divný znak a někdy to při pětipísmenným slovu vynechá to poslední :-D

 
Nahoru Odpovědět 1.11.2015 21:41
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na Michal Kuba
David Novák:

to proto, že se ti nejspíš provede ještě poslední inkrementace, než podmínka skončí.
zkus dát jen znak[j] = '\0'

Nahoru Odpovědět 1.11.2015 21:45
Chyba je mezi klávesnicí a židlí.
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na David Novák
Michal Kuba:

S tímhle už to funguje.. ale myslel jsem, že tam to +1 je správně, aby se právě ten poslední znak nesmazal.. ale tím zpětným lomítkem se nestane, že by se poslední znak přemazal, že?

 
Nahoru Odpovědět 1.11.2015 21:47
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na Michal Kuba
David Novák:

No není to zpětným lomítkem.. tím jen dáváš najevo, že tam opravdu chceš dát nulu a ne znak nula..

Hoď sem ten cyklus a zkus si ho vykrokovat.. Uvidíš, proč tam bude v tomto případě j a ne j+1

Nahoru Odpovědět 1.11.2015 21:51
Chyba je mezi klávesnicí a židlí.
Avatar
Odpovídá na Michal Kuba
Libor Šimo (libcosenior):

Michal, vidím, že stále tápeš v tých reťazcoch. Ak chceš prečítaj si toto: http://www.freespace.sk/…5%a1kola-r25
Je to časť o reťazcoch a zdrojom článku bola knižka od Herouta.

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

Vyskúšaj toto:

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

/**
* Funkcia skontroluje, ci retazec obsahuje iba jednu desatinnu botku,
* ak ich obsahuje viac,vrati false
* skontroluje, ci vstupny retazec obsahuje iba cislice a maximalne jednu bodku,
* ak nie, prvy odlisny znak zapise na prvu poziciu retazca
* @param vstupny retazec
* @return 1 (true) alebo 0 (false)
*/
int je_cislo(char *number)
{
    int i, point = 0;

    for (i = 0; number[i] != '\0'; i++) {
        /** spocita pocet bodiek **/
        if (number[i] == '.') {
            point++;
            /** ak je bodiek viac ako 1, return 0 **/
            if (point > 1)
                return 0;
        }
        /** ak je znak iny ako cislica alebo bodka, return 0 **/
        if (!isdigit(number[i]) && number[i] != '.') {
            return 0;
        }
    }
    return 1;
}

int main(int argc, char **argv)
{
    int i;

    for (i = 1; i < argc; i++) {
        if (je_cislo(argv[i])) {
            printf("Retazec %s je cislo.\n", argv[i]);
        }
        else
            printf("Retazec %s nie je cislo.\n", argv[i]);
    }

    return 0;
}
Nahoru Odpovědět 2.11.2015 7:38
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Libor Šimo (libcosenior):

Malá oprava v popise funkcie.
namiesto

  • ak nie, prvy odlisny znak zapise na prvu poziciu retazca

má byť

  • ak nie, vráti false
Nahoru Odpovědět 2.11.2015 7:56
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na David Novák
Michal Kuba:

Snažím se funkcí získat délku řetězce, ale nechce se mi to přeložit:

int strlen(char **znak)
{
 int velikost=0;
  while(znak++ !='\0')
   velikost++;
  return velikost;
}
 printf("Delka: %d\n",strlen(*znak));

Vyzkoušel jsem ještě různě ty ukazatele, ale furt to háže chybu, hlavně u toho, že do strlen vkládám znak a je tam konflikt typů :-(

 
Nahoru Odpovědět 2.11.2015 10:47
Avatar
Libor Šimo (libcosenior):

int strlen(char *retazec)
-
-
-
main()
{
printf("Delka: %d\n", strlen(retazec));

Nahoru Odpovědět 2.11.2015 12:54
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Odpovídá na Michal Kuba
Libor Šimo (libcosenior):

To som tu už ale písal:

/** vrati pocet znakov v retazci */
int strlen(char *slovo)
{
    int velkost = 0;

    while (*slovo++ != '\0')
        velkost++;

    return velkost;
}
Nahoru Odpovědět 2.11.2015 12:56
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Libor Šimo (libcosenior):

A tu máš funkciu na palindrom:

int je_palindrom(char * retazec)
{
    int i, velkost, pom = strlen(retazec);
    int j = pom - 1;

    for (i = 0; i < pom / 2; i++) {
        if (retazec[i] != retazec[j--])
            return 0;
    }
    return 1;
}
Nahoru Odpovědět 2.11.2015 13:57
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Libor Šimo (libcosenior):

Výpis vstupov argumentami v konzole.

Nahoru Odpovědět 2.11.2015 14:58
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na Libor Šimo (libcosenior)
Michal Kuba:

Díky moc.. Já vím že jeden kód jsi už posílal, ale on mi ne a ne fungovat.. resp. když to dělám teď u sebe v IDE tak to jede, když to pak překládám na terminálu na školním serveru tak to vyhodí chybu právě u toho int strlen ale funguje to potom správně..

 
Nahoru Odpovědět 2.11.2015 15:19
Avatar
Nahoru Odpovědět 2.11.2015 15:21
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Odpovídá na Michal Kuba
Libor Šimo (libcosenior):

Možno treba len premenovať funkciu zo strlen() na niečo iné, napr.: dlzka_retazca(). To preto, ak ten server kontroluje funkcie z knižnice string.h.

Nahoru Odpovědět 2.11.2015 15:24
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na Libor Šimo (libcosenior)
Michal Kuba:

Wow, měl jsi pravdu :) fungovalo to, jen tomu vadil ten název, tak jsem pro pořádek to změnil na delka_slova :-)

Díky :) Už jen udělám rozpoznání data a mám hotovo..

 
Nahoru Odpovědět 2.11.2015 15:51
Avatar
Odpovídá na Michal Kuba
Libor Šimo (libcosenior):

S datumom to moze byt zlozitejsie. Zalezi na jeho formate. Ak je zarucene, ze bude dd.mm.rrrr, je to jednoduche, ale ak bude moznost aj d.m.rrrr, uz musis pocitat s kazdou moznostou, teda aj s d.mm.rrrr a dd.m.rrrr.

Editováno 2.11.2015 16:48
Nahoru Odpovědět 2.11.2015 16:47
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na Libor Šimo (libcosenior)
Michal Kuba:

bude ve formátu DD-DD-DDD (D=0-9), ale musím ještě určit i den v týdnu (Po-Ne) resp. (Mon-Sun)

 
Nahoru Odpovědět 2.11.2015 18:11
Avatar
Jozef
Člen
Avatar
Nahoru Odpovědět 2.11.2015 18:24
I'm not afraid to die on a treadmill
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na Jozef
Michal Kuba:

nechám si to v záloze, nejdřív udělám v cyklu rozpoznání vůbec toho formátu, zda je to tak zadané.

 
Nahoru Odpovědět 2.11.2015 18:43
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na Michal Kuba
Michal Kuba:

teda formát má být DDDD-DD-DD, ale to je vlastně fuk :-D

 
Nahoru Odpovědět 2.11.2015 18:44
Avatar
Jozef
Člen
Avatar
Odpovídá na Michal Kuba
Jozef:

Lebo neviem, ako by si bez toho, čo som ti posielal, resp. niečoho podbného zistil, o aký deň sa jedná. Dostaneš zadané 17.11.1985 a ako zistíš, či to bol pondelok, utorok...? Pomocou toho čo som posielaj ti to hneď napíše

Nahoru Odpovědět 2.11.2015 18:58
I'm not afraid to die on a treadmill
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na Jozef
Michal Kuba:

Jo, to bezesporu použiju :-)
jen musím někam do svýho kódu, zřejmě hnedka někam na začátek cyklu

if(argc > 0)
    {
        for(i=1;i < argc; i++)
        {
         for(j=0; argv[i][j] != '\0'; j++)
         {
          if(isdigit(argv[i][j]))
          {
           cislo=cislo*10 + (argv[i][j] - '0');
          }
          else if(isalpha(argv[i][j]))
          {
          znak[j]=argv[i][j];
          }
         }
         if(cislo)
           {
            for(k=2; k < cislo; k++)
            {
             if(cislo % k==0)
             {
              prvocislo=0;
              break;
             }
            }
           if(prvocislo)
           {
            printf("Number: %d (prvocislo) \n",cislo);
            cislo=0;
           }
           else
           {
            printf("Number: %d \n",cislo);
            cislo=0;
           }
           }
           else if(znak)
             {
              znak[j]='\0';
              if(je_palindrom(znak))
                printf("Word: %s (palindrom)\n",znak);
              else
                printf("Word: %s \n",znak);
             }
        }
    }

hodit podmínku, která se vykoná, pokud vstup bude ve formátu DDDD-DD-DD a pokud to nebude takový formát, tak se provedou ostatní testy isdigit nebo is alpha.. nebo to je blbost?

 
Nahoru Odpovědět 2.11.2015 19:02
Avatar
Jozef
Člen
Avatar
Odpovídá na Michal Kuba
Jozef:

a ten dátum bude teda zadaný napr. takto: 2015-10-20 ? teda yyyy-mm-dd ? čísla oddelené pomlčkou alebo proste medzerou?

Nahoru Odpovědět 2.11.2015 19:06
I'm not afraid to die on a treadmill
Avatar
Jozef
Člen
Avatar
Odpovídá na Michal Kuba
Jozef:

Tak v tom prípade to je ľahké. Keď narazíš na pomlčku, vieš, že ide o dátum. (Predpokladám, že nedostaneš vstup "Ahoj_ako" ani nič podobné)

Nahoru Odpovědět 2.11.2015 22:23
I'm not afraid to die on a treadmill
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na Jozef
Michal Kuba:

No zkusil jsem otrocky napsat toto:

if(sizeof(argv[i])==10)
            {
                if(!(isdigit(argv[i][1])) &&!(isdigit(argv[i][2])) &&!(isdigit(argv[i][3])) &&!(isdigit(argv[i][4]))&&(argv[i][5]!='-')&&!(isdigit(argv[i][6]))&&!(isdigit(argv[i][7]))&&(argv[i][8]!='-')&&!(isdigit(argv[i][9]))&&!(isdigit(argv[i][10])))
                {
                    break;
                }
                else
                {
                    for(l=0;l<10;l++)
                    {
                        printf("%s\n",argv[i]);
                        /*datum[l]=argv[l];*/
                    }

                }

            }

Jenže to nechce fungovat jak bych chtěl.. prostě to jakoby přeskočí a potom to přijde až na to, že se jedná o číslo a pomlčky to vymaže..

 
Nahoru Odpovědět 2.11.2015 22:27
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na Michal Kuba
Michal Kuba:

tak zjištění a ověření dvojité zda-li se skutečně jedná o tvar YYYY-MM-DD jsem již zvládl, teď ještě konkrétně rozpoznat přesný den v týdnu..

 
Nahoru Odpovědět 2.11.2015 23:42
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na Michal Kuba
David Novák:

Nemáš náhodou za chvíli deadline? :D

Jinak určitě průběžně tam nahrávej aktuální verzi, co tam máš.. Někteří cvičící ti pak dají možnost opravy na získání dalších bodů-- ale musíš tam aspoň něco už mít ;)

Nahoru Odpovědět 2.11.2015 23:54
Chyba je mezi klávesnicí a židlí.
Avatar
Michal Kuba
Redaktor
Avatar
Odpovídá na David Novák
Michal Kuba:

Průběžně to tam nahrávám :) Odevzdáno to má být až v neděli, na obhajobu na cviku jsem aspoň částečně ready :-D

 
Nahoru Odpovědět  +1 3.11.2015 0:10
Avatar
Nahoru Odpovědět 3.11.2015 12:18
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
David Novák
Tým ITnetwork
Avatar
Odpovídá na Michal Kuba
David Novák:

co to sakra je? :D

Stačí cyklem procházet ten jeden argument a kontrolovat, že jsou tam čísla. když narazíš na pomlčku, tak ty předchozí čísla uložíš do struktury tm (viz. http://www.cplusplus.com/…time/mktime/), zkontroluješ asi rozsahy (to nevím, jestli mktime umí) a pomocí mktime zjistíš, co to bylo za den..

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

Je fakt, že ten jeho kód vyzerá hrozne a je to poriadna špageta. :-D
Ináč som našiel na nete pekný algoritmus na deň v týždni bez knižnice time.h:

int den_v_tyzdni(int d, int m, int y)
{
    static int t[] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 };
    y -= m < 3;
    return ( y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
}
Nahoru Odpovědět 3.11.2015 13:35
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 102 zpráv z 102.