I'm currently trying to compare each String from a char**
with another String.
In order to do so I tried to use strcmp
but I get a Segmentation Fault. Then i tried to use a hand-made strcmp, and by testing I have been able to spot that my seg. fault happens when at the end of the comparaison between the word that I'm spotting and char[i].
Here are some lines and some tests so you can get the issue.
That's my main :
int
main(int argc, char *argv[])
{
char search[1024];
ssize_t sz = getxattr(argv[1], "user.tag", search, sizeof(search) - 1);
printf("Old tags: %s\n", search);
if (sz != -1) {
char **tab = malloc(sizeof(char **));
tab = StringToTab(search);
char *mot = malloc(sizeof(char));
strcat(mot, argv[2]);
strcat(mot, "\0");
printf("\n%s\n", tab[3]);
if (estDansLeTableau(tab, mot, nb_occ(search, ',') + 1)) {
char *newtag = TabToString(removeFromTab(tab, argv[2],
(nb_occ(search, ','))
),
(nb_occ(search, ','))
);
printf("\nICI 1\n");
if (setxattr(argv[1], "user.tag", newtag, strlen(newtag), 0) == -1) {
perror("ERREUR");
}
else {
printf("\n La nouvelle liste de tag pour votre fichier est : %s \n", newtag);
}
memset(newtag, 0, 0);
}
else {
printf("\nle tag demandé n'est pas dans la liste des tags de ce fichier\n");
}
memset(tab, 0, 0);
}
else {
printf("\nLe fichier n'a aucun tag a enlever\n");
}
}
Tab is coming from the fonction StringToTab
who basically takes a string like [abc,bcd,def]
and turn it into a char**
like ["abc","bcd","def"]
:
char **
StringToTab(char *s)
{
char **tab = malloc((nb_occ(s, ',') + 1) * sizeof(char *));
char *add = malloc(sizeof(char *));
char c = s[1];
int j = 1;
int i = 0;
while (c != ']') {
if (c == ',') {
char *caracterVide = malloc(sizeof(&c));
caracterVide = "\0";
strcat(add, caracterVide);
memset(caracterVide, 0, 0);
printf("\nMot = %s\n", add);
tab[i] = malloc(sizeof(char *));
memcpy(tab[i], add, strlen(add));
printf("\nAffected word = %s\n", tab[i]);
memset(add, 0, sizeof(add));
i++;
j++;
c = s[j];
}
else {
char *sac = malloc(sizeof(&c));
*sac = c;
strcat(add, sac);
memset(sac, 0, 0);
printf("\nprefix = %s", add);
j++;
c = s[j];
}
}
printf("\nMot = %s\n", add);
tab[i] = malloc(sizeof(char *));
memcpy(tab[i], add, strlen(add));
printf("\nAffected word = %s\n", tab[i]);
memset(add, 0, 0);
i++;
j++;
c = s[j];
return tab;
}
Then we go to estDansLeTableau
(=isInTheTab) which is gonna take the tab that we just had, the argv[2]
which is the tag that I need to spot.
int
estDansLeTableau(char **t, char *m, int t_len)
{
// 1 si le mot est dans le tableau, 0 sinon
int j = 0;
while (j < t_len) {
printf("\nword 1 = %s, word 2 = %s\n", t[j], m);
if (strcmp(t[j], m) == 0) {
return 1;
}
else {
j++;
}
}
return 0;
}
and here is a test where i'm trying to spot "lol" on the tab :
Old tags: [Amine,Chris,Sara,Kamelia,lol,Sarah,Sarah]
prefix = A
prefix = Am
prefix = Ami
prefix = Amin
prefix = Amine
Mot = Amine
Affected word = Amine
prefix = C
prefix = Ch
prefix = Chr
prefix = Chri
prefix = Chris
Mot = Chris
Affected word = Chris
prefix = S
prefix = Sa
prefix = Sar
prefix = Sara
Mot = Sara
Affected word = Sara
prefix = K
prefix = Ka
prefix = Kam
prefix = Kame
prefix = Kamel
prefix = Kameli
prefix = Kamelia
Mot = Kamelia
Affected word = Kamelia
prefix = l
prefix = lo
prefix = lol
Mot = lol
Affected word = lol
prefix = S
prefix = Sa
prefix = Sar
prefix = Sara
prefix = Sarah
Mot = Sarah
Affected word = Sarah
prefix = S
prefix = Sa
prefix = Sar
prefix = Sara
prefix = Sarah
Mot = Sarah
Affected word = Sarah
Kamelia
word 1 = Amine, word 2 = lol
word 1 = Chris, word 2 = lol
word 1 = Sara, word 2 = lol
word 1 = Kamelia, word 2 = lol
word 1 = lol, word 2 = lol
Segmentation fault
It's been 2 days that I'm stuck on it and i have NO CLUE on how to solve it S.O.S lmao! Thanks a lot !
Most of the memory allocations are for the size of a pointer. On my system that is eight bytes. That could work as long as there are no elements more than seven characters.
char *caracterVide = malloc(sizeof(&c));
char *add = malloc(sizeof(char *));
There are also memory leaks.
char **tab = malloc(sizeof(char **));
tab = StringToTab(search);
The assignment following the malloc
overwrites the value returned by malloc and that memory can not be freed.
This is very curious.
char *sac = malloc(sizeof(&c));
*sac = c;
strcat(add, sac);
There is nothing to ensure that sac
is zero terminated. The concatenation could, by pure chance, add one character or it could iterate until a zero is found and possibly crash the program.
Here is one approach to taking the original string and breaking it into items separated by commas.
strspn
and strcspn
are very useful for counting characters. strspn
stops counting at the first non-matching character or the terminating zero and strcspn
stops at the first matching character or the terminating zero.
This does not show the items character by character but that could be done.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char ** StringToTab(char *s) {
char **tab = NULL;
char *comma = s;
char *item = s;
int count = 0;
int span = 0;
while ( *item) {// loop to terminating zero
item += strcspn ( item, ",");//count of characters that are not ,
if ( *item) {
++item;//advance past ,
}
++count;//add one for each comma
}
++count;//add one for item fillowing last comma
//allocate extra sentinel pointer
if ( NULL == ( tab = calloc ( sizeof *tab, ( count + 1)))) {
fprintf ( stderr, "calloc problem\n");
return tab;
}
count = 0;
item = s;
item += strspn ( s, "[");//count of characters that are [
while ( *item) {//not at terminating zero
comma = item;//set comma to the same as item
comma += strcspn ( item, ",");//count of characters that are not ,
if ( *comma) {
span = comma - item;
}
else {//at the terminating zero
span = strcspn ( item, "]");//count of characters that are not ]
}
//allocate memory for each item
if ( NULL == ( tab[count] = malloc ( span + 1))) {//span characters plus terminating zero
fprintf ( stderr, "malloc problem\n");
return tab;
}
strncpy ( tab[count], item, span);//copy span characters
tab[count][span] = 0;//set terminating zero
++count;
item = comma;
if ( *comma) {//not terminating zero
++item;//increment past ,
}
}
return tab;
}
int estDansLeTableau(char **t, char *m) {
// 1 si le mot est dans le tableau, 0 sinon
int j = 0;
while ( t[j]) {
printf("\nword 1 = %s, word 2 = %s\n", t[j], m);
if (strcmp(t[j], m) == 0) {
return j;
}
j++;
}
return -1;
}
int main(int argc, char *argv[]) {
char **tab = NULL;
char test[] = "[Amine,Chris,Sara,Kamelia,lol,Sarah,Sarah]";
char mot[] = "lol";
int each = 0;
int match = 0;
printf("Old tags: %s\n", test);
tab = StringToTab ( test);
if ( tab) {
if ( 0 <= ( match = estDansLeTableau(tab, mot))) {
printf("match %s at %d\n", mot, match);
}
each = 0;
while ( tab[each]) {
free ( tab[each]);
++each;
}
free ( tab);
}
}