vkladanie reťazca do reťazca

Programovacie jazyky, rady, poradňa...
beluský
Darca
Darca
Používateľov profilový obrázok
Príspevky: 317
Registrovaný: 21 sep 2006, 13:46

vkladanie reťazca do reťazca

Príspevok od používateľa beluský »

Dobrý deň vospolok,

Kód: Vybrať všetko

napíšte void strinsert(char *s, int d, char *s2, int i), ktorá vloží do reťazca
s od pozície i reťazec s2. Pre reťazec s je vyhradená pamäť d znakov. 

Napr. pre s:
totojeretazec, i: 6 a s2: druhy bude po volaní funkcie 
strinsert(s1, 50, s2, i);
v s: totojedruhyretazec. 

Použite funkciu strcat a kontrolujte, či pridaním
reťazca nepresiahnete pamät’ určenú pre s.
mám takéto zadanie a neviem s tým pohnúť... resp. neviem ako spravím, aby ten s2 vložilo od i-teho znaku

blbé pointre :roll: poradí niekto?
chrono
VIP
VIP
Používateľov profilový obrázok
Príspevky: 7127
Registrovaný: 25 dec 2006, 15:17

Príspevok od používateľa chrono »

Ja by som si presunul časť reťazca s od pozície i do pomocného poľa a nastavil by som s = '\0'; (tým by som nechal v reťazci s iba prvú časť). Potom by som použil dva krát strcat. Prvým použitím by sa tam pridal reťazec s2 a pri druhom pôvodný koniec reťazca s. Samozrejme budeš musieť otestovať či nie je strlen(s) + strlen(s2) + 1 väčšie ako d. ;)
beluský
Darca
Darca
Používateľov profilový obrázok
Príspevky: 317
Registrovaný: 21 sep 2006, 13:46

Príspevok od používateľa beluský »

chrono napísal:Ja by som si presunul časť reťazca s od pozície i do pomocného poľa a nastavil by som s = '\0'; (tým by som nechal v reťazci s iba prvú časť). Potom by som použil dva krát strcat. Prvým použitím by sa tam pridal reťazec s2 a pri druhom pôvodný koniec reťazca s. Samozrejme budeš musieť otestovať či nie je strlen(s) + strlen(s2) + 1 väčšie ako d. ;)
kde tu mám prosím ťa chybu

Kód: Vybrať všetko

void strinsert(char *s, int d, char *s2, int i)
{
	char *str;

	str = (char *)malloc(strlen(s)+strlen(s2));

	/* skopiruje zbytok retazca po i-1 znaku do premennej str */
	for (int x = i-1; x <= int(strlen(s)); x++)
		str[x-i+1] = s[x];	

	/* zbavi retazec s zvytku znakov po i-1 znaku */
	s[i] = '\0';

	strcat(s,s2);
	strcat(s,str+1);

	free(str);
}

int main ()
{
	char prvy[]="totoniejeretazec";
	char druhy[]="druhy";

	printf("OBSAH   %20s \t ADRESA %p\n",prvy, &prvy);
	printf("OBSAH   %20s \t ADRESA %p\n",druhy, &druhy);

	strinsert(prvy, 20, druhy, 9);
	printf("\nSPOJENY  %s \n", prvy);

	return 0;
}
chrono
VIP
VIP
Používateľov profilový obrázok
Príspevky: 7127
Registrovaný: 25 dec 2006, 15:17

Príspevok od používateľa chrono »

Jedna veľmi dôležitá pripomienka. Reťazec prvy si si nadefinoval s nejakou konkrétnou veľkosťou (veľkosť určí kompilátor z dĺžky toho reťazca) a potom sa ho pokúšaš predlžovať (a tak prepisuješ niečo, čo by si prepisovať nemal [klasický buffer overflow]).
Na presun konca reťazca použi funkciu strcpy(str, &s).
Ešte nie je doriešené, čo sa má robiť, ak je výsledný reťazec dlhší ako d. Má sa do toho reťazca uložiť iba tá časť, ktorá sa tam zmestí? Alebo sa nemá robiť nič?
beluský
Darca
Darca
Používateľov profilový obrázok
Príspevky: 317
Registrovaný: 21 sep 2006, 13:46

Príspevok od používateľa beluský »

chrono napísal:Jedna veľmi dôležitá pripomienka. Reťazec prvy si si nadefinoval s nejakou konkrétnou veľkosťou (veľkosť určí kompilátor z dĺžky toho reťazca) a potom sa ho pokúšaš predlžovať (a tak prepisuješ niečo, čo by si prepisovať nemal [klasický buffer overflow]).
Na presun konca reťazca použi funkciu strcpy(str, &s).
Ešte nie je doriešené, čo sa má robiť, ak je výsledný reťazec dlhší ako d. Má sa do toho reťazca uložiť iba tá časť, ktorá sa tam zmestí? Alebo sa nemá robiť nič?
O déčku nebolo nič povedané tuším, čiže sa asi predpokladá správny vstup... čiže to bolo treba riešiť dynamicky, alebo mu priradiť ručne veľkosť a nenechávať to na prekladač?!
asi takto:

Kód: Vybrať všetko

void strinsert(char *s, int d, char *s2, int i)
{
	char *str;

	str = (char *)malloc(d);

	/* skopiruje zbytok retazca po i-1 znaku do premennej str */
	strcpy(str, &s[i-1]);	

	/* zbavi retazec s zvytku znakov po i-1 znaku */
	s[i] = '\0';

	strcat(s,s2);
	strcat(s,str+1);

	free(str);
}

int main ()
{
	char *prvy;
	char druhy[]="druhy";

	prvy = (char *) malloc (30);
	sprintf(prvy,"totoniejeretazec");

	printf("OBSAH   %20s \t ADRESA %p\n",prvy, &prvy);
	printf("OBSAH   %20s \t ADRESA %p\n",druhy, &druhy);


	strinsert(prvy, 25, druhy, 9);
	printf("\nSPOJENY  %s \n", prvy);

	free(prvy);
	return 0;
}
chrono
VIP
VIP
Používateľov profilový obrázok
Príspevky: 7127
Registrovaný: 25 dec 2006, 15:17

Príspevok od používateľa chrono »

Nemusel si použiť malloc. Mohol si tam dať

Kód: Vybrať všetko

char   prvy[MAX_LEN];
. Samozrejme musel by si nadefinovať konštantu MAX_LEN. Potom by si ju použil aj pri volaní tej funkcie strinsert.

V tej funkcii strinsert nekontroluješ, či sa ti do reťazca s zmestí začiatok+stred+koniec reťazca. Tu sa musíš rozhodnúť, čo budeš robiť. Teda, či do reťazca s vložíš iba to, čo sa tam zmestí, alebo nebudeš robiť nič.
Ak tam budeš vkladať to, čo sa tam zmestí, tak budeš musieť použiť funkciu strncat a vložíš tam takú časť reťazca s2, ktorá sa tam zmestí a potom, ak tam ešte bude miesto, vložíš tam takú časť konca reťazca, ktorá sa tam zmestí. Nesmieš ale zabudnúť na to, že na konci reťazca s musí byť znak '\0'.
beluský
Darca
Darca
Používateľov profilový obrázok
Príspevky: 317
Registrovaný: 21 sep 2006, 13:46

Príspevok od používateľa beluský »

aha rozumiem, čiže keby som chcel kontrolovať či sa tam zmestí alebo to aspoň zabezpečiť nech sa tam zmestí určite, musel by som realokovať vo funkcii strinsert premennu char *s... čiže to skontrolujem takto

Kód: Vybrať všetko

strlen(s)+strlen(s2)<sizeof(s).... ?
vtedy nepresiahnem pamäť pridelenú s keď k nemu pripojím aj s2
chrono
VIP
VIP
Používateľov profilový obrázok
Príspevky: 7127
Registrovaný: 25 dec 2006, 15:17

Príspevok od používateľa chrono »

Podľa zadania tam nemáš nič realokovať. Máš skontrolovať, či sa to tam zmestí, ale už v zadaní nie je napísané, čo sa má stať, keď sa to tam nezmestí.

Kód: Vybrať všetko

Pre reťazec s je vyhradená pamäť d znakov. ...Použite funkciu strcat a kontrolujte, či pridaním reťazca nepresiahnete pamäť určenú pre s.
Čiže by si mal skontrolovať, či (strlen(s)+strlen(s2)+1) <= d (ale neviem, čo treba urobiť, keď to dlhšie je).
beluský
Darca
Darca
Používateľov profilový obrázok
Príspevky: 317
Registrovaný: 21 sep 2006, 13:46

Príspevok od používateľa beluský »

Kód: Vybrať všetko

chybové správy sú:
• do retazca nie je mozne vlozit podretazec od zvolenej pozicie
...
čiže len vypísať a nezmeniť
chrono
VIP
VIP
Používateľov profilový obrázok
Príspevky: 7127
Registrovaný: 25 dec 2006, 15:17

Príspevok od používateľa chrono »

beluský napísal:

Kód: Vybrať všetko

chybové správy sú:
• do retazca nie je mozne vlozit podretazec od zvolenej pozicie
...
čiže len vypísať a nezmeniť
V takom prípade tam stačí pridať :

Kód: Vybrať všetko

if (strlen(s) + strlen(s2) + 1 > d) {
	fprintf(stderr, "do retazca nie je mozne vlozit podretazec od zvolenej pozicie\n");
	return;
}
beluský
Darca
Darca
Používateľov profilový obrázok
Príspevky: 317
Registrovaný: 21 sep 2006, 13:46

Príspevok od používateľa beluský »

vďaka to už mám, moc si mi pomohol, ešte raz dík
Napísať odpoveď