Avatar billede phrame Nybegynder
14. februar 2003 - 13:49 Der er 51 kommentarer og
1 løsning

problemer med string to char funktion

Heisan...

Jeg har skrevet følgende funktion:

char stoc( string stringtekst )
{    int    length = stringtekst.length(),
        i;
    char chartekst[ length ];

    for( i=0; i<length; i++ )
        chartekst[ i ] = stringtekst[ i ];

    chartekst[ i+1 ] = '\0';

    return *chartekst;
}

Men jeg får kun returnere et tegn fra denne funktion???
Avatar billede arne_v Ekspert
14. februar 2003 - 13:53 #1
Ja. Den er jo også erklæret som char ikke som char *.
Avatar billede arne_v Ekspert
14. februar 2003 - 13:54 #2
Prøv med:

char *stoc( string stringtekst )
{   
  int length = stringtekst.length(), i;
  char *chartekst = (char *)malloc(length;
    for( i=0; i<length; i++ )
        chartekst[ i ] = stringtekst[ i ];

    chartekst[ i+1 ] = '\0';

    return chartekst;
}
Avatar billede arne_v Ekspert
14. februar 2003 - 13:55 #3
Hov der manglede en parentes.

char *stoc( string stringtekst )
{   
  int length = stringtekst.length(), i;
  char *chartekst = (char *)malloc(length);
    for( i=0; i<length; i++ )
        chartekst[ i ] = stringtekst[ i ];

    chartekst[ i+1 ] = '\0';

    return chartekst;
}
Avatar billede arne_v Ekspert
14. februar 2003 - 13:56 #4
Jeg har lavet 2 ændringer:

1)  funktionen returnerer nu char * ikke char og det er return
    char tekst ikke return *chartekst

2)  Jeg bruger en dynamisk allokering som du skal huske at free'e later.
Avatar billede arne_v Ekspert
14. februar 2003 - 13:58 #5
re 2)  Man må *aldrig* lave:

char *stoc( string stringtekst )
{   
  int length = stringtekst.length(), i;
  char chartekst[ length ];
  for( i=0; i<length; i++ )
        chartekst[ i ] = stringtekst[ i ];

    chartekst[ i+1 ] = '\0';

    return chartekst;
}
Avatar billede arne_v Ekspert
14. februar 2003 - 13:58 #6
Men iøvrigt hvis den string er en stl string, så må der da være
en metode som returnerer en C string.
Avatar billede phrame Nybegynder
14. februar 2003 - 14:01 #7
kender du til den funktion som kan returnere den... selvom funktionen nu virker.... Når du mener "free"... mener du så "delete chartekst"... men hvordan kan jeg gører det efter jeg har returnere chartekst??
Avatar billede hsloth Novice
14. februar 2003 - 14:03 #8
std::string har en funktion c_str() der returnerer en char pointer.
Avatar billede hsloth Novice
14. februar 2003 - 14:04 #9
Dvs. du kan lave :

char *stoc(std::string stringtekst) { return stringtekst.c_str();}
Avatar billede miknil Nybegynder
14. februar 2003 - 14:04 #10
Det er alt for besværligt selv at oprette den nye string, brug std::string::c_str()

miknil
Avatar billede miknil Nybegynder
14. februar 2003 - 14:05 #11
som hsloth også påpeger :-)

miknil
Avatar billede miknil Nybegynder
14. februar 2003 - 14:06 #12
arne > hvad er en C string, mener du et nultermineret char array ?
Avatar billede phrame Nybegynder
14. februar 2003 - 14:22 #13
hsloth> vildt elegant løsning... men nu får jeg bare fejlen "cannot convert const char * to char * in return"....
Avatar billede phrame Nybegynder
14. februar 2003 - 14:27 #14
åbenbart kan jeg jo bare lave returntype const og lade de variabler som jeg skal bruge funktionen til const.... men på hvilken måde kan det påvirke min kode i det lange løb?
Avatar billede hsloth Novice
14. februar 2003 - 14:27 #15
arne_v >>
Du skriver at man ikke MÅ lave en konstruktion som :

  int length = stringtekst.length();
  char chartekst[length];

og så returnerer chartekst pointeren.

Sandheden er vel at man ikke kan lave et char array med en varianle længde ved hjælp af [] operatoren, og at man vil være nødt til at bruge new eller malloc, altså f.eks. :


  int length = stringtekst.length();
  char *chartekst = new char[length];

eller har jeg misforstået noget ?
Avatar billede hsloth Novice
14. februar 2003 - 14:27 #16
varianle == variabel
Avatar billede arne_v Ekspert
14. februar 2003 - 14:31 #17
phrame>

Du bør bruge den c_str funktion.
Avatar billede arne_v Ekspert
14. februar 2003 - 14:31 #18
miknil>

Ja en C string er et nul termineret char array.
Avatar billede arne_v Ekspert
14. februar 2003 - 14:33 #19
phrame>

Når man bruger:
char *p = (char *)malloc(1000);
skal man bruge
free(p);

Når man bruger:
  char *p = new char[1000];
skal man bruge:
  delete p;

(det først kan bruges både i C og C++ - det sidste er C++ only)
Avatar billede arne_v Ekspert
14. februar 2003 - 14:34 #20
hsloth>

Så godt som alle moderne C compilere understøtter arrays hvor
dimensionereingen er en variabel som ikke kendes på compile time.
Avatar billede miknil Nybegynder
14. februar 2003 - 14:34 #21
arne >

altså

int main(void)
{
  C string a = (C string)malloc(100);
  memset(a,1,99);
  a[99] ='\0';
  printf("%s",a);
  return 0;
}

er lovlig C syntax ?

miknil
}
Avatar billede hsloth Novice
14. februar 2003 - 14:35 #22
Så må vi ha' et cast på banen :

char *stoc(std::string stringtekst) { return (char*)stringtekst.c_str();}

Det du skal være opmærksom på er at du ikke må modificere det indhold som pointeren fra stoc() peger på. Så længe du kun bruger den til at læse skulle det være ok. Grunden til at c_str() returnerer en const pointer er at pointeren peger direkte ned i std::string'ens interne lager
Avatar billede arne_v Ekspert
14. februar 2003 - 14:35 #23
hsloth>

Featuren er iøvigt en del af C99 standarden.
Avatar billede hsloth Novice
14. februar 2003 - 14:37 #24
arne_v>>

Når man bruger new[] skal man huske altid at bruge delete[] !
Avatar billede phrame Nybegynder
14. februar 2003 - 14:37 #25
jeg har også brugt din først løsning arne, altså:
char *stoc( string stringtekst )
{   
  int length = stringtekst.length(), i;
  char chartekst[ length ];
  for( i=0; i<length; i++ )
        chartekst[ i ] = stringtekst[ i ];

    chartekst[ i+1 ] = '\0';

    return chartekst;
}

hvilket virkede perfekt... men så jeg anbefalet af hsloth char *stoc(std::string stringtekst) { return stringtekst.c_str();}
Avatar billede arne_v Ekspert
14. februar 2003 - 14:37 #26
miknil>

Selvfølgelig er det ikke det.

char pointer a;

er heller ikke legal C, men de fleste forstår godt hvad man mener, når man
skriver "char pointer".
Avatar billede phrame Nybegynder
14. februar 2003 - 14:37 #27
glemte lige... men så får jeg fejlen "cannot convert const char * to char * in return"....

jeg ville hellere bruge din løsning arne... men hlsoth løsning er meget mere simpel og elegant....
Avatar billede arne_v Ekspert
14. februar 2003 - 14:41 #28
Jeg synes at det er pænere at bruge stl string c_str metoden.

Men spørgsmålet er om du overhovedet har brug for en
stoc funktion så - om ikke bare du kan bruge den c_str
metode samme sted som du vil bruge stoc ?
Avatar billede miknil Nybegynder
14. februar 2003 - 14:41 #29
Hvorfor ikke bruge de der til indrettede metoder ?

Ville du også  hellere bruge

for(i=0;i<100;i++)
  a[i] = '1';

end

memset((void*)a,1,99);

miknil
Avatar billede miknil Nybegynder
14. februar 2003 - 14:42 #30
eller memset((void*)a,1,sizeof(char)*99) for at være helt præcis
Avatar billede miknil Nybegynder
14. februar 2003 - 14:44 #31
aarrghh... memset((void*)a,1,sizeof(char)*100) for at være helt præcis
Avatar billede arne_v Ekspert
14. februar 2003 - 14:54 #32
miknil>

C standarden kræver sizeof (char) == 1 og jeg har heller aldrigt mødt en
compiler hvor det var tilfældet, så er den ikke overflødig.
Avatar billede phrame Nybegynder
14. februar 2003 - 14:54 #33
jeg kommer lige tilbage dette senere... har nogle andre programmerings problemmer som er dukket op i andre områder af projektet....
Avatar billede miknil Nybegynder
14. februar 2003 - 14:57 #34
arne>
Jeg synes det er god programmeringsskik at angive størrelsen, det gør vedligeholdelsen af koden enklere.
(hvis du fx skulle ønske at skifte til unicode på et tidspunkt)

miknil
Avatar billede arne_v Ekspert
14. februar 2003 - 14:58 #35
hsloth>

Du har ret - det bør være delete[] (det er det korrekte også selvom jeg
tror de fleset C++ compilere vil gøre det rigtigte med delete).
Avatar billede arne_v Ekspert
14. februar 2003 - 15:01 #36
miknil>

Unicode eller ikke unicode ændrer ikke på at sizeof(char) altid
er 1.

Der er derimod ingen garanti for at en char har størrelsen 8 bit.

Jeg troede iøvrigt at man normalt brugte wchar_t til at løse unicode
problemer med ??
Avatar billede hsloth Novice
14. februar 2003 - 15:01 #37
arne_v>>

Erfaringen viser at compileren vil generere kode der vikrer rigtigt indtil :

a) man skal vise sit program for en demo
eller
b) programmet netop er installeret hos ens vigtigste kunde
Avatar billede arne_v Ekspert
14. februar 2003 - 15:03 #38
hsloth>

:-)

Jeps.

En logisk følge af at den kendte lov om at sandsyneligheden for at
en tabt marmelade mad lander med marmeladen nedad vokser med
tæppets pris.
Avatar billede miknil Nybegynder
14. februar 2003 - 15:08 #39
arne >
For at skifte til unicode skal alle instancer af char skiftes til wchar_t.

I så fald ville
  memset((void*)a,1,sizeof(char)*100)
blive ændret til
  memset((void*)a,1,sizeof(wchar_t)*100)

mens
memset((void*)a,1,100)

nok ville resultere i at koden ikke blev opdateret og dermed er der introduceret en fejl.


miknil
Avatar billede miknil Nybegynder
14. februar 2003 - 15:15 #40
Og så kan man jo lade compileren om at bort optimere sizeof(char)

miknil
Avatar billede hsloth Novice
14. februar 2003 - 15:16 #41
arne_v>
C99 garanterer at sizeof(char) er 1 OG at en char fylder 8 bit - 1 byte, jvf afsnit 6.5.3.4.2 og 6.5.3.4.3

og så havde jeg overset at 6.7.5.2.1 i C99 tillader erklæring af et array på stakken ved hjælp af [] - min fejl.
Avatar billede arne_v Ekspert
14. februar 2003 - 15:30 #42
miknil>

Folk der skifter til unicode ved søg og erstat af char til wchar_t
får nok andre problemer.
Avatar billede arne_v Ekspert
14. februar 2003 - 15:31 #43
hsloth>

Så char skal være 8 bit i C99. Det mener jeg er nyt. Men sådan set
meget logisk.
Avatar billede miknil Nybegynder
14. februar 2003 - 15:31 #44
arne>
Der er nok ingen der skifter til unicode udelukkende v.b.a
søg og erstat, men hvorfor gøre det vanskeligere for sig selv
end højst nødvendigt.
Det er lettere at overse 1 end sizeof(char) !

miknil
Avatar billede arne_v Ekspert
26. februar 2003 - 22:55 #45
phrame>

Tid at lukke spørgsmålet ?
Avatar billede olennert Nybegynder
07. marts 2003 - 16:43 #46
arne_v>
Du skriver noget med at de fleste oversættere vil gøre det rigtige hvis du kommer til at skrive delete i forhold til delete[]. De oversættere jeg har kendskab til vil *ikke* gøre det rigtige i dette tilfælde, idet kun delete[] garanterer at destructors bliver kaldt for alle allokerede elementer. delete vil kalde destructor for det første element.
Avatar billede olennert Nybegynder
07. marts 2003 - 16:43 #47
phrame>
Er det ikke på tide at få lukket for spørgsmålet?
Avatar billede arne_v Ekspert
07. marts 2003 - 17:08 #48
olennert>

Enten bruger du nogle meget specielle compilere eller så overså du lige
i forbi farten at det er char's vi new'er og delete'r (og den har ingen
destructor !).

:-)
Avatar billede olennert Nybegynder
18. marts 2003 - 15:05 #49
arne_v >> Doh! Du har som sædvanlig fuldstændig ret. Men *hvis* nu char havde haft en d'tor, så havde jeg haft ret :-).

Derudover synes jeg det er god skik at bruge delete[] sammen med new[]. Eksempelvis hvis man har en eller anden typedef som i øjeblikket er en char*, men som om fem år bliver MyOwnChar*, hvor MyOwnChar er en eller anden klasse.
Avatar billede arne_v Ekspert
18. marts 2003 - 15:12 #50
Helt rigtigt.

Det indrømmede jeg også 14/02-2003 14:58:04 !
Avatar billede phrame Nybegynder
26. marts 2003 - 18:56 #51
den her diskusion er vist kommet på afveje...
Avatar billede arne_v Ekspert
26. marts 2003 - 18:59 #52
Jo, men flere af svarene kunne vel godt bruges alligevel - eller ?
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