LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 11-11-2003, 01:38 PM   #1
alitrix
Member
 
Registered: Jun 2003
Location: Netherlands, The
Distribution: Ubuntu, Kernel 2.6.7
Posts: 169

Rep: Reputation: 30
Unhappy Nested structures :S?


Hi,

I'm trying to code a simpel IRC bot (just for fun, so I can learn how to use strings/arrays in C).

I have this at the moment in my header:

Code:
struct STRUCT_AUTH {
	char nick[20];
	char authname[20];
} auths[MAXUSERS];

struct STRUCT_TRUSTED {
	char authname[20];
} trusts[MAXUSERS];
I understand that. When I want to add somebedy to the auth-structure, I just do:
auths[lastauth].nick=nickname and auths[lastauth++].authname =authname.

Oke, all that works. Perfect.
Now my problem, I want to make something like that, except a nested structure (if I call that correct)

Some people helped me and I understood something like this:
Code:
struct user {
  char nick[20]; /* User nick that is on channel x */
};

struct channel {
 char channame[40]; /* Channel name */
 int activeusers; /* How many users are on the chan? */
 struct user *user_list;
};
Oke, now my problem. How to declare this in my source (.c) file?
Some people gave me some malloc() examples, except they didn't work.

I want to be able to do something like this:
/* Here the malloc() thing and make a pointer c and a linkg c->user_list */
c->channame[x] = channel, c->activeusers=8
c->user_list[i]->nick=nick1, c->user_list[i]->nick=nick2, c->user_list[i]->nick=nick3, etc...

c->channame[x++] = channel, c->activeusers+=4
c->user_list[i]->nick=nick1, c->user_list[i]->nick=nick2,etc...

(Btw, I want multi-channeling as well, as you see)

Greetz,
AliTriX

Please, if you give me URL's wher they explain these stuff, give me a "good" url that explains something like that and not how to make arrays that tell you the x-y stuff (graphics, I don't understand a shit of that subject anyway)

Last edited by alitrix; 11-11-2003 at 01:45 PM.
 
Old 11-11-2003, 02:03 PM   #2
Mara
Moderator
 
Registered: Feb 2002
Location: Grenoble
Distribution: Debian
Posts: 9,696

Rep: Reputation: 232Reputation: 232Reputation: 232
There's something wrong with the structure you use. If I see it correctly, you use one table (channame) to keep different channel names (only offset is different). I think it should be something like this:
Code:
struct user {
    char nick[20]; /* User nick that is on channel x */
    struct user *next; /* pointer for next user */
};

struct channel {
    char channame[40]; /* Channel name */
    int activeusers; /* How many users are on the chan? */
    struct user *user_list;
};

struct channel channels[40];
And then
Code:
struct user *userptr; /* pointer for user */
channels[0].channame = something; /* channel name */
channels[0].activeusers=8;
channels[0].user_list=malloc(sizeof(struct user)); /* memory allocated for 'user' structure
channels[0].user_list->nick=nick1; /* filling name */
channels[0].user_list->next=NULL; /* null means there's nothing */
userptr=channels[0].user_list; /* now the pointer is channels[0].userlist (which points to 
memory allocated by malloc) */
userptr->next=malloc(sizeof(struct user)); /* malloc assigns memory for user struct, it's 
channel[0].user_list->next */
userptr=userptr->next; /*userptr becomes channel[0].user_list->next */
userpty->nick=nick2; /* filling new user structure */
userptr->next=NULL;
Your code can be also written without mallocs, using only tables. Byt there's one big BUT: it needs specified maximum number of users. If you set the maximum to 100, the program will use alwys memory for 100 users, even when there's only one user. It's not very bad for 100 users, but imagine 500 channels with 100 users each.

The code above doesn't have this problem.
 
Old 11-11-2003, 02:45 PM   #3
alitrix
Member
 
Registered: Jun 2003
Location: Netherlands, The
Distribution: Ubuntu, Kernel 2.6.7
Posts: 169

Original Poster
Rep: Reputation: 30
Hm...

I tryed to edit to change a little stuff, but there are several lines I get warnings/errors from and my compiler didn't make a binary from, cause the erros.
The code that I have:
Code:
#include <stdio.h>
#include <string.h>

struct user {
    char nick[20]; /* User nick that is on channel x */
    struct user *next; /* pointer for next user */
};

struct channel {
    char channame[40]; /* Channel name */
    int activeusers; /* How many users are on the chan? */
    struct user *user_list;
};

struct channel channels[40];

int main() {
	char channel[]="#test";
	char nick1[]="AliTriX";
	char nick2[]="AliTriX2";
	struct user *userptr; /* pointer for user */
	channels[0].channame = channel; /* channel name */
	channels[0].activeusers=8;
	channels[0].user_list=malloc(sizeof(struct user)); /* memory allocated for 'user' structure */
	channels[0].user_list->nick=nick1; /* filling name */
	channels[0].user_list->next=NULL; /* null means there's nothing */
	userptr=channels[0].user_list; /* now the pointer is channels[0].userlist (which points to 
	memory allocated by malloc) */
	userptr->next=malloc(sizeof(struct user)); /* malloc assigns memory for user struct, it's 
	channel[0].user_list->next */
	userptr=userptr->next; /*userptr becomes channel[0].user_list->next */
	userptr->nick=nick2; /* filling new user structure */
	userptr->next=NULL;

}

Errors:
dbzgt@AliTriX:~/c-test/trixy/tests$ gcc test.c -o test
test.c: In function `main':
test.c:22: incompatible types in assignment
test.c:24: warning: assignment makes pointer from integer without a cast
test.c:25: incompatible types in assignment
test.c:29: warning: assignment makes pointer from integer without a cast
test.c:32: incompatible types in assignment

(Line numbering is exactlly the same as it's pasted here)
 
Old 11-11-2003, 03:33 PM   #4
Mara
Moderator
 
Registered: Feb 2002
Location: Grenoble
Distribution: Debian
Posts: 9,696

Rep: Reputation: 232Reputation: 232Reputation: 232
Yes, I made a mistake. For copying strings, you can't use =. You need strcpy function. I also added casting - '(struct user *)malloc'. It tells that the result of malloc (free memory, without structure) should be threated as user structure.
Here's the code after corrections.
Code:
#include <stdio.h>
#include <string.h>

struct user {
    char nick[20]; /* User nick that is on channel x */
    struct user *next; /* pointer for next user */
};

struct channel {
    char channame[40]; /* Channel name */
    int activeusers; /* How many users are on the chan? */
    struct user *user_list;
};

struct channel channels[40];

int main() {
	char channel[]="#test";
	char nick1[]="AliTriX";
	char nick2[]="AliTriX2";
	struct user *userptr; /* pointer for user */
	/*channels[0].channame = "#test1";  channel name */
	strcpy(channels[0].channame,channel);
	channels[0].activeusers=8;
	channels[0].user_list=(struct user *)malloc(sizeof(struct user)); /* memory allocated for 'user' structure */
	/*channels[0].user_list->nick=nick1;  filling name */
	strcpy(channels[0].user_list->nick,nick1);
	channels[0].user_list->next=NULL; /* null means there's nothing */
	userptr=channels[0].user_list; /* now the pointer is channels[0].userlist (which points to
	memory allocated by malloc) */
	userptr->next=(struct user *)malloc(sizeof(struct user)); /* malloc assigns memory for user struct, it's
	channel[0].user_list->next */
	userptr=userptr->next; /*userptr becomes channel[0].user_list->next */
	/*userptr->nick=nick2;  filling new user structure */
	strcpy(userptr->nick,nick2);
	userptr->next=NULL;
	printf("0: %s 1: %s\n",
		channels[0].user_list->nick,
		channels[0].user_list->next->nick);
}
 
Old 11-11-2003, 04:21 PM   #5
alitrix
Member
 
Registered: Jun 2003
Location: Netherlands, The
Distribution: Ubuntu, Kernel 2.6.7
Posts: 169

Original Poster
Rep: Reputation: 30
K, tnx Mara, it all works.

Let say, I want to add a lot of users, and want to make a loop.
What part of that malloc do I have to put in the loop?

And how to read all the users in from a channel?

(I hope I'm not irritating you with these questions)
 
Old 11-13-2003, 04:17 PM   #6
Mara
Moderator
 
Registered: Feb 2002
Location: Grenoble
Distribution: Debian
Posts: 9,696

Rep: Reputation: 232Reputation: 232Reputation: 232
Well, you can use two ways to add users. At the beginning of the list or at the end. First option is simplier:
Code:
struct user *newuser;
while(something) {
    newuser=(struct user *)malloc(sizeof(struct user)); /* memory allocated for 'user' structure */
    strcpy(newuser,"Nick");
    newuser->next=channel[0].user_list;
    channels[0].user_list=newuser; /* null means there's nothing */
};
Of course you need to make it use parameters insted of name and channel number.

The code to list them all:
Code:
struct user *usr=channel[0].user_list;
while(usr!=NULL) {
    printf("%c\n",usr->nick);
    usr=usr->next;
}
Inserting at the end of list requires you to keep pointer to the last user or loop through the list (not effective).
 
Old 11-13-2003, 04:19 PM   #7
alitrix
Member
 
Registered: Jun 2003
Location: Netherlands, The
Distribution: Ubuntu, Kernel 2.6.7
Posts: 169

Original Poster
Rep: Reputation: 30
Thanks!
/me hugs Mara
 
Old 11-13-2003, 04:25 PM   #8
Mara
Moderator
 
Registered: Feb 2002
Location: Grenoble
Distribution: Debian
Posts: 9,696

Rep: Reputation: 232Reputation: 232Reputation: 232
Good luck writing your program, alitrix.
 
Old 11-13-2003, 04:26 PM   #9
alitrix
Member
 
Registered: Jun 2003
Location: Netherlands, The
Distribution: Ubuntu, Kernel 2.6.7
Posts: 169

Original Poster
Rep: Reputation: 30
Tnx again.
I hope it will work fine all of it

And if it doesn't, I just state my questions here ... If not bothering :P
 
Old 11-13-2003, 05:58 PM   #10
alitrix
Member
 
Registered: Jun 2003
Location: Netherlands, The
Distribution: Ubuntu, Kernel 2.6.7
Posts: 169

Original Poster
Rep: Reputation: 30
Sorry, but I just have 1 question.

I want to change that structure as well, so it can take more users then MAXUSERS defines.

I was trying to use with *next as well, but couldn't really figure out.

Code:
struct auths {
        char nick[20];
        char authname[20];
	struct auths *next;
};
I stopped until there.. then I was thinking of you add script, but I couldn't figure out more then this:
Code:
	struct auths *newuser;
	newuser=(struct auths *)malloc(sizeof(struct auths)); /* memory allocated for 'user' structure */
	strcpy(newuser,"Nick1");
	newuser->next=auths;
	channels[0].user_list=newuser; /* null means there's nothing */
(I don't know what I have to do with that last line)
 
Old 11-15-2003, 05:35 PM   #11
Mara
Moderator
 
Registered: Feb 2002
Location: Grenoble
Distribution: Debian
Posts: 9,696

Rep: Reputation: 232Reputation: 232Reputation: 232
The code is nearly OK.
What I propose
Code:
        struct auths *newuser;
	newuser=(struct auths *)malloc(sizeof(struct auths)); /* memory allocated for 'user' structure */
	strcpy(newuser,"Nick1");
//don't know what's authname is, probably login or something like that
//you should fill it here
	newuser->next=channels[0].user_list;
	channels[0].user_list=newuser;
I forgot about one thng - the variable you have the name of users in. It's a good idea to have it. The code will be simple - just increase it after adding user.
 
Old 11-15-2003, 08:13 PM   #12
alitrix
Member
 
Registered: Jun 2003
Location: Netherlands, The
Distribution: Ubuntu, Kernel 2.6.7
Posts: 169

Original Poster
Rep: Reputation: 30
Thanks for you reply
But I forgot to tell you that I've got it already and I know understand a little bit more about linked structures and nested structures.

I'm making big structures now, tnx for helping me with everything!
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Starting a nested X (or something like that :-D) oribd Linux - Newbie 2 10-21-2005 08:33 AM
nested groups for linux? plunger Linux - Newbie 4 09-28-2005 08:19 AM
C++ nested classes enemorales Programming 5 05-23-2005 04:40 PM
Shorewall nested zones JohnLocke Linux - Security 0 06-30-2004 01:24 AM
The GIMP and nested windows. Hal Linux - Software 7 12-13-2003 05:27 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 07:27 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration