|
| 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
| |
|
|