Fast i pekarträsket... [löst]

Elektronik- och mekanikrelaterad mjukvara/litteratur. (T.ex schema-CAD, simulering, böcker, manualer mm. OS-problem hör inte hit!)
Användarvisningsbild
oJsan
EF Sponsor
Inlägg: 1541
Blev medlem: 11 november 2005, 21:36:51
Ort: Umeå
Kontakt:

Fast i pekarträsket... [löst]

Inlägg av oJsan »

Pekare kan vara bra ibland, men det är inte alla gånger man bemästrar dem.
Denna lilla 2D-array har jag deklarerat globalt (ANSI C):

Kod: Markera allt

char * symbols[2][3] = 
{
	{	
		"ABC",
		"DEF",
		"GHI"
	},
	{
		"123",
		"456",
		"789"
	}
};
Senare i programmet vill jag skriva ut strängen "456". Utan att fundera det minsta så skrev jag:

Kod: Markera allt

printf("%s\n",symbols[1][1]);
Tyvärr gillade inte kompilatorn detta utan tyckte: error: expression must be a pointer to a complete object type


Initierar jag en variabel såhär:

Kod: Markera allt

	char ** cp = *symbols;
Så kan jag indexera alla sex strängar med cp[x], där x är 0-5
Jag vill ju kunna indexera i TVÅ dimensioner, precis som arrayen från början skapades, dvs cp[x][y]. Någon som förstår mitt problem och vet hur man bäst löser det?!

I minnet lagras strängarna för övrigt som en array av addresser. Var och en av adresserna pekar till en av de sex strängarna..
Senast redigerad av oJsan 20 juli 2006, 22:21:07, redigerad totalt 1 gång.
Användarvisningsbild
Icecap
Inlägg: 26632
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Ta bort pekarinitiatorn:

Kod: Markera allt

const char symbols[2][3] =
  {
    {"ABC",
      "DEF",
      "GHI"},
    {"123",
      "456",
      "789"}
  };
Den originala definition sparar först datan OCH sedan (i teorin, beroende på kompilern) ett array med pekare till dessa data varpå du indexerar i detta pekararray.

Du kanske inte behöver 'const' först men det är mest korrekt. Om "printf("%s\n",symbols[1][1]);" inte vill vara med utan att gnälla kan du använda "printf("%s\n",(char*)symbols[1][1]);"
Användarvisningsbild
oJsan
EF Sponsor
Inlägg: 1541
Blev medlem: 11 november 2005, 21:36:51
Ort: Umeå
Kontakt:

Inlägg av oJsan »

Ajdå, nu upptäckte jag ett problem i min förenklade frågeställning. Egentligen så är matrisen mycket större, men jag förenklade den för den här tråden... alla strängar är nämligen inte lika långa!
Bra förslag Icecap, men det kommer inte att fungera om du ersätter strängen "ABC" med "ABCDE".
Det är en 2D-array av char* (pekare till null-terminerade strängar alltså) jag vill ha, och inte en matris av char.
Användarvisningsbild
oJsan
EF Sponsor
Inlägg: 1541
Blev medlem: 11 november 2005, 21:36:51
Ort: Umeå
Kontakt:

Inlägg av oJsan »

Kom igen nu, visa vad ni kan när det gäller C-programmering! =D

Tillsvidare har jag löst problemet genom att göra såhär:

Kod: Markera allt

 char ** cp = *symbols;
 char * stringptr = cp[2*x + y];
Men det är ju inge vidare snyggt... :(
så tips och ideér är välkomna!
Användarvisningsbild
Icecap
Inlägg: 26632
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

OK, testa "printf("%s\n",&symbols[1][1]);"
Användarvisningsbild
ahlsten
Inlägg: 659
Blev medlem: 12 november 2005, 00:24:14
Ort: Uppsala

Inlägg av ahlsten »

Konstigt, vad har du för versioner av bibliotek och kompilator? För det kändes ju som att det skulle fungera och när jag kompilerade följande:

Kod: Markera allt

 
#include <stdio.h>

char* symbols[2][3] =
{
   {
      "ABC",
      "DEF",
      "GHI"
   },
   {
      "123",
      "456",
      "789"
   }
};

int main(int argc, char** argv)
{
   int i, e;
   if(argc < 3)
   {
      i = e = 1;
   }
   else
   {
      i = (int)*argv[1] - 48;
      e = (int)*argv[2] - 48;
   }
   printf("%s\n", symbols[i][e]);
   return 0;
}
med gcc ver 3.4.4 så fungerade det utmärkt...
Användarvisningsbild
oJsan
EF Sponsor
Inlägg: 1541
Blev medlem: 11 november 2005, 21:36:51
Ort: Umeå
Kontakt:

Inlägg av oJsan »

Kompilatorn som jag använder är de som ingår i VisualDSP++, men det är en "standard"-kompilator enligt ANSI/ISO men med några tilläg för DSP.

Jag har lokaliserat problemet nu, det fattades ett par siffror i min header-fil.
2D-arrayen med strängar var definierad i en c fil och användes i en annan, därför hade jag en global.h där arrayen deklareras som "extern":

Kod: Markera allt

extern char * symbols[][];
I andra fall där man använder arrayer så är det ju ok att lämna parenteserna tomma i h-filerna, så man slipper ändra på två ställen när man vill ändra arrayens storlek. Här fanns alltså mitt problem, skrev jag in arrayens storlek även i h-filen (alltså: [2][3]) så funkar det!

:D
*glad*

Edit: förtydligande...
Användarvisningsbild
ahlsten
Inlägg: 659
Blev medlem: 12 november 2005, 00:24:14
Ort: Uppsala

Inlägg av ahlsten »

Ah! Ja då trodde kanske kompilatorn att dimensionenerna skulle bestämmas run-time? Sådana multidimensionella arrayer är ju klart jobbigare...
Skönt att det löste sig, problem som löser sig is teh shit :wink:
Användarvisningsbild
oJsan
EF Sponsor
Inlägg: 1541
Blev medlem: 11 november 2005, 21:36:51
Ort: Umeå
Kontakt:

Inlägg av oJsan »

Ja precis, eftersom kompilatorn inte ens vet om arrayen finns så förlitar den ju sig på definitionen i headerfilen. Och nu när jag skrivit fullständig info så funkar det prima efter länkning!
Jag la även till "const" före eftersom arrayen ju faktiskt ÄR konstant och inte ska gå att ändra... bra tips Icecap! Rätta mig om jag har fel, men const gör väl ingen skillnad för maskinkoden, det är väl bara ett sätt att undvika problem vid kodskrivning? (Så man inte "råkar" sätta en pekare till symbols och modifiera innehållet oavsiktligt... )
Användarvisningsbild
Icecap
Inlägg: 26632
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Beroende på mål o dylikt kan det skilja mellan att spara data i RAM eller ROM(/flash eller vad fan man har) och samtidig är det viktigt att "hålla stilen" när man programmerar, de svåraste fel att hitta är de "enklaste/minste".
Skriv svar