NOVINKA! E-learningové kurzy umělé inteligence. Nyní AI za nejlepší ceny. Zjisti více:
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Diskuze: Pomoc s Visual Studio 2017

V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
Lukino Papadu Hasprún:27.10.2017 16:46

Ahojte,

Potreboval by som pomoct s jednym programom, ktore sme dostali v skole:

Napíšte program, ktorý z poľa znakov vymaže všetky výskyty podreťazca ako trojice znakov. Obsah poľa najviac 50 znakov načítajte ako prvý riadkok vstupu zo štandardného vstupu. Druhý riadok vstupu bude obsahovať 3 znaky. Výstupom programu bude obsah poľa po zmazaní všetkých výskytov 3-znakového podreťazca.
Ukážkový vstup:
qwertabcasdfabczxc↵
abc↵
Ukážkový výstup:
qwertasdfzxc↵

Toto je moj kod, ktory som napisal:

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char c[50], b[50], a[4];
int i, j = 0;
scanf("%49s", c);
scanf("%s", a);
for (i = 0; c[i] != '\0'; i++)
{
if (c[i] == a[0] && c[i + 1] == a[1] && c[i + 2] == a[2])
{
i += 2;
continue;
}
else
{
b[j] = c[i];
j++;
}
}
printf("%s\n", b);
system("PAUSE");
return 0;
}

A toto je jeho vystup:

dadnaslndasndsnadnsaldnsladn
dad
naslndasndsnadnsaldnsladn╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠dadnaslndasndsnadnsaldnsladn
Press any key to continue . . .

Vedel by mi niekto povedat co tam mam zle a hlavne preco mi to vypisuje nejake symboly ktore tam ani nema? Predom dakujem.

 
Odpovědět
27.10.2017 16:46
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Lukino Papadu Hasprún
DarkCoder:27.10.2017 18:56

K tvému programu:

  • pokud funkce nemá parametry, používej void
  • je dobré proměnné značit smysluplnějšími názvy
  • pro načítání řetězců používej gets()
  • výraz c[i] != '\0' je lépe zapisovat c[i]
  • je nezbytné hlídat si meze polí. Porovnáváš hodnoty které jsou mimo rozsah! Podmínka v cyklu je platná při:
i <= (strlen(c)-strlen(a))
  • výstup je chybný protože pole znaků má být řetězec, ale ten nemáš ukončen nulovým znakem. Za for cyklem:
b[j] = '\0';
Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
Nahoru Odpovědět
27.10.2017 18:56
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Lukino Papadu Hasprún:28.10.2017 17:39

Dakujem uz to funguje ako ma :)

 
Nahoru Odpovědět
28.10.2017 17:39
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Lukino Papadu Hasprún
DarkCoder:28.10.2017 18:24

Není zač, poděl se o své řešení s ostatními. Mě osobně zajímá, zda-li si se úspěšně vyvaroval chyby s rozsahem pole.

Editováno 28.10.2017 18:25
Nahoru Odpovědět
28.10.2017 18:24
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Lukino Papadu Hasprún:28.10.2017 23:58
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


int main(void)
{
        char retazec[51], podretazec[4], novy_retazec[51];
        int i = 0, j = 0;
        fgets(retazec, 51, stdin);
        int buffer = strlen(retazec) - 1;
        if ((buffer > 0) && (retazec[buffer] == '\n')) retazec[buffer] = '\0';
        setbuf(stdin, NULL);
        fgets(podretazec, 4, stdin);
        buffer = strlen(podretazec) - 1;
        if ((buffer > 0) && (podretazec[buffer] == '\n')) podretazec[buffer] = '\0';
        setbuf(stdin, NULL);
        while (retazec[i] != '\0')
        {
                if ((retazec[i] == podretazec[0]) && (retazec[i + 1] == podretazec[1]) && (retazec[i + 2] == podretazec[2])) i += 3;
                else
                {
                        novy_retazec[j] = retazec[i];
                        j++;
                        i++;
                }
        }
        novy_retazec[j] = '\0';
        puts(novy_retazec);
        system("PAUSE");
        return 0;
}

Ano nejako sa mi to podairlo vyriesit :)

 
Nahoru Odpovědět
28.10.2017 23:58
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Lukino Papadu Hasprún
DarkCoder:29.10.2017 13:47

Jsi si jist že následující část programu je korektní?

if ((retazec[i] == podretazec[0]) && (retazec[i + 1] == podretazec[1]) && (retazec[i + 2] == podretazec[2])) i += 3;
Nahoru Odpovědět
29.10.2017 13:47
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Neaktivní uživatel:29.10.2017 16:33

výraz c[i] != '\0' je lépe zapisovat c[i]

Proč?

Editováno 29.10.2017 16:33
Nahoru Odpovědět
29.10.2017 16:33
Neaktivní uživatelský účet
Avatar
Odpovídá na Neaktivní uživatel
Luboš Běhounek Satik:29.10.2017 16:45

je to podobný jako psát

if (neco == true)
nebo
if (pNeco == NULL)

misto

if (neco)
nebo
if (pNeco)

je to zbytecne delsi

Editováno 29.10.2017 16:45
Nahoru Odpovědět
29.10.2017 16:45
https://www.facebook.com/peasantsandcastles/
Avatar
Odpovídá na Luboš Běhounek Satik
Neaktivní uživatel:29.10.2017 16:55

Je to osobní názor nebo to podporují i nějaký guidelines? Nedaří se mi o tom nic moc najít. Protože tohle je celkem blackmagic a člověk se musí pídit v kódu aby zjistil, čemu by se vlastně neco nebo pNeco mohlo rovnat aby se to vyhodnotilo jako false.

// dodatek: navíc mi to podobný nepříjde, porovnávát bool s true je docela nesmysl, ale char nebo bůhvíco dalšího?

Editováno 29.10.2017 16:56
Nahoru Odpovědět
29.10.2017 16:55
Neaktivní uživatelský účet
Avatar
Odpovídá na Neaktivní uživatel
Luboš Běhounek Satik:29.10.2017 17:10

Spíš osobní názor, ale porovnávat, jestli je něco nula prostě můžeš bez toho porovnání s nulou, protože true je v céčku reprezentovaný nenulovým číslem :)
0 = false = NULL = '\0'

Editováno 29.10.2017 17:11
Nahoru Odpovědět
29.10.2017 17:10
https://www.facebook.com/peasantsandcastles/
Avatar
Luboš Běhounek Satik:29.10.2017 17:13

(jinak ted koukam, ze u toho pointeru mam preklep, melo tam byt

if (!pNeco)
Nahoru Odpovědět
29.10.2017 17:13
https://www.facebook.com/peasantsandcastles/
Avatar
Odpovídá na DarkCoder
Lukino Papadu Hasprún:29.10.2017 19:10

Ano som si isty, ide mi to spravne

 
Nahoru Odpovědět
29.10.2017 19:10
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Lukino Papadu Hasprún
DarkCoder:29.10.2017 19:40

To ono to funguje, ale mějme následující definici:

char retazec[51];

Toto pole znaků dokáže pojmout 50 znaků + null znak, tedy poslední položka je retazec[50]. Pokud toto pole naplníme hodnotami tak, že přesně využijeme jeho paměť, pak jeho buffer nabývá indexů [0..49] a retazec[50] je roven nulovému ukončovacímu znaku.
Podmínka:

while (retazec[i] != '\0')

nám udává, že cyklus běží až při i==49. A při i==49 nám výraz

(retazec[i + 1] == podretazec[1])

udává, že porovnávám nulový znak s druhým znakem pole podretazec a u výrazu

(retazec[i + 2] == podretazec[2])

dokonce porovnávám hodnotu, která je mimo rozsah pole retazec (Indexuji 51. prvek).
Proto je výraz:

if ((retazec[i] == podretazec[0]) && (retazec[i + 1] == podretazec[1]) && (retazec[i + 2] == podretazec[2])) i += 3;

nesprávný.

Nahoru Odpovědět
29.10.2017 19:40
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Lukino Papadu Hasprún:29.10.2017 22:18

Ano viem co myslis. Ako by si to teda zapisal ty?

 
Nahoru Odpovědět
29.10.2017 22:18
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Lukino Papadu Hasprún
DarkCoder:30.10.2017 0:41

Třeba takto:

#define _CRT_SECURE_NO_WARNINGS

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

#define MAXBUF 50
#define SUBBUF 3

int main(void){
        char retazec[MAXBUF + SUBBUF + 1];
        char podretazec[SUBBUF + 1];
        char novy_retazec[MAXBUF + 1];
        char *pret;
        char *ppod;
        char *pnov;

        pret = retazec;
        ppod = podretazec;
        pnov = novy_retazec;

        memset(retazec, '\0', sizeof(retazec));
        fgets(retazec, MAXBUF + 1, stdin);
        memset(podretazec, '\0', sizeof(podretazec));
        fgets(podretazec, SUBBUF + 1, stdin);

        while (*pret) {
                if ((*pret == *ppod) && (*(pret+1) == *(ppod+1) && (*(pret + 2) == *(ppod + 2)))) pret+=3;
                else {
                        *pnov = *pret;
                        pret++;
                        pnov++;
                }
        }
        *pnov = '\0';

        puts(novy_retazec);

        return 0;
}
Nahoru Odpovědět
30.10.2017 0:41
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Lukino Papadu Hasprún:30.10.2017 11:28

Hmm zaujimave, su tam veci ktore sme v skole este neprebrali :) Budem musiet dostudovat navyse, Dakujem hned sa do toho pustim.

 
Nahoru Odpovědět
30.10.2017 11:28
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Lukino Papadu Hasprún
DarkCoder:30.10.2017 11:34

Bez ukazatelů:

#define _CRT_SECURE_NO_WARNINGS

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

#define MAXBUF 50
#define SUBBUF 3

int main(void){
        char retazec[MAXBUF + SUBBUF + 1];
        char podretazec[SUBBUF + 1];
        char novy_retazec[MAXBUF + 1];
        int i = 0;
        int j = 0;

        memset(retazec, '\0', sizeof(retazec));
        fgets(retazec, MAXBUF + 1, stdin);
        memset(podretazec, '\0', sizeof(podretazec));
        fgets(podretazec, SUBBUF + 1, stdin);

        while (retazec[i]){
                if ((retazec[i] == podretazec[0]) && (retazec[i + 1] == podretazec[1]) && (retazec[i + 2] == podretazec[2])) i += 3;
                else {
                        novy_retazec[j] = retazec[i];
                        j++;
                        i++;
                }
        }
        novy_retazec[j] = '\0';

        puts(novy_retazec);

        return 0;
}
Nahoru Odpovědět
30.10.2017 11:34
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Lukino Papadu Hasprún:30.10.2017 15:23

Snazim sa pochopit tym retazcom a sice to nevyzera tak tazko ako sa to najprv zdalo ale dnes sme v skole akurat zacali preberat ukazatele a dostali sme na domacu ulohu toto:

Napíšte program, ktorý načíta reťazec (povinne použite scanf(“%s“, ....) a vytvorí nový v ktorom každú hviezdičku zdvojí a každú bodku vymaže. Na obrazovku vypíše výsledný reťazec (pomocou jediného printf). Celé riešenie musí používať jediné pole (reťazec).

Ukážkový vstup: abd.fh↵
Ukážka výstupu: abdfh↵

Asi by som s tym potreboval mensiu pomoc pre lepsie pochopenie ukazatelov. Nejako neviem prist na to ako pouzit ukazatele na upravu retazca bez toho aby som si vytvoril nove pole. Dakujem

 
Nahoru Odpovědět
30.10.2017 15:23
Avatar
Odpovídá na Lukino Papadu Hasprún
Lukino Papadu Hasprún:30.10.2017 16:45
Ukážkový vstup: ab*d.f*h↵
Ukážka výstupu: ab**df**h↵
 
Nahoru Odpovědět
30.10.2017 16:45
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Lukino Papadu Hasprún
DarkCoder:30.10.2017 17:13

K tvé úloze:

  • Podívej se nejprve na problematiku ukazatelů
  • Pokus se nejprve vytvořit svoji vlastní verzi programu

Úloha se dá řešit i bez použití ukazatelů (o jejich použití v zadání není ani zmínka). K povinnému použití scanf() pro načtení řetězce se nebudu vyjadřovat. Nové pole není třeba vytvářet pokud máme pole pro uložení řetězce dostatečně velké. Jeho část se dá použít jako odkladiště a místo, kde se dají provádět potřebné úpravy. Už jste brali dynamickou alokaci paměti?

Nahoru Odpovědět
30.10.2017 17:13
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Lukino Papadu Hasprún:30.10.2017 17:25

Ano trosku sme to prebehli

 
Nahoru Odpovědět
30.10.2017 17:25
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 21 zpráv z 21.