/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
strrep???
Fra : Chris


Dato : 22-05-02 00:51

Kan nogen hjælpe mig med noget kildekode til en sådan funktion:

char * strrep (char *string, const char *find, const char *replace);

Hvor alle forekomster af "find" i "string" bliver udskiftet med
"replace".

På forhånd tak
Chris

 
 
Anders Melchiorsen (22-05-2002)
Kommentar
Fra : Anders Melchiorsen


Dato : 22-05-02 01:02

dsl3353@vip.cybercity.dk (Chris) skrev:

> Kan nogen hjælpe mig med noget kildekode til en sådan funktion:
>
> char * strrep (char *string, const char *find, const char *replace);
>
> Hvor alle forekomster af "find" i "string" bliver udskiftet med
> "replace".

Jada. En løsning som ikke bør give 13 følger dette mønster:


char* my_strrep(char *string, const char *find, const char *replace)
{
char* next = 0;

while (next = strstr(string, find)) {
// "next" peger nu på en forekomst af "find" i "string".
//
// Erstat denne med "replace" idet du tager hensyn til
// at "find" og "replace" ikke nødvendigvis har samme
// længde.
}

return string;
}



/Anders

--
Address is valid for a week.
After that, remove (only) the '.day-JJJ-YYYY' part.

Bertel Lund Hansen (22-05-2002)
Kommentar
Fra : Bertel Lund Hansen


Dato : 22-05-02 07:35

Chris skrev:

>Kan nogen hjælpe mig med noget kildekode til en sådan funktion:
>char * strrep (char *string, const char *find, const char *replace);

Det er måske ikke lige det du vil have, men her:

   http://lundhansen.dk/bertel/programmer/gsar110.zip

ligger et program med C-kildekode inkluderet. Det er rasende
hurtigt og netop beregnet til søg og erstat.

PS. Jeg har ikke selv lavet det som man ville se hvis man ikke
fik et direkte link.

--
Bertel
http://lundhansen.dk/bertel/   FIDUSO: http://fiduso.dk/

Chris (22-05-2002)
Kommentar
Fra : Chris


Dato : 22-05-02 11:55

On Tue, 21 May 2002 23:50:54 GMT, dsl3353@vip.cybercity.dk (Chris)
wrote:

Tak for hjælpen så langt.
Nu har jeg skrevet to funktioner til mit behov. Dog er de ikke sikret
mod buffer overflow. Vil nogen mon hjælpe mig det?

Venligst
Chris
---
#include <stdio.h>
#include <string.h>

char *
_strrep (char *string, char *find, char *replace)
{
char *next, *ret;
int findlen = strlen (find);
int replacelen = strlen (replace);;

if (!(next = strstr (string, find)))
return string;

memmove (ret = next + replacelen, next + findlen, strlen (next +
findlen) + 1);
memcpy (next, replace, replacelen);
return ret;
}

char *
strrep (char *string, char *find, char *replace)
{
while (strstr (string, find))
_strrep (string, find, replace);
return string;
}

int
main ()
{
char test[] = "Dette er noget gylle. Og dette er endnu mere gylle.";

strrep (test, "gylle", "lortxxxxx");
printf ("%s\n", test);
return 0;
}


Anders Melchiorsen (22-05-2002)
Kommentar
Fra : Anders Melchiorsen


Dato : 22-05-02 12:12

dsl3353@vip.cybercity.dk (Chris) skrev:

> Nu har jeg skrevet to funktioner til mit behov. Dog er de ikke
> sikret mod buffer overflow. Vil nogen mon hjælpe mig det?

Hvis du mener at du gerne vil gardere dig imod problemer hvis længden
af replace er større end længden af find, så kan det ikke lade sig
gøre, sådan som funktionen virker.

Det er kalderen af funktionen, som har reserveret plads til string, og
derfor også hans ansvar, at bufferen er stor nok (ganske som med fx
strcpy).

Eller tænkte du på noget andet?


Anders.

--
Address is valid for a week.
After that, remove (only) the '.day-JJJ-YYYY' part.

Chris (22-05-2002)
Kommentar
Fra : Chris


Dato : 22-05-02 12:24

On 22 May 2002 13:12:14 +0200, Anders Melchiorsen
<postmaster@anders.day-142-2002.nospam.kalibalik.dk> wrote:


>Eller tænkte du på noget andet?

Tænkte nok på, hvorvidt det var muligt at overskrive bufferen.
Ligemeget, jeg tror, jeg har forstået det.

Tak skal du have.
Chris

Bertel Lund Hansen (22-05-2002)
Kommentar
Fra : Bertel Lund Hansen


Dato : 22-05-02 13:48

Chris skrev:

>char *_strrep (char *string, char *find, char *replace)

Undgå at bruge ordet "string" som variabel. Det bruges til
C-modulet af samme navn (string.h).

--
Bertel
http://lundhansen.dk/bertel/   FIDUSO: http://fiduso.dk/

Igor V. Rafienko (22-05-2002)
Kommentar
Fra : Igor V. Rafienko


Dato : 22-05-02 14:32

[ Bertel Lund Hansen ]

> >char *_strrep (char *string, char *find, char *replace)
>
> Undgå at bruge ordet "string" som variabel. Det bruges til
> C-modulet af samme navn (string.h).


.... og unngå å bruke variabelnavn som begynner med _, da slike navn er
reservert for implementasjonen. Samt unngå å bruke navn som begynner
på str og har "external linkage" -- disse er også reservert for
implementasjonen.





ivr
--
C++: "an octopus made by nailing extra legs onto a dog"
            -- Steve Taylor, 1998

David Rasmussen (22-05-2002)
Kommentar
Fra : David Rasmussen


Dato : 22-05-02 13:59

Chris wrote:
> On Tue, 21 May 2002 23:50:54 GMT, dsl3353@vip.cybercity.dk (Chris)
> wrote:
>
> Tak for hjælpen så langt.
> Nu har jeg skrevet to funktioner til mit behov. Dog er de ikke sikret
> mod buffer overflow. Vil nogen mon hjælpe mig det?
>
> Venligst
> Chris
> ---
> #include <stdio.h>
> #include <string.h>
>
> char *
> _strrep (char *string, char *find, char *replace)
> {
> char *next, *ret;
> int findlen = strlen (find);
> int replacelen = strlen (replace);;
>
> if (!(next = strstr (string, find)))
> return string;
>
> memmove (ret = next + replacelen, next + findlen, strlen (next +
> findlen) + 1);
> memcpy (next, replace, replacelen);
> return ret;
> }
>
> char *
> strrep (char *string, char *find, char *replace)
> {
> while (strstr (string, find))
> _strrep (string, find, replace);
> return string;
> }
>
> int
> main ()
> {
> char test[] = "Dette er noget gylle. Og dette er endnu mere gylle.";
>
> strrep (test, "gylle", "lortxxxxx");
> printf ("%s\n", test);
> return 0;
> }
>

Sådanne programmer er gode til at demonstrere hvor C++ er bedre end C :)


Bertel Lund Hansen (22-05-2002)
Kommentar
Fra : Bertel Lund Hansen


Dato : 22-05-02 14:32

David Rasmussen skrev:

>Sådanne programmer er gode til at demonstrere hvor C++ er bedre end C :)

Sådan et indlæg er godt til at demonstrere hvad delete-knappen er
til for.

--
Bertel
http://lundhansen.dk/bertel/   FIDUSO: http://fiduso.dk/

David Rasmussen (22-05-2002)
Kommentar
Fra : David Rasmussen


Dato : 22-05-02 15:30

Bertel Lund Hansen wrote:
> David Rasmussen skrev:
>
>
>>Sådanne programmer er gode til at demonstrere hvor C++ er bedre end C :)
>
>
> Sådan et indlæg er godt til at demonstrere hvad delete-knappen er
> til for.
>

Wow, kan du slette mit indlæg? Det kan man ikke her...


Igor V. Rafienko (23-05-2002)
Kommentar
Fra : Igor V. Rafienko


Dato : 23-05-02 11:44

[ dsl3353@vip.cybercity.dk ]

[ snip ]

> Tak for hjælpen så langt.
> Nu har jeg skrevet to funktioner til mit behov. Dog er de ikke sikret
> mod buffer overflow. Vil nogen mon hjælpe mig det?


Det er to måter å sikre mot buffer overflow her -- enten sørger man
for at det er plass til den teksten som skal settes inn (og det
greieste er kanskje å sjekke at strlen( find ) >= strlen( replace ))
eller sørger man for å allokere plassen, om nødvendig.

Jeg har egentlig litt mer sans for den siste løsningen (dog, den vil
(sannsynligvis) koste mer, både tids- og plassmessig, og den vil
kreve å omskrive det du har laget hittil).





ivr
--
C++: "an octopus made by nailing extra legs onto a dog"
            -- Steve Taylor, 1998

Chris (23-05-2002)
Kommentar
Fra : Chris


Dato : 23-05-02 15:19

On 23 May 2002 12:43:51 +0200, igorr@ifi.uio.no (Igor V. Rafienko)
wrote:

>Jeg har egentlig litt mer sans for den siste løsningen (dog, den vil
>(sannsynligvis) koste mer, både tids- og plassmessig, og den vil
>kreve å omskrive det du har laget hittil).

Kan jeg få et hint til at gøre det på denne måde?

Venligst
Chris

Anders Melchiorsen (23-05-2002)
Kommentar
Fra : Anders Melchiorsen


Dato : 23-05-02 15:41

dsl3353@vip.cybercity.dk (Chris) skrev:

> On 23 May 2002 12:43:51 +0200, igorr@ifi.uio.no (Igor V. Rafienko)
> wrote:
>
> > [ Reserver plads selv ]
>
> Kan jeg få et hint til at gøre det på denne måde?

Du skal gøre som strdup(), ikke som strcpy(). Forskellen er om det er
kalderen eller den kaldte, der reserverer hukommelsen (via malloc).


Anders.

--
Min adresse er gyldig i en uge.
Derefter skal (kun) '.dJJJ-YY' delen fjernes.

Byrial Jensen (23-05-2002)
Kommentar
Fra : Byrial Jensen


Dato : 23-05-02 18:36

Anders Melchiorsen <postmaster@anders.d143-02.nospam.kalibalik.dk> skrev:
>> > [ Reserver plads selv ]
>>
>> Kan jeg få et hint til at gøre det på denne måde?
>
> Du skal gøre som strdup(), ikke som strcpy(). Forskellen er om det er
> kalderen eller den kaldte, der reserverer hukommelsen (via malloc).

Pas på med strdup(). Det er ikke en standard funktion, men findes
på visse unix'er.

Kent Friis (23-05-2002)
Kommentar
Fra : Kent Friis


Dato : 23-05-02 20:58

Den Thu, 23 May 2002 17:36:10 GMT skrev Byrial Jensen:
>Anders Melchiorsen <postmaster@anders.d143-02.nospam.kalibalik.dk> skrev:
>>> > [ Reserver plads selv ]
>>>
>>> Kan jeg få et hint til at gøre det på denne måde?
>>
>> Du skal gøre som strdup(), ikke som strcpy(). Forskellen er om det er
>> kalderen eller den kaldte, der reserverer hukommelsen (via malloc).
>
>Pas på med strdup(). Det er ikke en standard funktion, men findes
>på visse unix'er.

Man kan da godt "gøre som" en funktion, selvom den ikke er standard.

Mvh
Kent
--
The frozen north will hatch a flightless bird,
who will spread his wings and dominate the earth
And cause an empire by the sea to fall
To the astonishment, and delight of all.

Igor V. Rafienko (23-05-2002)
Kommentar
Fra : Igor V. Rafienko


Dato : 23-05-02 17:21

[ dsl3353@vip.cybercity.dk ]

[ snip ]

> > Jeg har egentlig litt mer sans for den siste løsningen (dog, den
> > vil (sannsynligvis) koste mer, både tids- og plassmessig, og den
> > vil kreve å omskrive det du har laget hittil).
>
> Kan jeg få et hint til at gøre det på denne måde?

[ mumle noe om at ungdommen nå om dagen ikke er som vi var på deres
alder ]

Jeg har lekt med tanken selv en liten stund, men det blir utrolig
grisete uansett hvordan man skal gjøre dette: ideen er å dele opp
strengen i "biter" der separatoren er den teksten som skal byttes
bort. Bitene settes sammen ved å legge 'replacement' imellom:

char*
replace( const char *src, const char *replacee,
const char *replacement )
{
size_t result_length = 0U;
size_t replacement_length = strlen( replacement );
size_t suffix_length = 0U;

/* make sure there is room for the terminating '\0' */
char *result = malloc( 1 );
const char *start = src;
const char *stop = strstr( start, replacee );

while ( stop != NULL ) {
size_t segment_length = stop - start;
result = realloc( result,
result_length + segment_length + replacement_length );
   memmove( result + result_length,
start,
segment_length );
memmove( result + result_length + segment_length,
       replacement,
    replacement_length );
result_length += segment_length + replacement_length;

start = stop + strlen( replacee );
stop = strstr( start, replacee );
}

suffix_length = strlen( start );
if ( suffix_length ) {
   result = realloc( result,
          result_length + suffix_length );
memmove( result + result_length,
       start,
       suffix_length );
   result_length += suffix_length;
}

result[ result_length ] = '\0';
return result;
}


Denne funksjonen har noen barnesykdommer:

* Den vil ikke takle '\0' som data i src, replacee eller replacement
* Det er ingen feilhåndtering
* Håndering av overlappende "matches" foregår på en enkel, men ikke
nødvendigvis riktig måte. Men siden du unnlot å spesifisere dette,
får det bare bli slik.
* De hyppige kall på realloc vil sannsynligvis lede til
fragmenteringsproblematikk. Alternativet er å gjøre allokering i to
skritt: 1) allokere garantert nok hukommelse
    2) allokere akkurat nok og memmove resultatet
* Jeg tror[tm] at alle grensetilfellene er korrekte, men jeg har ikke
undersøkt det nøye. Dette er bare et utkast.





ivr
--
C++: "an octopus made by nailing extra legs onto a dog"
            -- Steve Taylor, 1998

Søg
Reklame
Statistik
Spørgsmål : 177496
Tips : 31968
Nyheder : 719565
Indlæg : 6408491
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste