Kirjoittaja: Metabolix
Kirjoitettu: 31.07.2007 – 31.07.2007
Tagit: ohjelmointitavat, koodi näytille, vinkki
Tällä pienellä funktiolla voi yhdistää monta tekstinpätkää yhdeksi tekstiksi. Parametreja voi antaa haluamansa määrän, yhdistäminen loppuu ensimmäiseen NULL-osoittimeen. Tämä lopetusehto kannattaa pitää mielessä, jos joskus ihmettelee, miksi yhdistetty teksti katkeaakin kesken kaiken: voi olla, että jokin parametreista onkin ollut NULL-osoitin jo liian varhaisessa vaiheessa.
Funktio hakee parametrit stdarg-otsikossa esiteltävillä makroilla, mittaa tekstien yhteispituuden, varaa malloc-funktiolla oikean määrän muistia ja yhdistää tekstit. Funktion palauttama osoitin täytyy itse vapauttaa free-funktiolla, jottei ohjelmaan jää muistivuotoa.
// yhdista_tekstit.h #ifndef _YHDISTA_TEKSTIT_H #define _YHDISTA_TEKSTIT_H 1 extern char *yhdista_tekstit(const char *ensimmainen, ...); #endif
// yhdista_tekstit.c
#include "yhdista_tekstit.h"
// Otsikot:
// stdarg.h: parametrilista (funktion ...-"parametri")
#include <stdarg.h>
// string.h: tekstin mittaaminen (strlen) ja kopiointi (strcpy)
#include <string.h>
// stdlib.h: muistin varaus (malloc)
#include <stdlib.h>
char *yhdista_tekstit(const char *ensimmainen, ...)
{
	va_list lista;
	size_t len;
	const char *str;
	char *yhdiste, *ptr;
	// Luetaan parametreista tekstien pituudet
	va_start(lista, ensimmainen);
	for (str = ensimmainen, len = 0; str != NULL; str = va_arg(lista, const char*)) {
		len += strlen(str);
	}
	va_end(lista);
	// Varataan sopivasti muistia
	yhdiste = ptr = malloc(len + 1);
	if (yhdiste == NULL) {
		return NULL; // Virhe!
	}
	// Kopioidaan kukin teksti (ptr osoittaa aina tekstin loppuun, joten jatketaan aina siitä kohti)
	va_start(lista, ensimmainen);
	for (str = ensimmainen; str != NULL; str = va_arg(lista, const char*)) {
		strcpy(ptr, str);
		ptr += strlen(ptr);
	}
	va_end(lista);
	// Yhdistetty teksti:
	return yhdiste;
}// testiohjelma.c
// gcc testiohjelma.c yhdista_tekstit.c
// Tai lisää IDE:ssä samaan projektiin yhdista_tekstit.c:n kanssa
#include <stdio.h>
#include <stdlib.h>
#include "yhdista_tekstit.h"
int main(int argc, char **argv)
{
	char *str;
	str = yhdista_tekstit("Ohjelma on ", argv[0], ", ja NULL lopettaa.", NULL);
	printf("Yhdistetty teksti: %s\n", str);
	free(str); // Muista vapauttaa yhdistetty teksti!
	return 0;
}Luulenpa, että size_t len; pitäisi alustaa nollaksi.
Kirjoitusvirhe kommentissa "... ja kopiointi (stdcpy)."
strcpy sehän siis on.
Kopeekka kirjoitti:
Luulenpa, että
size_t len;pitäisi alustaa nollaksi.
Kyllä se alustetaan, vaikkakin mielestäni vähän erikoisessa paikassa.
for (str = ensimmainen, len = 0; str != NULL; str = va_arg(lista, const char*)) {VB.Net ja Visual Basic koodarit saa tällä pään kipeeksi.. vai että monen tekstin yhdistäminen.
Meitzi kirjoitti:
VB.Net ja Visual Basic koodarit saa tällä pään kipeeksi.. vai että monen tekstin yhdistäminen.
Niin saa. ;)
Varsinainen ajatushan tässä on tuo muistin varaaminen dynaamisesti. Yhdistely sinänsä menisi kyllä strcat-funktiolla, mutta se ei tarkista muistiasioita.