Newsgroup: it.comp.os.linux.development
Titolo: modificare una stringa in C

come posso fare per prendere una stringa e sostituire ad uno o più
caratteri altri caratteri?
per esempio, siccome devo passare da utf a latex, sostituire a "Ãš" la
stringa "\`{e}" ?

 stringa "\`{e}" ?
Non stai sostituendo _caratteri_ con _caratteri_. Stai sostituendo pezzi di
stringa. Un carattere e` UN carattere.
Quindi la risposta e`: in C _puoi_ sostituire un carattere con un altro
carattere, per esempio una "x" con una "y" senza alcun problema.
Invece quello che vuoi fare tu e` modificare arbitrariamente una stringa, il
che non e` possibile (le stringhe sono array di caratteri, quindi allocati
staticamente, quindi non modificabili in lunghezza).
Se stai facendo un programmino per te, senza pretese, allora la cosa piu`
semplice in assoluto e` sovradimensionare le stringhe o creare dei buffer
sovradimensionati (per esempio lunghi come la piu` lunga sostituzione x
lunghezza della stringa). Altrimenti ci sono mille modi efficienti di fare
questa cosa...
-- 
  Palantir   ===    
http://netpalantir.altervista.org
icq:57482808 === Per scrivermi in priv togli la chiocciola

 stringa.
lo so, ma volevo sapere se qualcuno conosceva qualche cosa di già
implementato che fa le sostituzioni. Insomma, vorrei una funzione che
prende in pasto la stringa originale, la sottostringa da cambiare e la
sottostringa nuova e che mi ritorni una nuova stringa allocata dalla
funzione.


 * This file is part of GesConf.
 *
 * GesConf is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
/**************************************************************************
 * Function: strrepl
 * Details:  It replaces string it that it is found in an other string with 
 *           an other string.
 *           WARNING, with replace char with plus large char, is possible
 *           a StrTo buffer overflow.
 * Returns: 
 **************************************************************************/
void strrepl (char *StrTo, char *StrFor, char *StrRepl){
  int LenStrTo, LenStrFor, LenStrRepl, LenStrOut, IniSect, EndSect;
  char *StrTmp;
  LenStrOut= LenStrTo= strlen (StrTo);
  LenStrFor= strlen (StrFor);
  LenStrRepl= strlen (StrRepl);
// set the lenght of string with replaced char
  if (LenStrFor != LenStrRepl){
    LenStrOut= IniSect= 0;
    while (IniSect < LenStrTo){
      EndSect= strnstrN (StrTo, StrFor, IniSect);
      if (EndSect < LenStrTo)
        LenStrOut += (EndSect - IniSect + LenStrRepl);
      else
        LenStrOut += (LenStrTo - IniSect);
      IniSect= EndSect + LenStrFor;
    } // while (IniSect < LenStrTo)
  }
  StrTmp= (char*) xmalloc (LenStrOut + 1);
  *StrTmp= '\0';
// replace char
  IniSect= 0;
  while (IniSect < LenStrTo){
    EndSect= strnstrN (StrTo, StrFor, IniSect);
    if (EndSect < LenStrTo){
      strncat (StrTmp, &StrTo[IniSect], EndSect - IniSect);
      strcat (StrTmp, StrRepl);
    }
    else
      strcat (StrTmp, &StrTo[IniSect]);
    IniSect= EndSect + LenStrFor;
  } // while (IniSect < LenStrTo)
  strcpy (StrTo, StrTmp);
  free (StrTmp);
} // strrepl

 implementato che fa le sostituzioni. Insomma, vorrei una funzione che
]zac[
Manca un pezzo sempre tratto da ecc. ecc.
/**************************************************************************
 * Function: strnstrN
 * Details:  It return the position of one string to the inside of an other 
 *           string to leave from the demanded position. 
 * Returns: 
 **************************************************************************/
int strnstrN (char *StrTo, char *StrFor, int IniFind){
  int LenStr, PosFind;
  char *pPosFind;
// it sets up the initial position of search. 
  if (IniFind < 0)
    IniFind= 0;
  PosFind= LenStr= strlen (StrTo);
  if (IniFind < LenStr){
    pPosFind= strstr (&StrTo[IniFind], StrFor);
    if(pPosFind != NULL)
      PosFind= pPosFind - StrTo;
  }
   return (PosFind);
} // strnstrN

 implementato che fa le sostituzioni
Aah, ho capito ;-) Vabbe che il mio nick vuol dire "colui che vede lontano",
ma indovinare i tuoi reconditi pensieri era un po' arduo ;-P La prossima
volta scrivilo subito. Cmq ti hanno gia` risposto.


 funzione.
1) Perchè in C?
2) man pcre
-- 
  Giuseppe "Cowo" Corbelli \/\ My software: 
http://cowo.yoda2000.net
    **ANTI-SPAM** -- **Substitute IHATESPAM with cowo to reply by mail** 
-<! There are 10 kind of persons: who understands binary and who doesn't. !>-

 1) Perchè in C?
perché tutto il software è fatto in c? :-)

 caratteri altri caratteri?
Potresti usare Glib::GString. Un GString è una stringa in grado di
variare la sua dimensione on-the-fly.
Ciao,
 Emmanuele.
-- 
Emmanuele Bassi (Zefram)                 [ 
http://www.emmanuelebassi.net
 ]
GnuPG Key fingerprint = 4DD0 C90D 4070 F071 5738  08BD 8ECC DB8F A432 0FF4

>> caratteri altri caratteri?
sed non va bene?
o cmq le regexp anche sotto C
ciao
-- 
Er Baitch
"Live Your Life!!!" (Ring ain't a jail)
http://baitch.altervista.org/

 o cmq le regexp anche sotto C
ma non mi risulta che funzionino con un char*

 variare la sua dimensione on-the-fly.
ho guardato la dimensione, solo che non mi sembra che abbia funzioni per
sostituire sottostringhe....

 sostituire sottostringhe....
Ti basta trovare la posizione di un char unicode con g_utf8_strchr,
usando la stringa originale, convertirla in una GLib::GString e usare la
funzione GString::insert alla posizione trovata in precedenza. A quel
punto, recuperi la stringa dalla GLib::GString.
Questo è un prototipo di funzione che prende una stringa codificata in
UTF-8, un carattere unicode da sostituire e una stringa da sostituirgli.
Codice non testato, as usual.
#v+
	/* unichar_escape:
	 * @src: La stringa da controllare
	 * @c: Carattere Unicode da sostituire
	 * @escape: La stringa con cui sostituire il carattere
	 *
	 * Questa funzione realizza l'escape di un carattere Unicode da
	 * una stringa. La stringa deve essere codificata in UTF-8. La
	 * memoria occupata dalla stringa ritornata va liberata con
	 * g_free(). Ad esempio:
	 *
	 *	unichar_escape (str, "è", "&eacute;");
	 *
	 * Return value: la stringa con i caratteri sostituiti.
	 */
	gchar *
	unichar_escape (const gchar *src, gunichar c, gchar *escape)
	{
		GString *string;
		gchar *p, *dst;
 
		if (! g_unichar_validate (c)) {
			g_warning ("%c" is not a valid UTF char\n");
			return NULL;
		}
		if (! g_utf8_validate (src, -1, NULL)) {
			g_warning ("%s" is not a valid UTF-8 string\n");
			return NULL;
		}
		if (! escape) {
			g_warning ("%s" is not a valid string\n");
			return NULL;
		}
 
		p = g_utf8_strchr (src, -1, c);
		if (! p) {
			/* L'unichar C non è contenuto nella stringa */
			return src;
		}
 
		string = g_string_new (src);
		while (p) {
			glong index = g_utf8_pointer_to_offset (src, p);
			/* qui potrebbe volerci un po' di codice per
			eliminare il '\0' da fine stringa di escape;
			basta fare una prova, è banale. */
			g_string_insert (string, (gssize) index, escape);
			p = g_utf8_strchr (p, -1, c);
		}
 
		dst = g_strdup (string->str);
		g_string_free (string);
		return dst;
	}
#v-


Ottavio Campana wrote:

In C devi farti carico delle dimensioni della stringa.
La stringa di caratteri C è un buffer di memoria, se durante la sostituzione
sfori ottieni un segmentation-fault, se la stringa è di piccole dimensioni
puoi allocarla staticamente con un buffer di generose dimensioni es. con
char stringa[BUFFER];
In questo caso puoi scrivere un tuo algoritmo per fare ciò.
Se tu invece potessi utilizzare il C++ allora tutto si semplifica
utilizzando std::string, la potente classe stl per la gestione delle
stringhe. In questo caso non ti preoccupi più delle dimensioni del buffer e
ci sono sia funzioni membro e di libreria in grado di farti tutte le
operazioni che desideri su qualisiasi container (anche std::string).
ciao.