Avatar billede jepper Nybegynder
08. marts 2000 - 19:36 Der er 13 kommentarer og
1 løsning

Sæt strenge sammen i C++

Hejsa,
ok det er nok lidt af et begynderspm, men her er det alligevel.

Kode:
char aa[] = "hej ";
char bb[] = "med ";
char cc[] = "dig";
char dd[] = aa,bb,cc;

Hvordan sætter jeg så a, b  og c sammen?

Output:
C:\test.cpp(42) : error C2440: 'initializing' : cannot convert from 'char [5]' to 'char []'
        There is no context in which this conversion is possible
C:\test.cpp(42) : error C2040: 'bb' : 'char' differs in levels of indirection from 'char [5]'
C:\test.cpp(42) : error C2040: 'cc' : 'char' differs in levels of indirection from 'char [4]'

Hvad gør jeg galt?
Avatar billede stoltze Nybegynder
09. marts 2000 - 08:55 #1
Hej Jepper

Egentlig findes der ikke  strenge i C, istedet bruger arrays of char. Når skriver "char[] xx" laver du en pointer til det array. Når du skirver char[] xx = "Noget memory" afsætter du memory til det array og initialiserer det med en tekst. Du kan også allokere memory uden at initalisere det med f.eks "char xx[32]" prøv følgende:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void main()
{
  char aa[] = "Hej ";
  char bb[] = "med ";
  char cc[] = "dig.";

  char s[32];

  /* Kopier en streng */

  strcpy(s, aa);

  /* Tilføj til streng */

  strcat(s, bb);
  strcat(s, cc);

  /* Udskriv */

  printf("%s\n", s);

  return;
}

Hilsen Stoltze
Avatar billede stoltze Nybegynder
09. marts 2000 - 08:58 #2
Der skal stå et procent tegn foran det første s i printf. Browseren laver det om.

Hilsen Stoltze
Avatar billede dmk Nybegynder
09. marts 2000 - 09:32 #3
Hej Jepper

En mere simple måde at sætte strenge og tal sammen på er, at bruge funktionen sprintf.

sprintf fungerer lige som printf, den skriver blot output til en buffer i stedet for stdout. I dit eksempel fra før kunne du have lavet dd således:

sprintf(dd, "%s%s%s", aa, bb, cc);

%s betyder "her skal stå en streng", og funktionen printer så strengen ind på %s's plads. Det gør jeg så 3 gange lige efter hinanden, og din streng er sat sammen!
Du skal dog lige være opmærksom på, at strengen dd skal være stor nok til at alle de tre andre strenge kan stå i den. Funktionen checker ikke noget, og hvis ikke der er plads nok, så får du en access violation.

Du kan også skrive tal ind på denne måde:

int Tal=4;
char* String="noget tekst";
char Buffer[200];
sprintf(Buffer, "%s %d", String, Tal);

Buffer vil så indeholde: "noget tekst 4";

DMK
Avatar billede jepper Nybegynder
09. marts 2000 - 11:07 #4
OK, nu var det godt nok i C++ jeg ville lave det. Det der med %streng har jeg prøvet, er der ikke en tilsvarende metode i cpp?
Avatar billede dmk Nybegynder
09. marts 2000 - 11:37 #5
Øhh? Det er da cpp?

C++ er ikke andet end standard c med lidt ekstra muligheder, så som klasser osv. Men grundstenene i c++ er de samme som i c, og måden at håndtere strenge på er den samme! Du kan selvfølgelig nemt lave din egen strengklasse, og det er også ofte noget af det aller første man laver, når man begynder at kode c/c++, da man skal bruge strenge hele tiden. Derfor er det ret smart at have noget testet kode, som man bruger alle steder, i stedet for at lave forskellige felj forskellige steder.

Du kan sikkert godt finde nogle streng-klasser rundt omkring på nettet, men jeg vil anbefale dig at lave din egen, da du så bedre forstår hvad der egentlig sker. Det er i øvrigt en rigtig god øvelse som nybegynder.


DMK
Avatar billede jepper Nybegynder
09. marts 2000 - 14:41 #6
Aha. Nu forstår jeg det bedre :)
Men der er stadig et problem.
Nu får jeg dette output:

test.exe
hej med med med

Koden er:
#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void main()
{
char aa[] = "hej ";
char bb[] = "med ";
char cc[] = "dig";
char dd[] = "";
char s[32];

sprintf(dd, "%s%s%s", aa, bb, cc);

cout << dd;

}

Hvorfor bliver dd til aa og s til bb?
Avatar billede dmk Nybegynder
09. marts 2000 - 14:43 #7
Du prøver at printe noget resultat ind i en buffer der ikke er allokeret! Det burde give en Access Violation...

Du skal skrive resultatet ind i s i stedet for dd.

sprintf(s, "...)

cout<<s;


:-) DMK
Avatar billede jepper Nybegynder
09. marts 2000 - 15:03 #8
Fedt, nu virker det.

Mange tak for hjælpen!
Avatar billede jepper Nybegynder
09. marts 2000 - 16:19 #9
Ok, lige en sidste en :-)

Hvordan konverterer man mellem i dette tilfælde bla1 og bb[]
Det er da det der bliver gjort, ikke?

Kode:
#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


void bla2(char input)
{
    char aa[] = "hej ";
    char bb[] = input;
    char cc[] = "dig";
    char s[32];
   
    sprintf(s, "%s%s%s", aa, bb, cc);
   
    cout << s;
   
}

void main(void)
{
    char bla1 = "med ";
    bla2(bla1);
}

Error:
test.cpp
E:\slet\test.cpp(10) : error C2440: 'initializing' : cannot convert from 'char' to 'char []'
        There are no conversions to array types, although there are conversions to references or pointers to arrays
E:\slet\test.cpp(22) : error C2440: 'initializing' : cannot convert from 'char [5]' to 'char'
        This conversion requires a reinterpret_cast, a C-style cast or function-style cast
Error executing cl.exe.

test.exe - 2 error(s), 0 warning(s)
Avatar billede dmk Nybegynder
09. marts 2000 - 16:31 #10
Problemet er, at du har erklæret "bla1" samt parameteren "input" som en enkelt karakter, hvor du i virkeligheden ville have haft en streng (dvs. en char*).


#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


void bla2(char* input)
{
    char* aa = "hej ";
    char* bb = input;
    char* cc = "dig";
    char s[32];
   
    sprintf(s, "%s%s%s", aa, bb, cc);
   
    cout << s;
   
}

void main(void)
{
    char* bla1 = "med ";
    bla2(bla1);
}


Det skulle virke.


DMK
Avatar billede jepper Nybegynder
09. marts 2000 - 17:47 #11
Du havde som sædvanlig ret :)
Avatar billede soepro Nybegynder
13. marts 2000 - 09:43 #12
De fleste C++ compilere inkludere faktisk en foruddefineret streng klasse - ligeledes de fleste steder implementeret med navnet 'AnsiString'. Pricinpperne for brugen er meget analoge til char[], men den eliminerer ofte muligheden for nogle af de fælder, som du allerede HAR opdaget - f.eks. memoryoverskrivningen i 'sprintf(bla, "....'. Samtidigt er diverse operatorer overloaded, hvilket gør det mere enkelt at flytte rundt på strengenes indhold, lave sammenligninger osv. :

AnsiString A,B;
:
  if(A == B) // I modsætning til strcmp(A, B) == 0
:
  A = B; // I modsætning til strcpy(A, B)
:
  A = B + " osv."; // I modsætning til strcpy(A, B); strcat(A, " osv.");
Avatar billede dmk Nybegynder
14. marts 2000 - 13:57 #13
AnsiString er vel noget Borland Builder specifikt, og ikke noget der generelt er med i en c++ compiler? AnsiString (Borland Builder version) er i øvrigt lavet i objekt pascal og ikke C++, da den er en del af VCL, eller hva'?
Jeg må nok indrømme at jeg taler ud fra hukommelse, da jeg ikke har Borland på min computer mere. Jeg bruger pt kun Visual og gcc/g++ (Linux), og her er jeg bestemt ikke bekendt med nogen AnsiString klasse.

DMK
Avatar billede soepro Nybegynder
15. marts 2000 - 08:16 #14
dmk >> Den findes også i VB, hvor den blot hedder String. Jvnf. Borlands manualer (og navnet) er det ganske alm. ANSI C++.
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