Deklarace a inicialisace: pismena[20] = "abcdefghij";
V jazyku C se o to, aby znakový řetězec nebyl větší, než je místo pro něj vyčleněné
(s možnými nepříjemnými následky:
přepsání hodnot v jiných proměnných a nebo vyvolání přerušení
z důvodu porušení ochrany paměti) musí postarat
programátor.
Napište funkci strchins podle následujících pokynů a informací
do tohoto programu
/**
* @file vkladaniDovnitr.c
* @author Ales Zlamal
*/
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
/**
* Funkce vlozi zadany znak do znakoveho retezce na zadane misto
*
* @param b ukazatel, kam se ma znak vlozit
* @param d kolik mista jeste zbyva do konce mista pro znakovy retezec
* @param z znak, jenz se ma vlozit
* @return NULL, pokud se vkladany znak jiz nevesel; anebo pokud se vesel, adresu kam mel byt vlozen
*/
char *strchins(char *b, int d, char z);
#define DELKA_RETEZCE 25
int main()
{
char str[DELKA_RETEZCE] = "Pridava se dopredu: ";
printf("%s\n", str);
strchins(str + 20, DELKA_RETEZCE - strlen(str), 'D');
printf("%s\n", str);
strchins(str + 20, DELKA_RETEZCE - strlen(str), 'C');
printf("%s\n", str);
strchins(str + 20, DELKA_RETEZCE - strlen(str), 'B');
printf("%s\n", str);
strchins(str + 20, DELKA_RETEZCE - strlen(str), 'A');
printf("%s\n", str);
printf("Delka retezce je %zu.\n", strlen(str));
if (strchins(str + 20, DELKA_RETEZCE - strlen(str), 'X') == NULL) {
printf("Nejde to - ");
}
printf("%s\n", str);
printf("Delka retezce je %zu.\n", strlen(str));
return EXIT_SUCCESS;
}
Princip je skoro stejný jako v třídění zařazováním (Insert sortu).
Výstup programu je:
Pridava se dopredu:
Pridava se dopredu: D
Pridava se dopredu: CD
Pridava se dopredu: BCD
Pridava se dopredu: ABCD
Delka retezce je 24.
Nejde to - Pridava se dopredu: ABCD
Delka retezce je 24.
Použitím funkce strchins (stejné jako v předchozím zadání) napište nerekursivní funkci,
která zadanou číselnou hodnotu vyjádřenouv pravidelné posiční soustavě o zadaném základu vloží do zadaného místa znakového řetězce.
/**
* @file vyjadreniCisel.c
* @author Ales Zlamal
*/
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
/**
* Funkce udela ze zadane ciselne hodnoty prislusnou cislici
*
* @param x cislena hodnota
* @return cislice
*/
char cislice(unsigned int x);
/**
* Funkce vlozi zadany znak do znakoveho retezce na zadane misto
*
* @param b ukazatel, kam se ma znak vlozit
* @param d kolik mista jeste zbyva do konce mista pro znakovy retezec
* @param z znak, jenz se ma vlozit
* @return NULL, pokud se vkladany znak jiz nevesel; anebo pokud se vesel, adresu kam mel byt vlozen
*/
char *strchins(char *b, int d, char z);
/**
* Funkce vlozi cislo v posicni soustave se zadanym zakladem do znakoveho retezce na zadane misto
*
* @param s ukazatel, kam se ma znak vlozit
* @param d kolik mista jeste zbyva do konce mista pro znakovy retezec
* @param c cislo, jehoz representace se ma vlozit
* @param z zaklad represenace cisla, jehoz representace se ma vlozit
* @return NULL, pokud se vkladany znak jiz nevesel; anebo pokud se vesel, adresu kam mel byt vlozen
*/
char *strnumbsins(char *s, int d, unsigned int c, unsigned int b);
#define DELKA_RETEZCE 75
#define D_C 12
int main()
{
unsigned int cislo, zaklad;
char rtz[DELKA_RETEZCE];
char s[D_C];
char *kca;
for(;;) {
printf("Zadejte cislo a zaklad: ");
if (fgets(s, D_C, stdin) == NULL || *s == '\n') break;
cislo = (unsigned int)strtoul(s, &kca, 10);
if (*kca != '\n') {
zaklad = (unsigned int)strtoul(kca, &kca, 10);
} else {
printf("Zadejte jeste zaklad: ");
if (fgets(s, D_C, stdin) == NULL || *s == '\n') break;
zaklad = (unsigned int)strtoul(s, &kca, 10);
}
sprintf(rtz, "Cislo %u je v pravidelne posicni soustave o zakladu %u rovno ", cislo, zaklad);
strnumbsins(rtz, DELKA_RETEZCE, cislo, zaklad);
printf("%s.\n", rtz);
printf(" Delka retezce je %zu.\n", strlen(rtz));
}
return EXIT_SUCCESS;
}
char cislice(unsigned int x)
{
return x < 10 ? '0' + x : 'A' - 10 + x;
}
Výstup programu je:
Zadejte cislo a zaklad: 2184
Zadejte jeste zaklad: 2
Cislo 2184 je v pravidelne posicni soustave o zakladu 2 rovno 100010001000.
Delka retezce je 74.
Zadejte cislo a zaklad: 4096 2
Cislo 4096 je v pravidelne posicni soustave o zakladu 2 rovno 000000000000.
Delka retezce je 74.
Zadejte cislo a zaklad:
Parsing
V češtině pro parsovat, parsování a parsing nemáme vhodné termíny
a tak se zhusta používají odvozeniny toho anglofonního.
(Při čtení anglofonní odborné literatury se tak zmenšuje možnost zmatení … )
Parsování znamená rozdělit znakový řetězec na znakové podřetězce navzájem oddělené zadanými oddělovači.
Ilustraci zvolíme velmi zjednodušenou: v parsovaném řetězci je oddělovačem právě jedna mezera, ani na začátku
a ani na konci není tento oddělovač a není v něm žádná interpunkce.
Úkol: napočítejte počet „slov” a (dynamicky) naalokujte stejně velké pole ukazatelů na řetězce. Velikost znakových polí pro uložení „slov” ‑ řetězců musí být ještě o 1 větší než je
velikost ukládaných „slov” ‑ řetězců pro uložení řetězec ukončujícího '\0'.
Řetezec k vyzkoušení:
"Boleslav pije sladkou vodu a Jaroslava se myje vodou slanou a Karel spravuje boty"
V jazyku C mezi funkcemi pracujícími se znakovými řetězce (jejichž hlavičky jsou v hlavičkovém souboru
<string.h>) je i funkce strtok
(Asi zkratka ze string tokenize).
Ta má řadu nectností, jak vidno dále:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main()
{
char r[32], *p, *q[7];
int i, c;
strcpy(r, "pec spadla a skakal pes");
printf("|%s|\n", r);
printf("\n");
p = q[0] = strtok(r, " ");
i = 0;
p = strtok(NULL, " ");
while (p != NULL) {
q[++i] = p;
p = strtok(NULL, " ");
}
c = i;
for (i = 0; i <= c; ++i) {
printf("|%s|\n", q[i]);
}
printf("\n");
printf("|%s|\n", r);
printf("\n");
strcpy(r, "Putin je vrah");
printf("|%s|\n", r);
printf("\n");
for (i = 0; i <= c; ++i) {
printf("|%s|\n", q[i]);
}
return EXIT_SUCCESS;
}
S výstupem:
|pec spadla a skakal pes|
|pec|
|spadla|
|a|
|skakal|
|pes|
|pec|
|Putin je vrah|
|Putin je vrah|
|n je vrah|
|ah|
||
|pes|
Navíc tato funkce není reentrantní. Další informace třeba tady.
Osobně doporučuji tuto funkci nepoužívat.