[Cvičení 8] [Obsah] [Cvičení 10]

Cvičení 9


Řetězce v jazyce C

Témata


Úlohy

Úloha 9.1

Napište proceduru void spoj(char *s1, char *s2, char *s3), která má tři řetězce jako parametry. První parametr je cesta k souboru (disk a adresáře), druhý parametr je název souboru. Do třetího řetězce funkce uloží spojenou cestu. Nejprve zjistí, zda je cesta ukončena znakem '\\', pokud ne, znak doplní.
Příklad:
char celk_cesta[256];
spoj("C:\\Dokumenty","semestralka.c",celk_cesta);
V řetězci celková cesta bude text: C:\Dokumenty\semestralka.c

Řešení:

Dev C++:spojeni_soubor.dev, spojeni_soubor.c
CodeBlocks:spojeni_soubor.cbp, spojeni_soubor.c

Úloha 9.2

Napište funkci odstran(char *s, char z), která odstraní z řetězce s všechny výskyty znaku z.

Řešení:

Dev C++:odstran_znak.dev, odstran_znak.c
CodeBlocks:odstran_znak.cbp, odstran_znak.c


Konverzní funkce pro převod čísel na řetězce a opačně

V knihovně stdlib.h existuje několik funkcí pro převod mezi číselnými hodnotami a řetězci a naopak. Přehled několika z nich uvádí tabulka 2.

Konverzní funkce
Hlavička funkce Význam
int atoi(const char *s) Převede řetězec na číslo typu int. Číslo v řetězci je v desítkové soustavě.
long atol(const char *s) Převede řetězec na číslo typu long.
double atof(const char *s) Převede řetězec na číslo reprezentované v pohyblivé řádové čárce
char *itoa(int value, char *s, int radix) Převede číslo typu int na řetězec s. Radix určuje číselnou soustavu (2 až 36), ve které má být číslo v řetězci uloženo. Paměť pro řetězec musí být alokována (v překladači Borland C++ vrací funkce max. 33 znaků). Funkce vrací ukazatel na řetězec s.
char *ultoa(unsigned long value, char *s, int radix) Převede číslo typu unsigned long na řetězec s.
long strtol(const char *s, char **endptr, int radix) Převede řetězec na číslo typu long. Číslo v řetězci může být zapsáno v číselné soustavě o základu 2 až 36 (parametr radix). Endptr viz poznámka. Pokud dojde při převodu k chybě, funkce vrací 0.
unsigned long strtoul(const char *s, char **endptr, int radix) Převede řetězec na číslo typu unsigned long v soustavě dané parametrem radix.
double strtod(const char *s, char **endptr) Převede řetězec na číslo typu double.

Tabulka 2: Konverzní funkce

Následující program demonstruje použití funkce itoa:

Dev C++:prevod.dev, prevod.c
Code Blocks:prevod.cbp, prevod.c

Poznámka:

Parametr endptr je ukazatel na ukazatel na char. Pokud není roven hodnotě NULL, funkce do tohoto ukazatele uloží ukazatel na znak, kde byla ukončena konverze. Ukazatel se dá využít, obsahuje-li řetězec několik číselných hodnot např. oddělených mezerami a potřebujeme-li postupně tato čísla převést.
long pole[7];
char s[] = "1 5 7 14 10 4 -4";
char *uk;

uk = s;
for(int i=0;i<7;i++)
   pole[i] = strtol(uk,&uk,10);
Pro převody mezi řetězci a číselnými proměnnými lze s výhodou použít i funkce sscanf a sprintf.


Funkce sprintf a sscanf

Tyto dvě funkce z knihovny stdio.h jsou odvozeny od známých funkcí printf a scanf. V případě funkce sprintf není výstup směřován na terminálový výstup, ale do řetězce, obdobně, v případě funkce sscanf se textový vstup nenačítá z klávesnice (terminálového vstupu), ale z řetězce.

int sprintf(char *buffer, const char *format[, argument, ...]);
int sscanf(const char *buffer, const char *format[, address, ...]);
Úlohu 8.2 bychom za pomoci funkce sprintf řešili jednoduše takto:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
  char text1[81];
  char text2[81];
  char *spojeny;

  printf("Zadej prvni text: ");
  gets(text1);

  printf("Zadej druhy text: ");
  gets(text2);

  spojeny = (char *)malloc(strlen(text1)+strlen(text2)+3+1);
  /* hodnotu 1 pričítám na ukončující znak a hodnotu 3 na spojení pomocí spojky "a" a dvou mezer */

  sprintf(spojeny,"%s a %s",text1,text2);

  printf("%s",spojeny);

  free(spojeny);
  return 0;
}
Konverzi např. celého čísla do proměnné x z řetězce ret za použití funkce sscanf naprogramujeme snadno: sscanf(ret,"%d",&x); Návratový kód funkce má stejný význam jako u scanf.

Úloha 9.3

Přepište úlohu 9.1 s využitím funkce sprintf.

Řešení:

Dev C++:spojeni_soubor2.dev, spojeni_soubor2.c
CodeBlocks:spojeni_soubor2.cbp, spojeni_soubor2.c

Úloha 9.4

Napište program, který automaticky generuje do řetězce jména souborů ahoj1.txt, ahoj2.txt, ..., ahoj10.txt.

Řešení:

Dev C++:generovani_jmen.dev, generovani_jmen.c
CodeBlocks:generovani_jmen.cbp, generovani_jmen.c

Úloha 9.5

Napište proceduru tisk_cisla(float f, int pocet), která vytiskne číslo typu float na zadaný počet desetinných míst.
(Návod: Formátovací řetězec pro funkci printf vytvořte jako dynamické pole znaků a naplňte jej pomocí funkce sprintf. Jeho délku odvoďte podle počtu cifer hodnoty v proměnné pocet; zjistíte jej pomocí dekadického logaritmu.)

Řešení:

Dev C++:tisk_cisla.dev, tisk_cisla.c
CodeBlocks:tisk_cisla.cbp, tisk_cisla.c


[Cvičení 8] [Obsah] [Cvičení 10]