/ 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
Ren C og sprintf() ved skrivning til samme~
Fra : Bertel Lund Hansen


Dato : 23-02-03 14:29

Hej alle

Er det jkorrekt opførsel af compileren når man ikke kan stole på
at følgende virker:

   char linje[] = "Et eller andet snask";
   char *pos;

   ...
   pos=strchr(linje,' ');
   *pos=0;
   pos=strstr(linje,"snask");
   sprintf(linje,"%s %s",linje,pos);
   ...

Planen var at det skulle give "Et snask", men jeg har lige bokset
en hel formiddag med et program og sære fejl indtil jeg sprintede
til en char-buffer i stedet for og derfra tilbage til linje.

--
Bertel

I øvrigt er det svært hele tiden af skaffe nye sentenser.

 
 
Michael Rasmussen (23-02-2003)
Kommentar
Fra : Michael Rasmussen


Dato : 23-02-03 14:37

On Sun, 23 Feb 2003 14:29:23 +0100, Bertel Lund Hansen wrote:

> Hej alle
>
> Er det jkorrekt opførsel af compileren når man ikke kan stole på
> at følgende virker:
>
>    char linje[] = "Et eller andet snask"; char *pos;
>
>    ...
>    pos=strchr(linje,' ');
>    *pos=0;
>    pos=strstr(linje,"snask");
>    sprintf(linje,"%s %s",linje,pos);
>    ...
>
Du har ikke tildelt noget memory til pos, så den er ikke pålidelig.
Prøv noget i stil med:
pos = (char *) malloc(strlen(linje)+1);

--
Hilsen/Sincerely
Michael Rasmussen

En windows admin er en person, for hvem den største bedrift er, at
lave konfiguration af serveren med trial and error via en gui.


Bertel Lund Hansen (23-02-2003)
Kommentar
Fra : Bertel Lund Hansen


Dato : 23-02-03 14:52

Michael Rasmussen skrev:

>Du har ikke tildelt noget memory til pos

Nej, det er jo noget af fidusen. Pos peger midt ned i linje. En
allokering til pos ville være spildt - og (hukommelses)spild hvis
det ikke blev frigivet.

--
Bertel

I øvrigt er det svært hele tiden af skaffe nye sentenser.

Michael Rasmussen (23-02-2003)
Kommentar
Fra : Michael Rasmussen


Dato : 23-02-03 15:02

On Sun, 23 Feb 2003 14:51:53 +0100, Bertel Lund Hansen wrote:

>
> Nej, det er jo noget af fidusen. Pos peger midt ned i linje. En
> allokering til pos ville være spildt - og (hukommelses)spild hvis
> det ikke blev frigivet.
Det er da heller ikke noget problem at frigive memory!
free(pos)

Men, som jeg ser det, afslutter du aldrig strengen korrekt:
pos=strstr(linje,"snask");
burde du ikke tilføje '\0' til enden af strengen?
*++pos = '\0';

--
Hilsen/Sincerely
Michael Rasmussen

En windows admin er en person, for hvem den største bedrift er, at
lave konfiguration af serveren med trial and error via en gui.


Bertel Lund Hansen (23-02-2003)
Kommentar
Fra : Bertel Lund Hansen


Dato : 23-02-03 16:18

Michael Rasmussen skrev:

>Det er da heller ikke noget problem at frigive memory!
>free(pos)

Næ, men hvorfor allokere og frigive hukommelse som ikke skal
bruges?

Med din opskrift:

Init:
linje = [E t e l l e r a n d e t s n a s k ]
pos = []

Efter ordren pos = linje;
pos = linje = [E t e l l e r a n d e t s n a s k ]
/død hukommelse/ = []

>burde du ikke tilføje '\0' til enden af strengen?

Nej, det gør sprintf selv. Eneste krav (som jeg kender) er at
target skal have plads til den nye streng, og det har den
automatisk når jeg laver den kortere.

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

Leo Laursen (23-02-2003)
Kommentar
Fra : Leo Laursen


Dato : 23-02-03 16:27

Michael Rasmussen <mir@datanom.net>:
>> Nej, det er jo noget af fidusen. Pos peger midt ned i linje. En
>> allokering til pos ville være spildt - og (hukommelses)spild hvis
>> det ikke blev frigivet.
> Det er da heller ikke noget problem at frigive memory!
> free(pos)

Det er et problem at allokere noget hukommelse, bare for at flytte pos
pointeren over til et helt andet segment.
Kan man overhovedet lave free(pos) hvis den har mistet kontakten til det
allokerede område?

> Men, som jeg ser det, afslutter du aldrig strengen korrekt:
> pos=strstr(linje,"snask");
> burde du ikke tilføje '\0' til enden af strengen?
> *++pos = '\0';

En stringliteral er nultermineret, så det var noget af det første Bertel
gjorde.

*++pos et positionen n i "snask", som så bliver slettet.

Leo
--
Watson's Law:
   The reliability of machinery is inversely proportional to the
   number and significance of any persons watching it.

Bertel Lund Hansen (23-02-2003)
Kommentar
Fra : Bertel Lund Hansen


Dato : 23-02-03 16:31

Leo Laursen skrev:

>Kan man overhovedet lave free(pos) hvis den har mistet kontakten til det
>allokerede område?

Jeg mener at resultatet er udefineret, og jeg ved at det ikke
virker efter hensigten.

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

Kim Hansen (23-02-2003)
Kommentar
Fra : Kim Hansen


Dato : 23-02-03 14:58

Bertel Lund Hansen <nospamfor@lundhansen.dk> writes:

> Hej alle
>
> Er det jkorrekt opførsel af compileren når man ikke kan stole på
> at følgende virker:
>
>    char linje[] = "Et eller andet snask";
>    char *pos;
>
>    ...
>    pos=strchr(linje,' ');
>    *pos=0;
>    pos=strstr(linje,"snask");

Her har du lige rettet linje til "Et", så snask kan ikke findes i
linje. Du kunne i steder skrive:
   pos=strstr(pos+1,"snask");

>    sprintf(linje,"%s %s",linje,pos);
>    ...
>
> Planen var at det skulle give "Et snask", men jeg har lige bokset
> en hel formiddag med et program og sære fejl indtil jeg sprintede
> til en char-buffer i stedet for og derfra tilbage til linje.

Med den rettelse får jeg "Et snask"

--
Kim Hansen | |\ _,,,---,,_ | Det er ikke
Dalslandsgade 8, A708 | /,`.-'`' -. ;-;;,_ | Jeopardy.
2300 København S | |,4- ) )-,_. ,\ ( `'-' | Svar _efter_
Phone: 32 88 60 86 | '---''(_/--' `-'\_) | spørgsmålet.

Bertel Lund Hansen (23-02-2003)
Kommentar
Fra : Bertel Lund Hansen


Dato : 23-02-03 16:13

Kim Hansen skrev:

>>    *pos=0;
>>    pos=strstr(linje,"snask");
>
>Her har du lige rettet linje til "Et", så snask kan ikke findes i
>linje.

Ja, det var en fejl i eksemplet som ikke var i mit program.

>Med den rettelse får jeg "Et snask"

Jeg fik linjer med manglende tegn skrevet ned til min udfil
indtil jeg ændrede som forklaret.

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

Soeren Sandmann (23-02-2003)
Kommentar
Fra : Soeren Sandmann


Dato : 23-02-03 17:44

Bertel Lund Hansen <nospamfor@lundhansen.dk> writes:

> Jeg fik linjer med manglende tegn skrevet ned til min udfil
> indtil jeg ændrede som forklaret.

Det havde nok været nemmere at stille spørgsmålet "er det tilladt at
bruge sprintf() til at læse og skrive det samme sted i hukommelsen på
samme tid, fx ..."

Jeg kan ikke svare på spørgsmålet, men jeg ville undgå at gøre det,
selv hvis det er tilladt ifølge standarden, fordi det er et specielt
tilfælde som den der har skrevet sprintf(), måske ikke har taget højde
for.

Bertel Brander (24-02-2003)
Kommentar
Fra : Bertel Brander


Dato : 24-02-03 05:43

Bertel Lund Hansen skrev:
> Hej alle
>
> Er det jkorrekt opførsel af compileren når man ikke kan stole på
> at følgende virker:
>
>    char linje[] = "Et eller andet snask";
>    char *pos;
>
>    ...
>    pos=strchr(linje,' ');
>    *pos=0;
>    pos=strstr(linje,"snask");
>    sprintf(linje,"%s %s",linje,pos);
>    ...
>
> Planen var at det skulle give "Et snask", men jeg har lige bokset
> en hel formiddag med et program og sære fejl indtil jeg sprintede
> til en char-buffer i stedet for og derfra tilbage til linje.
>
Ja, kompileren opfører sig korrekt. Ifølge "man sprintf":

#include <stdio.h>

int sprintf( str, format [, arg,
char * str;
char * format;

fprintf, sprintf and snprintf are identical to printf,
other than the destination of the formatted output:
fprintf sends the output to a specified file fd, while
sprintf stores the output in the specified char array str
and snprintf limits number of characters written to str to
at most size (including terminating 0). For sprintf and
snprintf, the behavior is also undefined if the output
*<[str>> overlaps with one of the arguments.

Det betyder at man ikke kan bruge den samme streng som argument og
destination.

/b
--
Bertel Brander, author of Wain, a free text editor for programmers:
http://home20.inet.tele.dk/midgaard/program.htm


Bertel Lund Hansen (23-02-2003)
Kommentar
Fra : Bertel Lund Hansen


Dato : 23-02-03 20:44

Bertel Brander skrev:

> at most size (including terminating 0). For sprintf and
> snprintf, the behavior is also undefined if the output
> *<[str>> overlaps with one of the arguments.

>Det betyder at man ikke kan bruge den samme streng som argument og
>destination.

Mange tak. Det var forklaringen.

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

Bertel Lund Hansen (24-02-2003)
Kommentar
Fra : Bertel Lund Hansen


Dato : 24-02-03 10:09

Bertel Brander skrev:

>Det betyder at man ikke kan bruge den samme streng som argument og
>destination.

Gælder det forresten også for strcat()?

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

Jacob Bunk Nielsen (24-02-2003)
Kommentar
Fra : Jacob Bunk Nielsen


Dato : 24-02-03 10:13

Bertel Lund Hansen <nospamfor@lundhansen.dk> writes:
> Bertel Brander skrev:
>
>>Det betyder at man ikke kan bruge den samme streng som argument og
>>destination.
>
> Gælder det forresten også for strcat()?

Fra strcat(3):

,----
| DESCRIPTION
| The strcat() function appends the src string to the dest
| string overwriting the `\0' character at the end of dest,
| and then adds a terminating `\0' character. The strings
| may not overlap, and the dest string must have enough
| space for the result.
|
| The strncat() function is similar, except that only the
| first n characters of src are appended to dest.
`----

Så svaret er vist ja.

--
Jacob - www.bunk.cc
People who push both buttons should get their wish.

Søg
Reklame
Statistik
Spørgsmål : 177491
Tips : 31966
Nyheder : 719565
Indlæg : 6408458
Brugere : 218886

Månedens bedste
Årets bedste
Sidste års bedste