Avatar billede ultik Nybegynder
28. april 2002 - 18:12 Der er 6 kommentarer og
1 løsning

Streng problemer i C

Hej

Jeg har et problem med noget streng-manipulation jeg er igang med, så jeg vil håbe der er nogen der kan lokkes til at kigge på koden, og evt. udpege hvor det går galt.

#include <string.h>
// instr leder src igennem for at finde første occurance af srchfor
char *instr(char *src, char *srchfor)
{
    char *tmp, *found=NULL;

    // mens den kan finde det første bogstav i strengen
    while ((tmp = strchr(src, srchfor[0])) != NULL)
    {
        // tjek om resten af bogstaverne også matcher
        if (strncmp(tmp, srchfor, strlen(srchfor)) == 0)
        {
            // resultatet er fundet!
            found = tmp;
            return found;
        }
    }
    // = NULL hvis ikke fundet, ellers pointer til starten på den fundne streng
    return found;
}

char *split(char *src, char *delimiter, char *part2)
{
    // split deler src op efter den første delimiter og returnerer den første del
    // part2 kommer til at pege på den anden del.
    char *loc = instr(src, delimiter);
    // delimiteren findes slet ikke, returner src og sæt part2 til null
    if (!loc)
    {
        part2= NULL;
        return src;
    }
    // delim. findes, del strengen op, alloker plads til det
    char *part1 = (char *) malloc((loc - src));
    strncpy(part1, src, (loc-src));
    // anden del går galt åbenbart...
    // først flytter vi location hen til bagefter delimiteren
    loc += strlen(delimiter);
    // så allokerer vi plads til den
    part2 = (char *) malloc(strlen(loc));
    // og før vi returnerer sætter vi del2
    // strcpy(part2, loc);
    strcpy(part2, loc);
    debug(part2);
    return part1;
};

Problemet er så at når jeg kalder split() som længere nede, får jeg ikke det rigtige ud af den. Inde i koden ser det sådan her ud :

                    // Før kommandoen udføres skal der tages højde for at argumenter skal
                    // sendes i en anden variabel. Dette gør vi ved at dele kommandoen op i 2, efter et space.

char *params;
debug(command); // giver det rigtige
command = split(command, " ", params);
debug(command); // giver det rigtige
debug(params); // giver IKKE det rigtige

Inde i selve split funktionen giver mine debug kald de rigtige værdier... hvad går der galt?  ( debug er bare en wrapper til MessageBox og noget "sorter-debug-kald-fra-når-vi-builder-releases"-kode.. )

På forhånd tak.
Med venlig hilsen
Ulrik Jensen
ulrik@qcom.dk
Avatar billede ultik Nybegynder
28. april 2002 - 18:14 #1
der sidder også et par andre #includes øverst vel at mærke :

#include <windows.h>
#include <stdio.h>
Avatar billede ultik Nybegynder
28. april 2002 - 18:19 #2
just for reference så compiler jeg med Borlands gratis compiler, men regner ikke med at det skulle være så vigtigt
Avatar billede krukken Juniormester
28. april 2002 - 18:37 #3
Hvilke fejlmeddelser får du?!
Avatar billede fka_waldeinburg Nybegynder
28. april 2002 - 18:56 #4
Ulrik dog som du kan spørge :)
Når du allokerer hukommelse til en pointer udefra, skal du selvfølgelig have en reference til pointeren istedet for en kopi (tsk tsk). Derfor
char ** part2
og
* part2 = (char *) malloc(strlen(loc));
Avatar billede ultik Nybegynder
28. april 2002 - 19:00 #5
waldeinburg og jeg fandt ud af det over ICQ, og han postede derfor lige noget af løsningen, så vi kunne få pointsene ud af systemet, selve koden det blev ændret til følger her :

char *split(char *src, char *delimiter, char **part2)
{
    // split deler src op efter den første delimiter og returnerer den første del
    // part2 kommer til at pege på den anden del.
    char *loc = instr(src, delimiter);
    // delimiteren findes slet ikke, returner src og sæt part2 til null
    if (!loc)
    {
        part2= NULL;
        return src;
    }
    // del. findes, del strengen op, alloker plads til det
    char *part1 = (char *) malloc((loc - src));
    strncpy(part1, src, (loc-src));
    // anden del går galt åbenbart...
    // først flytter vi location hen til bagefter delimiteren
    loc += strlen(delimiter);
    // så allokerer vi plads til den
    *part2 = (char *) malloc(strlen(loc));
    // og før vi returnerer sætter vi del2
    // strcpy(part2, loc);
    strcpy(*part2, loc);
    debug(*part2);
    return part1;
};

char *params;
debug(command);
command = split(command, " ", &params);
debug(params);

og nu virker det så ;)
Avatar billede fka_waldeinburg Nybegynder
28. april 2002 - 19:04 #6
undskyld. Glemte et par "*part2" og et enkelt "&params". Men det må vi jo alle sammen lære at leve med. Det er jo ingen ulykke. JEG ANGRER ALTSÅ!
Avatar billede tson Nybegynder
28. april 2002 - 19:19 #7
Problemet er at parametre til funktioner overføres by-value i C. Så når du ændrer værdien af part2 inde i split funktionen (og det gør du jo med dit malloc kald), så ændrer det kun den lokale kopi af part2.

Du skal skrive split om så den sidste parameter er en char ** og ikke en char *, altså:

char *split(char *src, char *delimiter, char **part2)

Inde i funktionen skal du bruge *part2 alle de steder du nu har part2, så funktionen kommer til at se sådan her ud:


char *split(char *src, char *delimiter, char **part2)
{
    // split deler src op efter den første delimiter og returnerer den første del
    // part2 kommer til at pege på den anden del.
    char *loc = instr(src, delimiter);
    // delimiteren findes slet ikke, returner src og sæt part2 til null
    if (!loc)
    {
        *part2= NULL;
        return src;
    }

    // delim. findes, del strengen op, alloker plads til det
    char *part1 = (char *) malloc((loc - src));
    strncpy(part1, src, (loc-src));
    // anden del går galt åbenbart...
    // først flytter vi location hen til bagefter delimiteren
    loc += strlen(delimiter);
    // så allokerer vi plads til den
    *part2 = (char *) malloc(strlen(loc));
    // og før vi returnerer sætter vi del2
    // strcpy(part2, loc);
    strcpy(*part2, loc);
    //  debug(*part2);
    return part1;
};
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester