Welcome, Guest: Register On Nairaland / LOGIN! / Trending / Recent / New
Stats: 3,173,924 members, 7,890,046 topics. Date: Monday, 15 July 2024 at 08:25 AM

C Code Help: How Do I Go About This? (pointer To Pointer) - Programming - Nairaland

Nairaland Forum / Science/Technology / Programming / C Code Help: How Do I Go About This? (pointer To Pointer) (1332 Views)

Must My Array Or Pointer Allocation Have A Limit In C Or C++? / Sms Short Code Help / I Need A Java Script Date Picker Code Help (2) (3) (4)

(1) (Reply) (Go Down)

C Code Help: How Do I Go About This? (pointer To Pointer) by Nobody: 1:14pm On May 19, 2013
C gurus in the house, please help. I have multiple array of pointers which I'd like to print.

Snippet:

Char* page1[] = {"Header1","pg1menu1","pg1menu2","pg1menu3"};

Char* page2[] = {"Header2","pg2menu1","pg2menu2"};

Char* page3[] = {"Header3","pg3menu1","pg3menu2","pg3menu3"};

Char** allpages[] = {page1, page2, page3};

//I then created a function to take int x, such that the x determines the page to print:

void pagetoprnt(int x)
{
int i;

Char* receive = allpages[x]; /*that is, if x = 2, my function should call and display page3*/

for(i=0; i<=sizeof(page1); i++) /*i have used page1 in my sizeof because it's the longest.*/
{
Printf("%s", receive);
}
}

Okay that's it. There is sth wrong in this code and I knew that before compiling (I am still trying to wrapping my head around pointer to pointer).

When I took out the function and asked to print allpages, say:

for(i=0; i<=sizeof(page1); i++)
{
Printf("%s", allpages[i];
}

It prints just page3 and core dumps.
Re: C Code Help: How Do I Go About This? (pointer To Pointer) by princejude(m): 3:08pm On May 19, 2013
Which compiler are you using ?
It is also better to post a complete, compileable and simple code.
Re: C Code Help: How Do I Go About This? (pointer To Pointer) by Kobojunkie: 8:34pm On May 19, 2013
@Poster, looking carefully at your test code there


for(i=0; i<=sizeof(page1); i++)
{
Printf("%s", allpages[i];
}


What the above says is,

* Starting from index 0, to the sizeof the array defined by Char* page1[] = {"Header1","pg1menu1","pg1menu2","pg1menu3"};, which is 3, print in string format, all the entries in the array defined by Char** allpages[] = {page1, page2, page3};

* It so happens that the elements in Char** allpages[] = {page1, page2, page3}; , are addresses, and not Strings as you seem to expect there. So what you get printed out there is a list of the all the pointer addresses contained in allpages(the pointers will store the address to the first character in it's own array), after which it errors out or prints more crap since your loop there is looking for items from 0 to 3, which is beyond the bounds of the array, allpages.
Re: C Code Help: How Do I Go About This? (pointer To Pointer) by WhiZTiM(m): 10:52pm On May 19, 2013
first of all, sizeof operator returns the size of the pointer except in statically allocated array... (i.e no pointers copied and no callac, malloc, etc)!.
Check http://en.wikipedia.org/wiki/Sizeof

... You need to keep track of the array.... What you are trying to do is flawed without you having an int array to keep track of memory bounds.

Save yourself troubles and use some struct... And use them hierachically...

Struct Page
{
. . .char *elements[]
. . .int element_count
}

struct allpages
{
. . .Page *pages
. . .int page_count
}

this is what you should do!
I hope you get my point here...
(i cant type much on my small phone)

1 Like

Re: C Code Help: How Do I Go About This? (pointer To Pointer) by Nobody: 10:15am On May 20, 2013
Thanks guys!

princejude: Which compiler are you using ?
It is also better to post a complete, compileable and simple code.

I'm on Eclipse, Juno.


Kobojunkie: @Poster, looking carefully at your test code there


for(i=0; i<=sizeof(page1); i++)
{
Printf("%s", allpages[i];
}


What the above says is,

* Starting from index 0, to the sizeof the array defined by Char* page1[] = {"Header1","pg1menu1","pg1menu2","pg1menu3"};, which is 3, print in string format, all the entries in the array defined by Char** allpages[] = {page1, page2, page3};

* It so happens that the elements in Char** allpages[] = {page1, page2, page3}; , are addresses, and not Strings as you seem to expect there. So what you get printed out there is a list of the all the pointer addresses contained in allpages(the pointers will store the address to the first character in it's own array), after which it errors out or prints more crap since your loop there is looking for items from 0 to 3, which is beyond the bounds of the array, allpages.

Yes ma, I discovered that in my declaration:

Char* page1[] =
{"Header1","pg1menu1","pg1menu2","pg1
menu3"};

Char* Page1[] is an array of pointers, but the members "Header1", "pg1menu1" etc are not pointers, but strings! This makes nonsense of the rest of the code /*pardon my dull head*/

But I still don't know what to do.

WhiZTiM: first of all, sizeof operator returns the size of the pointer except in statically allocated array... (i.e no pointers copied and no callac, malloc, etc)!.
Check http://en.wikipedia.org/wiki/Sizeof

... You need to keep track of the array.... What you are trying to do is flawed without you having an int array to keep track of memory bounds.

Save yourself troubles and use some struct... And use them hierachically...

Struct Page
{
. . .char *elements[]
. . .int element_count
}

struct allpages
{
. . .Page *pages
. . .int page_count
}

this is what you should do!
I hope you get my point here...
(i cant type much on my small phone)

Yes WhiZTiM, I get your point, but please expatiate further.

Thank you everyone for your responses, In the end, it'll make sense if I get pointer to pointer once and for all!
Re: C Code Help: How Do I Go About This? (pointer To Pointer) by Nobody: 3:42pm On May 20, 2013
BTW, I have dumped my attempt to print from the pointer to pointer (postponing judgment day), instead this is how I have it now.

char h1[] ={"Header1"};
char p1m1[] ={"pg1menu1"};
char p1m2[]={"pg1menu2"};
char p1m3[] ={"pg1menu3"};
char* page1[] = {h1, p1m1, p1m2, p1m3};

char h2[] ={"Header2"};
char p2m1[] ={"pg2menu1"};
char p2m2[]={"pg2menu2"};
char p2m3[] ={"pg2menu3"};
char* page2[] = {h2, p2m1, p2m2, p2m3};

char h3[] ={"Header3"};
char p3m1[] ={"pg3menu1"};
char p3m2[]={"pg3menu2"};
char p3m3[] ={"pg3menu3"};
char* page3[] = {h3, p3m1, p3m2, p3m3};

/*i.e, i have also discarded the lofty idea of using a single for loop to print all possible pages sad */

int page1()
{
int i;
int isize= sizeof(*page1);

for(i=0 ; i <= isize ; i++)
{
Printf("%s", page1[i]);
}
return rpage1; /*the pages are going to be linked, so I need to track them*/
}

/*this is pretty elementary, so I think I'm going to go WhiZTiM's way. Please do sth bro*/
Re: C Code Help: How Do I Go About This? (pointer To Pointer) by usisky(m): 8:11pm On May 20, 2013
.
Re: C Code Help: How Do I Go About This? (pointer To Pointer) by usisky(m): 8:18pm On May 20, 2013
#define info_msg 0
#define menu_msg 1
#define msg_buff_size 2

Char *msg[msg_buff_size] = {{"msg1"},{"msg2"}};

either this:
printf("%s",*(msg+info_msg));//etc

or this for d entire array:

for(unsigned int i=0;i<msg_buff_size;i++)
{
printf("%s\n",*(msg+i));
}

try using this. Can't really say much Right now; on my mobile currently. But d above is how u address pointer array. D style above also makes ur code intelligible for d reader. Peace!!
Re: C Code Help: How Do I Go About This? (pointer To Pointer) by WhiZTiM(m): 9:08pm On May 20, 2013
This should help.... Your problem has inspired me to write a full tutorial on pointer to pointer stuff... I will post when I am done
...This is what I mean... Its more readable and maintainable on the long run


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

//Definitions
typedef struct _page_entity
{
char** elements;
int count;
} Page;

typedef struct _all_pages
{
Page* pages;
int count;
} All_Pages;

void print_page(Page* pg)
{
int i;
for(i=0; i < pg->count; i++)
printf("%s\n", pg->elements[i]);
}

void print_page_item_from_All_Pages(All_Pages* pg, int page_index, int element)
{
if((page_index >= pg->count) || (element >= pg->pages[page_index].count))
{
printf("You ID10T! that's out of bounds\n"wink;
exit(-1);
}
printf("%s\n", pg->pages[page_index].elements[element] );
}

void print_all_pages(All_Pages* pg)
{
int i;
for(i = 0; i < pg->count; i++)
print_page(&pg->pages[i]);
}

//main
int main(int argc, char* argv[])
{
char* page_1[] = { "Header1", "pg1menu1", "pg1menu2", "pg1menu3" };
char* page_2[] = { "Header2", "pg2menu1", "pg2menu2" };
char* page_3[] = { "Header4", "pg3menu1", "pg3menu3", "pg3menu3" };

Page page1, page2, page3;

page1.elements = page_1;
page1.count = 4;

page2.elements = page_2;
page2.count = 3;

page3.elements = page_3;
page3.count = 4;

Page pages[] = { page1, page2, page3 };

All_Pages allPages;
allPages.pages = pages;
allPages.count = 3;

printf("----------------\nALL PAGES\n"wink;
print_all_pages(&allPages);

printf("----------------\nPAGE 1\n"wink;
print_page(&page1);

printf("----------------\n3rd item on PAGE 3\n"wink;
print_page_item_from_All_Pages(&allPages, 2, 2);

printf("----------------\n5th item on PAGE 3\n"wink;
print_page_item_from_All_Pages(&allPages, 4, 2);

return EXIT_SUCCESS;
}

1 Like

Re: C Code Help: How Do I Go About This? (pointer To Pointer) by WhiZTiM(m): 10:35pm On May 20, 2013
My Output was:

whiztim@whiztim-Vostro-1500:~/Documents/developer/C/others/quickies/demos/ptrTOptr$ ./t.out
----------------
ALL PAGES
Header1
pg1menu1
pg1menu2
pg1menu3
Header2
pg2menu1
pg2menu2
Header4
pg3menu1
pg3menu3
pg3menu3
----------------
PAGE 1
Header1
pg1menu1
pg1menu2
pg1menu3
----------------
3rd item on PAGE 3
pg3menu3
----------------
5th item on PAGE 3
You IDIOT! thats out of bounds
Re: C Code Help: How Do I Go About This? (pointer To Pointer) by Kobojunkie: 2:04am On May 21, 2013

Char* Page1[] is an array of pointers, but the members "Header1", "pg1menu1" etc are not pointers, but strings! This makes nonsense of the rest of the code /*pardon my dull head*/

In C, a string is represented by an array of chars, and what you really are getting is a pointer to the first element in the array. i.e the definition

char CString[] ="MyString";

is really a pointer pointing to the first element in the array CString

So, if you were to try to get the third element in that array by using code such as below


char element = CString[2];

what you in fact doing is specifying an offset from the start pointer location to the element you want. In this case, since this is an array of characters, you are indicating that you want the value at the address[location pointed to by the pointer CString(i.e location 0 + 2 bytes], this translates to the location where element with index 2 or element 3 is stored in the array.

1 Like

Re: C Code Help: How Do I Go About This? (pointer To Pointer) by mkwayisi: 2:12pm On May 21, 2013
I surely know this is going to be an overkill but I just want to suggest to you a cleaner and better way to implement such thing. Note that, within the "main" function, I ignored all error checks so as not to *obnubilate* the intent of the program.

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

typedef struct _page {
char *header;
char **items;
size_t count;
} page;

typedef struct _page_box {
page **pages;
size_t count;
} page_box;

//==[ CODE ]===================================================================
// create_page_box
page_box * create_page_box(void)
{
page_box *pb;
if ((pb = malloc(sizeof(*pb))))
memset(pb, 0, sizeof(*pb));
return pb;
}

//==[ CODE ]===================================================================
// create_page
page * create_page(page_box *pb, const char *hdr)
{
if (pb != NULL) {
pb->pages = realloc(pb->pages, sizeof(*pb->pages) * (pb->count + 1));
if (pb->pages != NULL) {
pb->pages[pb->count] = malloc(sizeof(page));
if (pb->pages[pb->count] != NULL) {
memset(pb->pages[pb->count], 0, sizeof(page));
if (hdr && (pb->pages[pb->count]->header = malloc(strlen(hdr) + 1)))
strcpy(pb->pages[pb->count]->header, hdr);
pb->count++;
return pb->pages[pb->count-1];
}
}
}
return NULL;
}

//==[ CODE ]===================================================================
// add_page_item
int add_page_item(page *pg, const char *str)
{
if (pg && str) {
pg->items = realloc(pg->items, sizeof(*pg->items) * (pg->count + 1));
if (pg->items != NULL) {
pg->items[pg->count] = malloc(strlen(str) + 1);
if (pg->items[pg->count] != NULL) {
strcpy(pg->items[pg->count], str);
pg->count++;
return 1;
}
}
}
return 0;
}

//==[ CODE ]===================================================================
// free_page_box
void free_page_box(page_box *pb)
{
int i, j;
for (i = 0; i < pb->count; i++) {
for (j = 0; j < pb->pages[i]->count; j++)
free(pb->pages[i]->header);
free(pb->pages[i]);
}
free(pb);
}

//==[ CODE ]===================================================================
// main
int main()
{
page_box *pb;
page *pg;
int i, j;

// Create a container for all pages
pb = create_page_box();

// Create page 1
pg = create_page(pb, "Header 1" );
add_page_item(pg, "pg1menu1" );
add_page_item(pg, "pg1menu2" );
add_page_item(pg, "pg1menu3" );

// Create page 2
pg = create_page(pb, "Header 2" );
add_page_item(pg, "pg2menu1" );
add_page_item(pg, "pg2menu2" );

// Create page 3
pg = create_page(pb, "Header 3" );
add_page_item(pg, "pg3menu1" );
add_page_item(pg, "pg3menu2" );
add_page_item(pg, "pg3menu3" );

// Print out all the pages
for (i = 0; i < pb->count; i++) {
printf("%s\n===========\n", pb->pages[i]->header);
for (j = 0; j < pb->pages[i]->count; j++) {
printf("%d. %s\n", j + 1, pb->pages[i]->items[j]);
}
printf("\n" );
}

// Free all allocated memory
free_page_box(pb);
pb = NULL;

return 0;
}

1 Like

Re: C Code Help: How Do I Go About This? (pointer To Pointer) by usisky(m): 5:39pm On May 21, 2013
Na wa'o!! The OP simply stated he wanted to knw how to reference ARRAY OF POINTERS. which one now be "cleaner and better way"? SMH! Of course there are gazillion ways to accomplish even d most trivial of tasks...but here, d OP wanted a simple answer on array of pointers and not on STRUCTURES, or the best way to accomplish his current problem. EVERYONE can code, but how many understand what the PROBLEM is?!! Again....SMH!

1 Like

Re: C Code Help: How Do I Go About This? (pointer To Pointer) by lordZOUGA(m): 6:28pm On May 21, 2013
@usisky, you probably didn't see this part of the OP's reply.
olu_kenzo :

But I still don't know what to do.

Yes WhiZTiM, I get your point, but please expatiate further.

Thank you everyone for your responses, In the end, it'll make sense if I get pointer to pointer once and for all!

3 Likes

Re: C Code Help: How Do I Go About This? (pointer To Pointer) by Nobody: 7:04am On May 23, 2013
WhiZTiM: My Output was:

whiztim@whiztim-Vostro-1500:~/Documents/developer/C/others/quickies/demos/ptrTOptr$ ./t.out
----------------
ALL PAGES
Header1
pg1menu1
pg1menu2
pg1menu3
Header2
pg2menu1
pg2menu2
Header4
pg3menu1
pg3menu3
pg3menu3
----------------
PAGE 1
Header1
pg1menu1
pg1menu2
pg1menu3
----------------
3rd item on PAGE 3
pg3menu3
----------------
5th item on PAGE 3
You IDIOT! thats out of bounds

Wow! I'm sorry I'm late. Airtel has been grossly irresponsible around here for days.

You're a genius man. I cut head sir! I have implemented sth very similar to this and my code works now. I'm able to track the prev, current and next pages using struct pointers.

I'll put my whiztim-esque code here for the benefit of beginners --like myself-- who may (naturally) run into similar code issues in the future.

Writing code is nice, writing clean code is IT.


Kobojunkie:

In C, a string is represented by an array of chars, and what you really are getting is a pointer to the first element in the array. i.e the definition

char CString[] ="MyString";

is really a pointer pointing to the first element in the array CString

So, if you were to try to get the third element in that array by using code such as below


char element = CString[2];

what you in fact doing is specifying an offset from the start pointer location to the element you want. In this case, since this is an array of characters, you are indicating that you want the value at the address[location pointed to by the pointer CString(i.e location 0 + 2 bytes], this translates to the location where element with index 2 or element 3 is stored in the array.


Thanks. I wish you gurus would spend more time. Nairaland may just become our own Stackoverflow, really.


usisky: #define info_msg 0
#define menu_msg 1
#define msg_buff_size 2

Char *msg[msg_buff_size] = {{"msg1"},{"msg2"}};

either this:
printf("%s",*(msg+info_msg));//etc

or this for d entire array:

for(unsigned int i=0;i<msg_buff_size;i++)
{
printf("%s\n",*(msg+i));
}

try using this. Can't really say much Right now; on my mobile currently. But d above is how u address pointer array. D style above also makes ur code intelligible for d reader. Peace!!

Thanks bro!

mkwayisi: I surely know this is going to be an overkill but I just want to suggest to you a cleaner and better way to implement such thing. Note that, within the "main" function, I ignored all error checks so as not to *obnubilate* the intent of the program.

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

typedef struct _page {
char *header;
char **items;
size_t count;
} page;

typedef struct _page_box {
page **pages;
size_t count;
} page_box;

//==[ CODE ]===================================================================
// create_page_box
page_box * create_page_box(void)
{
page_box *pb;
if ((pb = malloc(sizeof(*pb))))
memset(pb, 0, sizeof(*pb));
return pb;
}

//==[ CODE ]===================================================================
// create_page
page * create_page(page_box *pb, const char *hdr)
{
if (pb != NULL) {
pb->pages = realloc(pb->pages, sizeof(*pb->pages) * (pb->count + 1));
if (pb->pages != NULL) {
pb->pages[pb->count] = malloc(sizeof(page));
if (pb->pages[pb->count] != NULL) {
memset(pb->pages[pb->count], 0, sizeof(page));
if (hdr && (pb->pages[pb->count]->header = malloc(strlen(hdr) + 1)))
strcpy(pb->pages[pb->count]->header, hdr);
pb->count++;
return pb->pages[pb->count-1];
}
}
}
return NULL;
}

//==[ CODE ]===================================================================
// add_page_item
int add_page_item(page *pg, const char *str)
{
if (pg && str) {
pg->items = realloc(pg->items, sizeof(*pg->items) * (pg->count + 1));
if (pg->items != NULL) {
pg->items[pg->count] = malloc(strlen(str) + 1);
if (pg->items[pg->count] != NULL) {
strcpy(pg->items[pg->count], str);
pg->count++;
return 1;
}
}
}
return 0;
}

//==[ CODE ]===================================================================
// free_page_box
void free_page_box(page_box *pb)
{
int i, j;
for (i = 0; i < pb->count; i++) {
for (j = 0; j < pb->pages[i]->count; j++)
free(pb->pages[i]->header);
free(pb->pages[i]);
}
free(pb);
}

//==[ CODE ]===================================================================
// main
int main()
{
page_box *pb;
page *pg;
int i, j;

// Create a container for all pages
pb = create_page_box();

// Create page 1
pg = create_page(pb, "Header 1" );
add_page_item(pg, "pg1menu1" );
add_page_item(pg, "pg1menu2" );
add_page_item(pg, "pg1menu3" );

// Create page 2
pg = create_page(pb, "Header 2" );
add_page_item(pg, "pg2menu1" );
add_page_item(pg, "pg2menu2" );

// Create page 3
pg = create_page(pb, "Header 3" );
add_page_item(pg, "pg3menu1" );
add_page_item(pg, "pg3menu2" );
add_page_item(pg, "pg3menu3" );

// Print out all the pages
for (i = 0; i < pb->count; i++) {
printf("%s\n===========\n", pb->pages[i]->header);
for (j = 0; j < pb->pages[i]->count; j++) {
printf("%d. %s\n", j + 1, pb->pages[i]->items[j]);
}
printf("\n" );
}

// Free all allocated memory
free_page_box(pb);
pb = NULL;

return 0;
}

What da Malloc! This is what I call platter of gold. I had to especially re-read and re-analyze your code because of that **pptr guy.

Thank you my good sir.


usisky: Na wa'o!! The OP simply stated he wanted to knw how to reference ARRAY OF POINTERS. which one now be "cleaner and better way"? SMH! Of course there are gazillion ways to accomplish even d most trivial of tasks...but here, d OP wanted a simple answer on array of pointers and not on STRUCTURES, or the best way to accomplish his current problem. EVERYONE can code, but how many understand what the PROBLEM is?!! Again....SMH!

No be so my broda. I wanted it both ways.

It may sound dumb, but I performed the same task some weeks back using entirely functions. You can't imagine how grotesque the code was. I wouldn't even commission that whale of a code now for 5Kobo.

My point, I have learnt a lot from everyone here and I'm willing to take more, Airtel willingly.

Thank you all!

(1) (Reply)

Apply For The Google Hash Code Programming Competition 2016 / Java Programming / Android Developer

(Go Up)

Sections: politics (1) business autos (1) jobs (1) career education (1) romance computers phones travel sports fashion health
religion celebs tv-movies music-radio literature webmasters programming techmarket

Links: (1) (2) (3) (4) (5) (6) (7) (8) (9) (10)

Nairaland - Copyright © 2005 - 2024 Oluwaseun Osewa. All rights reserved. See How To Advertise. 70
Disclaimer: Every Nairaland member is solely responsible for anything that he/she posts or uploads on Nairaland.