I am trying to make all the names in the Struct lowercase so that I can compare them and remove them.
int removeNameCard(NameCard *idCard, int *size){
char name[80];
char *ptr;
char rubbish;
int a = 0, c = 0;
printf("removeNameCard():\n");
printf("Enter personName:\n");
scanf("%c", &rubbish); // Why is there a '\n' char here??
fgets(name, 80, stdin);
if((ptr = strchr(name, '\n'))){
*ptr = '\0';
}
if((*size) == 0){
printf("The name card holder is empty\n");
return 0;
}
// Convert everything to Lower Case first
while(name[a]){
name[a] = tolower(name[a]);
a = 1;
}
printf("tolower(): %s", name);
for(int b = 0; b < *size; b = 1){
// Why is this Dot Notation when I passed in a pointer to the Struct?
while (idCard[b].personName)[c]){
(idCard[b].personName)[c] = tolower((idCard[b].personName)[c]);
c = 1;
}
}
for(int i = 0; i < *size; i = 1){
if((idCard[i].personName) == name){
printf("%d. This is from Holder: %s, This is from User: %s", i,(idCard[i].personName),name);
printf("The name card is removed\n");
printf("nameCardID: %d\n", idCard[i].nameCardID);
printf("personName: %s\n", idCard[i].personName);
printf("companyName: %s\n", idCard[i].companyName);
int k = 0;
do{
idCard[i k].nameCardID = idCard[i k 1].nameCardID;
strcpy((idCard[i k].personName),(idCard[i k 1].personName));
strcpy((idCard[i k].companyName),(idCard[i k 1].companyName));
}while((i k 1) != (*size 1));
}
}
return 0;
}
However, I am rather confused why the Compiler asked me to use Dot Notation instead of Pointer Notation as I thought I passed in the address of the Struct into *idCard so it should be a pointer if I am not wrong?
And am I wrong for trying to access each individual character in every name of the Struct like this?: (idCard[b].personName)[c]
Thank you
CodePudding user response:
However, I am rather confused why the Compiler asked me to use Dot Notation instead of Pointer Notation…
idCard[i]
is a structure, not a pointer to a structure, so its members are accessed as idCard[i].member
, not idCard[i]->member
.
idCard[i]
is a structure because whenever x
is a pointer, x[i]
is one of the objects that x
points to. It is not the address of the object. You could calculate the address of the object with x i
, and then you could reference the object with *(x i)
. And x[i]
is actually defined in this way; x[i]
is defined to be *(x i)
. (In case of expressions generally, E1[E2]
is defined to be (*((E1) (E2)))
.)
And am I wrong for trying to access each individual character in every name of the Struct like this?: (idCard[b].personName)[c]
This will work, but the parentheses are unnecessary. You can use idCard[b].personName[c]
. Due to the C grammar, it is already grouped as (idCard[b].personName)[c]
.
CodePudding user response:
However, I am rather confused why the Compiler asked me to use Dot Notation instead of Pointer Notation as I thought I passed in the address of the Struct into *idCard so it should be a pointer if I am not wrong?
Arrays are mostly just pointers to the first element in the array (except that the compiler may be aware of the array size).
Because arrays are mostly just pointers; for arrays of integers myInt = myIntArray[x];
is like myInt = *(myIntArray x);
- the pointer dereferencing is implied by array indexing. Note that to access a char
in the middle of an int
in an array, you could (not portably) use something like myChar = *((char *)(myIntArray x)) offset_of_char_in_int);
; and this is a little bit like accessing a field inside an array of structures (in that they're both accessing something smaller within an array of larger things).
For arrays of structures; indexing the array causes dereferencing (just like it does for the array of integers); so myIDcardStruct = idCard[i];
is like myIDcardStruct = *(idcard i);
. Because array indexing has implied dereferencing, myIDcardStruct
is not a pointer.
The ->
operator is like adding the offset of the requested structure's field to the address, casting the address to the requested field's type, and then dereferencing. In other words myInt = myStructPointer->myIntField;
is like myInt = (*myStructPointer).myIntField;
which is like tempAddress = (void *)myStructPointer offset_of_myIntField; myInt = *((int *)tempAddress);
.
What this means is that if you have an array of structures (which is mostly a pointer to the first structure in the array), indexing the array causes the pointer to be implicitly dereferenced, and using ->
also causes implicit dereferencing; and if you do both then you've (implicitly) dereferenced a pointer twice, which is too much dereferencing (because it's not a pointer to a pointer to a structure, or an array of pointers to structures). Because you only want it dereferenced once you have to choose between one implicit deference (array indexing) or the other implicit dereference (->
); e.g. you can choose between myInt = idCard[i].nameCardID;
or myInt = (idCard i)->nameCardID;
.
Of course the important thing is making code easy to read, and myInt = idCard[i].nameCardID;
is easier to read than myInt = (idCard i)->nameCardID;
.