[C] strlen() bij multidimensional arrays

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Maarten Kroon
  • Registratie: Maart 2006
  • Laatst online: 04-04 16:53
Oke poging twee, ik hoop niet dat dit topic ook direct gesloten wordt. Ik zal het probleem iets beter proberen uit te leggen.

Ik ben een klein spelletje aan het maken in C, nu leek het mij grappig om dat met ASCII tekens te doen ipv. pixels.

Ik heb tot zover een 2-dimensional array bestaande uit spaties met daar omheen een rand van '#' tekens. Mijn enige probleem is, ik kan voor de loopjes om bijvoorbeeld de array's mee te vullen geen strlen(array) gebruiken, kan iemand mij op de goede weg helpen? Alvast bedankt.

Hierbij de code, verdere uitleg volgt na de code.

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <stdio.h>
#include <string.h>

void draw_border(char (*)[21]);

int main(void)
{
    char level[21][21];
    draw_border(level);
    
    int i;
    for(i = 0; i < 20; i++)
    {
        printf("%s\n", level[i]);
    }
    
    system("pause");
    return 0;
}

void draw_border(char (*level)[21])
{
    int i, j;
    for(i = 0; i < 20; i++)
    {
        for(j = 0; j < 20; j++)
        {
            if(i == 0 || i == 19 || j == 0 || j == 19) 
            {
                level[i][j] = '#';
            }
            else
            {
                level[i][j] = ' ';
            }            
        }
        level[i][20] = '\0';
    }   
}


Zoals jullie kunnen zien gebruik ik in zowel de main als de draw_border functie een aantal loopjes om de array te printen dan wel te vullen zie.

In de main:
code:
1
2
3
4
    for(i = 0; i < 20; i++)
    {
        printf("%s\n", level[i]);
    }


in de draw_border functie:
code:
1
2
3
4
5
    for(i = 0; i < 20; i++)
    {
        for(j = 0; j < 20; j++)
        {
            if(i == 0 || i == 19 || j == 0 || j == 19)


De stukjes: "i < 20", "j < 20", "i == 19" en "j == 19" wil ik graag vervangen door iets als strlen(level) zodat ik gemakkelijk het formaat van de array kan aanpassen zonder overal in de code alle for loops hoef te veranderen.

Resultaat van de code ziet er trouwens als volgt uit:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
####################
#                  #
#                  #
#                  #
#                  #
#                  #
#                  #
#                  #
#                  #
#                  #
#                  #
#                  #
#                  #
#                  #
#                  #
#                  #
#                  #
#                  #
#                  #
####################

[ Voor 0% gewijzigd door BtM909 op 18-07-2011 01:23 ]


Acties:
  • 0 Henk 'm!

  • Koppensneller
  • Registratie: April 2002
  • Laatst online: 17:48

Koppensneller

winterrrrrr


Acties:
  • 0 Henk 'm!

  • Styxxy
  • Registratie: Augustus 2009
  • Laatst online: 19:45
"sizeof(array) / size(typearray)" is inderdaad een veel voorkomende methode.

PS: overal getallen gebruiken... Misschien eens een constante overwegen?

Acties:
  • 0 Henk 'm!

  • Boudewijn
  • Registratie: Februari 2004
  • Niet online

Boudewijn

omdat het kan

Ik ruik een magic numbers smell ja.

i3 + moederbord + geheugen kopen?


Acties:
  • 0 Henk 'm!

  • CyBeR
  • Registratie: September 2001
  • Niet online

CyBeR

💩

Dat kun je op twee manieren doen die veel beter zijn dan strlen():

• met een #define, als je niet van plan bent die grootte ooit runtime aan te passen, of
• met een variabele, als je dat wel bent.

All my posts are provided as-is. They come with NO WARRANTY at all.


Acties:
  • 0 Henk 'm!

  • Maarten Kroon
  • Registratie: Maart 2006
  • Laatst online: 04-04 16:53
Bedankt voor de reacties, ik heb even wat aanpassingen gemaakt namelijk #define gebruikt ipv. magic numbers of strlen. Ziet dit er wel net uit?

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#define LEVELWIDTH 20
#define LEVELLENGTH 20

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

void draw_border(char (*)[LEVELLENGTH + 1]);

int main(void)
{
    char level[LEVELWIDTH + 1][LEVELLENGTH + 1];
    draw_border(level);
    
    int i;
    for(i = 0; i < LEVELLENGTH; i++)
    {
        printf("%s\n", level[i]);
    }
    
    system("pause");
    return 0;
}

void draw_border(char (*level)[LEVELLENGTH + 1])
{
    int x, y;
    for(x = 0; x < LEVELWIDTH; x++)
    {
        for(y = 0; y < LEVELLENGTH; y++)
        {
            if(x == 0 || x == (LEVELWIDTH - 1) || y == 0 || y == (LEVELLENGTH - 1)) 
            {
                level[x][y] = '#';
            }
            else
            {
                level[x][y] = ' ';
            }            
        }
        level[x][LEVELLENGTH] = '\0';
    }   
}

Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 18:51
Dat is al beter. Je kunt ook overwegen om voor je 2-dimensionale map een apart type te introduceren:

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#define LEVELWIDTH 20
#define LEVELHEIGHT 20
typedef char level_t[LEVELHEIGHT][LEVELWIDTH+1];

void draw_border(level_t level)
{
    /* code hier */
}

int main()
{
    level_t level;
    draw_border(level);
    /* meer code hier */
    return 0;
}


Denk ook even goed na over de grootte en de betekenis die je aan de dimensies toekent. Als je elke regel als een zero-terminated string wil representeren moet de laatste dimensie extra ruimte hebben (LEVELWIDTH+1 in mijn code) en dat is dus de dimensie die je doorgaans voor de x-coördinaat gebruikt.

Jij lijkt het andersom te willen doen in draw_border() (de x-coördinaat als eerste dimensie en de y-coördinaat als tweede) maar dat is onlogisch (tenminste, onder de aanname dat de x-as horizontaal loopt en de y-as verticaal) en bovendien inconsistent met de lus op regel 15: daar indexeer je de eerste dimensie met waarden van 0..LEVELLENGTH-1 maar de eerste dimensie van de array heeft grootte LEVELWIDTH+1. Nu zijn LEVELWIDTH en LEVELLENGTH in jouw code toevallig gelijk, maar dat is niet vanzelfsprekend.

Trouwens, als je C-code wil posten, gebruik dan bij voorkeur [code=c][/code] tags, dan voegt het forum automatisch mooie syntax highlighting toe. ;)
CyBeR schreef op maandag 18 juli 2011 @ 03:28:
Dat kun je op twee manieren doen die veel beter zijn dan strlen():
[..]
• met een variabele, als je dat wel bent.
Als je dimensies variabel zijn kun je geen pure 2-dimensionale array gebruiken, dus dat lijkt me in dit geval niet echt een optie. Dan zul je een andere datarepresentatie moeten kiezen.

Acties:
  • 0 Henk 'm!

  • Maarten Kroon
  • Registratie: Maart 2006
  • Laatst online: 04-04 16:53
Ja daar was ik net ook achter gekomen toen ik de grootte van een van de arrays wilde aanpassen :D.

Acties:
  • 0 Henk 'm!

  • CyBeR
  • Registratie: September 2001
  • Niet online

CyBeR

💩

Soultaker schreef op maandag 18 juli 2011 @ 15:56:
Als je dimensies variabel zijn kun je geen pure 2-dimensionale array gebruiken, dus dat lijkt me in dit geval niet echt een optie. Dan zul je een andere datarepresentatie moeten kiezen.
Jawel, maar je moet 'm bij verandering wel even opnieuw allocen idd.

All my posts are provided as-is. They come with NO WARRANTY at all.


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 18:51
Ik bedoel vooral dat als de breedte variabel is je er geen statisch type aan kunt toekennen.

In C99 kun je nog een heel eind komen met variable length arrays, maar dat is enigzins beperkend omdat je dan altijd de dimensies mee moet passen, en niet interoperable met C++ (of eerdere versies van C).

Acties:
  • 0 Henk 'm!

  • CyBeR
  • Registratie: September 2001
  • Niet online

CyBeR

💩

Soultaker schreef op dinsdag 19 juli 2011 @ 01:11:
Ik bedoel vooral dat als de breedte variabel is je er geen statisch type aan kunt toekennen.

In C99 kun je nog een heel eind komen met variable length arrays, maar dat is enigzins beperkend omdat je dan altijd de dimensies mee moet passen, en niet interoperable met C++ (of eerdere versies van C).
Oh, maar dat hoeft ook niet.

char *array = malloc(x*y) werkt prima hoor.

Daarmee bedoel ik te zeggen: het ding hoeft helemaal niet multidimensionaal te zijn.

[ Voor 9% gewijzigd door CyBeR op 19-07-2011 01:17 ]

All my posts are provided as-is. They come with NO WARRANTY at all.


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 18:51
Nee, inderdaad, maar dat bedoelde ik met "een andere datarepresentatie kiezen". ;) (Een andere optie is om een array-van-arrays te maken; kost iets meer geheugen maar is makkelijk te indiceren.)
Pagina: 1