ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
strcmp() compares two strings, or array of chars which are null-terminated. The 'cell_phone' function parameter is declared as a pointer to a char, which presumably points to a string; a pointer to a char and a char are not the same.
I cannot comment on whether the usage of ppension->cell_phone[i] is correct or not because I have not seen how it is declared. As for the variable cell_phone, you should not be de-referencing it, for this would yield a single character. Try something like this:
Code:
if(!(strcmp(ppension->cell_phone[i], cell_phone))) /* Note that I removed the * from cell_phone */
hi
i cant understand you:
now you insert a pointer (type char*) to strcmp function...however from what i know, strcmp must recieve a char and now a char pointer?
/* pension.h - pension header file */
#ifndef _PENSION_H_
#define _PENSION_H_
/* constants' definitions */
#define MAX_DOGS 500 /* maximum number of dogs of the same type */
#define MAX_DOGS_PER_PERSON 5 /* maximum number of dogs that one person can have */
#define CELL_PHONE_LENGTH 12 /* the length of a cellphone's string including NULL in the end */
#define DATE_LENGTH 11 /* the length of a date's string including NULL in the end */
#define TYPE1_COST 70 /* cost for a male dog of type 1 */
#define TYPE2_COST 1000 /* monthly cost for a male dog of type 2 */
#define TYPE3_COST 100 /* cost per day for a male dog of type 3 */
#define FEMALE_EXTRA_COST 5 /* % of extra cost for female dogs */
#define DISCOUNT_PER_DOG 10 /* % of discount per dog for each dog when a person has multiple dogs */
/* types' definitions */
/* define your structs and their types here. */
typedef struct dogs_type1 {
int top1;
int* dog_id1;
char* dog_name1;
char* dog_gender1;
char* first_name1;
char* family_name1;
char* cell_phone1;
}type1;
typedef struct dogs_type2 {
int top2;
int* dog_id2;
char* dog_name2;
char* dog_gender2;
char* first_name2;
char* family_name2;
char* cell_phone2;
char* date2;
}type2;
typedef struct dogs_type3 {
int top3;
int* dog_id3;
char* dog_name3;
char* dog_gender3;
char* first_name3;
char* family_name3;
char* cell_phone3;
char* date3;
int* days_num3;
}type3;
typedef struct _PENSION {
type1 dogs1;
type2 dogs2;
type3 dogs3;
}PENSION;
typedef enum _BOOL {FALSE=0 , TRUE} BOOL;
/* interface functions */
PENSION* CreatePension();
BOOL AddDog(PENSION* ppension, int dog_id, char* dog_name, char dog_gender, char* first_name, char* family_name, char* cell_phone, char* date, int days_num);
BOOL RemoveDog(PENSION* ppension, int dog_id);
BOOL PrintDetails(PENSION* ppension, char* cell_phone);
void PrintBills(PENSION* ppension);
void FreePension(PENSION* ppension);
#endif /*_PENSION_H_*/
strcmp() compares two strings, not two char values. If you referenced any book or online tutorial that indicated that two chars are compared, then you should dispose of it.
As for your next query, it would seem that you are developing redundant code. If you have two or more structures that will contain the same data, then it would be wiser to define a structure that defines the common data. For example:
As for your obsessiveness with the usage of malloc(), it is definitely not required in all cases. As my example demonstrates above, it is possible to make educated guesses as to what the maximum size that a string will require. You are allocating 500 bytes for every member within a structure, which seems wasteful.
Taking the code I've shown above, here would be a typical example of its application:
Code:
struct Employee* emp = malloc(sizeof(struct Employee));
printf("Enter employee first name: ");
fgets(emp->employee.firstName, sizeof(emp->employee.firstName), stdin);
printf("Enter employee last name: ");
fgets(emp->employee.lastName, sizeof(emp->employee.lastName), stdin);
...
char* input = malloc(50);
printf("Enter employee salary: ");
fgets(input, 50, stdin);
int result = sscanf(input, "%f", &emp->salary);
if (result != 1)
{
/* error with input */
}
...
Now, if I want to compare to see if a Student is also an Employee, I could do something like:
Code:
if (strcmp(stud->student.firstName, emp->employee.firstName) == 0 &&
strcmp(stud->student.lastName, emp->employee.lastName) == 0)
{
/* names match */
}
To conclude this response, if any of the concepts above are not clear to you, I would suggest that you revisit a good tutorial. Someone on this forum recently floated this link to a supposedly good tutorial: http://beej.us/guide/bgc/output/print/bgc_A4.pdf
I have not looked at it myself, but Beej is considered a respected author for a similar tutorial for Socket/Network programming.
/* pension.h - pension header file */
#ifndef _PENSION_H_
#define _PENSION_H_
/* constants' definitions */
#define MAX_DOGS 500 /* maximum number of dogs of the same type */
#define MAX_DOGS_PER_PERSON 5 /* maximum number of dogs that one person can have */
#define CELL_PHONE_LENGTH 12 /* the length of a cellphone's string including NULL in the end */
#define DATE_LENGTH 11 /* the length of a date's string including NULL in the end */
#define TYPE1_COST 70 /* cost for a male dog of type 1 */
#define TYPE2_COST 1000 /* monthly cost for a male dog of type 2 */
#define TYPE3_COST 100 /* cost per day for a male dog of type 3 */
#define FEMALE_EXTRA_COST 5 /* % of extra cost for female dogs */
#define DISCOUNT_PER_DOG 10 /* % of discount per dog for each dog when a person has multiple dogs */
/* types' definitions */
/* define your structs and their types here. */
typedef struct dogs_type1 {
int top1;
int* dog_id1;
char* dog_name1;
char* dog_gender1;
char* first_name1;
char* family_name1;
char* cell_phone1;
}type1;
typedef struct dogs_type2 {
int top2;
int* dog_id2;
char* dog_name2;
char* dog_gender2;
char* first_name2;
char* family_name2;
char* cell_phone2;
char* date2;
}type2;
typedef struct dogs_type3 {
int top3;
int* dog_id3;
char* dog_name3;
char* dog_gender3;
char* first_name3;
char* family_name3;
char* cell_phone3;
char* date3;
int* days_num3;
}type3;
typedef struct _PENSION {
type1* dogs1;
type2* dogs2;
type3* dogs3;
}PENSION;
typedef enum _BOOL {FALSE=0 , TRUE} BOOL;
/* interface functions */
PENSION* CreatePension();
BOOL AddDog(PENSION* ppension, int dog_id, char* dog_name, char dog_gender, char* first_name, char* family_name, char* cell_phone, char* date, int days_num);
BOOL RemoveDog(PENSION* ppension, int dog_id);
BOOL PrintDetails(PENSION* ppension, char* cell_phone);
void PrintBills(PENSION* ppension);
void FreePension(PENSION* ppension);
#endif /*_PENSION_H_*/
and it continue to show me an error messagefor all the structs, this is just an example):
Code:
error: request for member `dogs1' in something not a structure or union|
i read alot of material about it over google and i didnt succssed to figure it out...can someone help me please?
There is a rule: if you have structure X then use X.member to acces its members; if you have a pointer to structure then use either (*X).member or X->member.
As dwhitney67 already said, your code looks redundant. If you want an array of structures (DOGS, whatever it means) then create an array of structures, not structure of arrays, as you seem to be trying to do.
There is a rule: if you have structure X then use X.member to acces its members; if you have a pointer to structure then use either (*X).member or X->member.
As dwhitney67 already said, your code looks redundant. If you want an array of structures (DOGS, whatever it means) then create an array of structures, not structure of arrays, as you seem to be trying to do.
You have declared kelet to be an array of 10 pointers to char.
I'm not sure why you want to set the kelet array values to a value of 66; typically one would set the values to NULL (or 0). Also, you should not be seeking exactly 10 fields from the string that was entered, but instead looking to ensure that you do not end up with a NULL field.
By the way, the input statement that you provided only contains 7 fields, not 10.
Consider this code:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
const char* delimiters = " \t\n";
char* kelet[10];
char input[255];
while (fgets(input, sizeof(input), stdin)) /* use ctrl-d to exit while loop */
{
char* token = strtok(input, delimiters);
int i = 0;
memset(kelet, 0, sizeof(kelet));
while (token && i < 10)
{
kelet[i++] = token;
token = strtok(NULL, delimiters);
}
/* verify parsing of input */
for (int j = 0; j < i; ++j)
{
printf("token %d: %s\n", j, kelet[j]);
}
}
return 0;
}
/* pension.h - pension header file */
#ifndef _PENSION_H_
#define _PENSION_H_
/* constants' definitions */
#define MAX_DOGS 500 /* maximum number of dogs of the same type */
#define MAX_DOGS_PER_PERSON 5 /* maximum number of dogs that one person can have */
#define CELL_PHONE_LENGTH 12 /* the length of a cellphone's string including NULL in the end */
#define DATE_LENGTH 11 /* the length of a date's string including NULL in the end */
#define TYPE1_COST 70 /* cost for a male dog of type 1 */
#define TYPE2_COST 1000 /* monthly cost for a male dog of type 2 */
#define TYPE3_COST 100 /* cost per day for a male dog of type 3 */
#define FEMALE_EXTRA_COST 5 /* % of extra cost for female dogs */
#define DISCOUNT_PER_DOG 10 /* % of discount per dog for each dog when a person has multiple dogs */
/* types' definitions */
/* define your structs and their types here. */
typedef struct _PENSION {
int top1;
int* dog_id1;
char* dog_name1;
char* dog_gender1;
char* first_name1;
char* family_name1;
char* cell_phone1;
int top2;
int* dog_id2;
char* dog_name2;
char* dog_gender2;
char* first_name2;
char* family_name2;
char* cell_phone2;
char* date2;
int top3;
int* dog_id3;
char* dog_name3;
char* dog_gender3;
char* first_name3;
char* family_name3;
char* cell_phone3;
char* date3;
int* days_num3;
}PENSION;
typedef enum _BOOL {FALSE=0 , TRUE} BOOL;
/* interface functions */
PENSION* CreatePension();
BOOL AddDog(PENSION* ppension, int dog_id, char* dog_name, char dog_gender, char* first_name, char* family_name, char* cell_phone, char* date, int days_num);
BOOL RemoveDog(PENSION* ppension, int dog_id);
BOOL PrintDetails(PENSION* ppension, char* cell_phone);
void PrintBills(PENSION* ppension);
void FreePension(PENSION* ppension);
#endif /*_PENSION_H_*/
This line of code, and the ones similar to it, has a bug:
Code:
ppension->dog_id1[ppension->top1]=dog_id;
It is ppension that is an array of pension structures; the dog_id1 is a mere pointer to a char, which presumably will point to a string of characters that are null terminated.
You need to reference the appropriate pension structure using something like, if indeed top1 is an index value to the array:
Code:
ppension[ppension->top1]->dog_id1 = <str ptr>
Let me explain why I used <str ptr> above; in your main() function you are obtaining individual string tokens using strtok(), however these are mere pieces of the array "input", which appears that you will be using over an over again. This will affect your data, with perhaps only the last entry being added to ppension being valid.
You are going to a) have to allocate duplicates of your strings (e.g. using strdup()), or b) declare your structure members (e.g. dog_id1) as an array of characters and not a pointer to characters. I advised you on option b earlier, but I presume you did not comprehend this advice. For option b), usage of strncpy() would be required.
If you have a book/tutorial, go back to read about strings, about copying strings, and then about pointers.
P.S. This could be simplified; you have 3 of the same variable... why is that?
I really suspect that you are getting confused between the difference between array and a pointer to an array (or other type). The following is legal code:
Code:
char array[50]; /* here, 50 contiguous bytes are reserved on the stack. */
char* ptr = array; /* here, we setup a pointer to the first element of the array. */
char* ptr2 = &array[0]; /* this has the same effect as the statement above. */
More examples:
Code:
/* This is a mere definition of a structure; no memory is allocated for this structure at this time. */
struct Foo
{
char name[50];
};
...
struct Foo myFoo; /* here, space of the size of struct Foo is reserved on the stack. */
struct Foo* ptr = &myFoo; /* here, a pointer is assigned to reference the location in memory for myFoo */
struct Foo* ptr2 = malloc(sizeof(struct Foo)); /* here, memory is allocated on the heap (not the stack!) */
Continuing, a string can be allocated, and accessed if it were an array:
Code:
char* str = malloc(50); /* allocate 50 bytes on the heap */
str[0] = 'T';
str[1] = 'h';
str[2] = 'e';
str[3] = ' ';
str[4] = 'E';
str[5] = 'n';
str[6] = 'd';
str[7] = '\0'; /* strings requires a terminating null character */
/* or */
strncpy(str, "The End", 50); /* an easier way to initialize an array with a string */
/* bad assignment */
str = "The End"; /* this is legal, however now you have a memory leak because */
/* free() was not called to complement the malloc() used previously. */
As I have suggested previously, re-read your book/tutorial on these basic concepts. There's no need for you to continue with your programming assignment until you have fully understood the concepts discussed above.
#define DATE_LENGTH 11 /* the length of a date's string including NULL in the end */
#define TYPE1_COST 70 /* cost for a male dog of type 1 */
#define TYPE2_COST 1000 /* monthly cost for a male dog of type 2 */
#define TYPE3_COST 100 /* cost per day for a male dog of type 3 */
#define FEMALE_EXTRA_COST 5 /* % of extra cost for female dogs */
#define DISCOUNT_PER_DOG 10 /* % of discount per dog for each dog when a person has multiple dogs */
/* types' definitions */
/* define your structs and their types here. */
typedef struct _PENSION {
int top1;
int dog_id1[MAX_DOGS];
char* dog_name1[MAX_DOGS];
char *dog_gender1[MAX_DOGS];
char* first_name1[MAX_DOGS];
char* family_name1[MAX_DOGS];
char* cell_phone1[MAX_DOGS];
}PENSION;
typedef enum _BOOL {FALSE=0 , TRUE} BOOL;
PENSION* CreatePension();
BOOL AddDog(PENSION* ppension, int dog_id, char* dog_name, char dog_gender, char* first_name, char* family_name, char* cell_phone, char* date, int days_num);
BOOL RemoveDog(PENSION* ppension, int dog_id);
BOOL PrintDetails(PENSION* ppension, char* cell_phone);
void PrintBills(PENSION* ppension);
void FreePension(PENSION* ppension);
#endif /*_PENSION_H_*/
My gut instinct would be to define your structure like this:
Code:
#ifndef PENSION_H
#define PENSION_H
typedef enum { MALE, FEMALE } Gender;
typedef struct
{
int dog_id;
char dog_name[50]; /* a dog name can be no more than 50 chars long */
Gender dog_gender;
char owner_first_name[50]; /* a first name can be no more than 50 chars long */
char owner_family_name[50]; /* same here */
char owner_cell_phone[15]; /* a cell phone number can be no more than 15 chars */
} Pension;
#endif
Then, in a separate header file/source file (perhaps PensionManager.h), define something that will manage the array of Pension structure objects that you require. For example:
Code:
#ifndef PENSION_MANAGER_H
#define PENSION_MANAGER_H
#include "Pension.h"
#define MAX_DOGS 500
Pension* thePensions; /* used to reference the array of Pension objects */
int numPensions;
void initPensions();
void addPension(/* insert function param attributes here */);
void removePension(/* insert function param attributes here */);
void etc(/* insert function param attributes here */);
#endif
PensionManager.c:
Code:
#include "PensionManager.h"
#include <stdlib.h>
#include <string.h>
void initPensions()
{
thePensions = malloc(MAX_DOGS * sizeof(Pension));
numPensions = 0;
}
void addPension(..., const char* dogName, ...)
{
strncpy(thePensions[numPensions].dog_name, dogName, sizeof(thePensions[numPensions].dog_name) - 1);
...
++numPensions; /* increment the number of Pensions that we are now managing */
}
...
Is this clearer now?
Last edited by dwhitney67; 04-24-2012 at 08:45 AM.
My gut instinct would be to define your structure like this:
Code:
#ifndef PENSION_H
#define PENSION_H
typedef enum { MALE, FEMALE } Gender;
typedef struct
{
int dog_id;
char dog_name[50]; /* a dog name can be no more than 50 chars long */
Gender dog_gender;
char owner_first_name[50]; /* a first name can be no more than 50 chars long */
char owner_family_name[50]; /* same here */
char owner_cell_phone[15]; /* a cell phone number can be no more than 15 chars */
} Pension;
#endif
Then, in a separate header file/source file (perhaps PensionManager.h), define something that will manage the array of Pension structure objects that you require. For example:
Code:
#ifndef PENSION_MANAGER_H
#define PENSION_MANAGER_H
#include "Pension.h"
#define MAX_DOGS 500
Pension* thePensions; /* used to reference the array of Pension objects */
int numPensions;
void initPensions();
void addPension(/* insert function param attributes here */);
void removePension(/* insert function param attributes here */);
void etc(/* insert function param attributes here */);
#endif
PensionManager.c:
Code:
#include "PensionManager.h"
#include <stdlib.h>
#include <string.h>
void initPensions()
{
thePensions = malloc(MAX_DOGS * sizeof(Pension));
numPensions = 0;
}
void addPension(..., const char* dogName, ...)
{
strncpy(thePensions[numPensions].dog_name, dogName, sizeof(thePensions[numPensions].dog_name) - 1);
...
++numPensions; /* increment the number of Pensions that we are now managing */
}
...
Is this clearer now?
hi
thanks alot for your help, i really appreciate it..i hope after my first program i will know how to help others too
I understand you and try to implement it...i hope i will no have problem with it
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.