I am in the process of writing a simple program for Linux. I have a problem with one function "addonlyonce". It compares strings and adds to an array without duplicates (If the string does not exist in an array). The function works well, but not for utmp struct. When comparing each string of the utmp structure always returns 1 (it means that string already exists in the array - and it is wrong :( ). You can compile this code by gcc thiscode.c -o test
(it works only on Linux).
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <utmp.h>
int addonlyonce(char **array, char *str) {
int i=0;
printf("I got %s\n",str);
while(*array != '\0') {
if(strcmp(*array,str)==0) {
printf("Already exists!\n");
return 1;
}
i++;
array++;
}
*array=str;
printf("Sit down on the number: %d\n",i);
return 0;
}
void printarray(char **array) {
printf("Array looks like: ");
while(*array != '\0') {
printf("%s ",*array);
array++;
}
printf("\n");
}
int main(void) {
char *users[20]={0};
char exuser2[]="exuser2";
struct utmp current_record;
FILE *fp = fopen(UTMP_FILE, "r");
addonlyonce(users,"exuser1");
printarray(users);
addonlyonce(users,exuser2);
printarray(users);
addonlyonce(users,"exuser1");
printarray(users);
addonlyonce(users,"exuser3");
printarray(users);
while (fread(¤t_record, sizeof(struct utmp), 1, fp) == 1) {
addonlyonce(users,current_record.ut_name); //HERE DON'T WORK
printarray(users);
}
addonlyonce(users,"exuser4");
printarray(users);
fclose(fp);
return 0;
}
I wanted to make it so (correct functioning):
I got exuser1
Sit down on the number: 0
Array looks like: exuser1
I got exuser2
Sit down on the number: 1
Array looks like: exuser1 exuser2
I got exuser1
Already exists!
Array looks like: exuser1 exuser2
I got exuser3
Sit down on the number: 2
Array looks like: exuser1 exuser2 exuser3
I got reboot
Sit down on the number: 3
Array looks like: exuser1 exuser2 exuser3 reboot
I got kelloco2
Sit down on the number: 4
Array looks like: exuser1 exuser2 exuser3 reboot kelloco2
I got przemek
Sit down on the number: 5
Array looks like: exuser1 exuser2 exuser3 reboot kelloco2 przemek
I got guest
Sit down on the number: 6
Array looks like: exuser1 exuser2 exuser3 reboot kelloco2 przemek guest
I got exuser4
Sit down on the number: 7
Array looks like: exuser1 exuser2 exuser3 reboot kelloco2 przemek guest exuser4
But, after execute I get something like this:
I got exuser1
Sit down on the number: 0
Array looks like: exuser1
I got exuser2
Sit down on the number: 1
Array looks like: exuser1 exuser2
I got exuser1
Already exists!
Array looks like: exuser1 exuser2
I got exuser3
Sit down on the number: 2
Array looks like: exuser1 exuser2 exuser3
I got reboot
Sit down on the number: 3
Array looks like: exuser1 exuser2 exuser3 reboot
I got kelloco2
Already exists! //Here a problem arises
Array looks like: exuser1 exuser2 exuser3 kelloco2
I got przemek
Already exists!
Array looks like: exuser1 exuser2 exuser3 przemek
I got guest
Already exists!
Array looks like: exuser1 exuser2 exuser3 guest
I got exuser4
Sit down on the number: 4
Array looks like: exuser1 exuser2 exuser3 guest exuser4
.
What could be wrong? Regards K.
Haven't read all your code, but this bugs me:
while(*array != '\0') {
array is a **char
. This means *array is a *char
. But you compare it to a char ('\0'
). You probably meant NULL
?
And now to your bug:
*array=str;
This is the bad line. You aren't copying the string! You are just pointing to the same place in memory!
This means that if you change the string pointed to by str
, the string pointed to by *array
will change too!
So once you add a string using ut_name
and then changing ut_name
and adding it again - it finds it already, because you have the same memory for ut_name
and *array
.
Anyway - use strcpy
(after allocating memory!!!) instead of that line *array=str
and everything will work fine.