utilise un debuger pour vérifier quels caractères sont échangés … fais un dessin pour bien comprendre lesquels tu devrais échanger et lesquels tu échanges réellement.
First solve the problem. Then, write the code. ~ John Johnson
5.1.2.2.1 Program startup
It shall be defined with a return type of int and with no parameters:
int main(void) { /*...*/ }
or with two parameters (referred to here as argc and argv, though any names may be used,
as they are local to the function in which they are declared):
int main(int argc, char *argv[]) { /*...*/ }
Tu tentes de modifier une chaine littérale.
6.4.5 String literals
If the program attempts to modify such an array, the behavior is undefined.
Sources tirées de la norme ISO/IEC 9899:201x.
Après ces corrections, essaye à nouveau ton programme.
Tu déclares un pointeur aux qui pointe n'importe où et tu le déréférence pour lui assigner une valeur. je ne vois pas comment ça peut fonctionner a part avec de la (mal)chance ?
Nullement besoin exécuter ton code pour savoir qu'il est incorrect à bien des égards. - Tu ne testes pas ton pointeur d'entrée - Tu n'initialises pas ton pointeur de sortie - Tu n'alloues pas ton pointeur de sortie - Tu utilises de mauvais types pour déclarer tes variables, char* au lieu de const char*, ta chaîne d'entrée n'est jamais modifiée. Idem pour ta boucle, il faudrait plutôt utiliser un size_t qu'un int. - Ton algorithme est faux et oublie le dernier caractère de ta chaîne plus le caractère \0 qui est le caractère de fin de chaine.
Ça fait beaucoup pour une fonction simple. En tous cas, ton compilateur, quel qu’il soit est robuste
Ce n'est pas parceque ça fonctionne chez toi que c'est le cas partout.
Par exemple, chez moi ça crash. Logique puisque comme on te l'a expliqué il y a plusieurs problèmes, le principal étant que tu n'initialises pas ton pointeur aux (qui pointe donc n'importe où) et que tu le déréférence derrière. Si cela fonctionne chez toi c'est uniquement de la (mal)CHANCE !
L'initialisation des pointeurs (de tout type de variable en fait) est une garantie; Elle te permet de t'assurer qu'à n'importe quel moment de l'éxécution du programme l'état (sa valeur) ta variable (e.g pointeurs) soit défini. Un pointeur contient une adresse, lors de la création d'un pointeur l'adresse vers laquel pointe ton pointeur ne peut pas être connue à l'avance.
Lorsque tu initialise ton pointeur à NULL (qui équivaut à 0x00000000 pour une adresse en 32bits), tu peux à l'avance connaître l'état de ta variable avant sa modification. Connaître l'état de ta variable permet de garantir la conformité de tes données.
Aller un petit exemple:
int main(int argc, char *argv[])
{
char *s; // Non initialisé !!!
if (argc > 2) // On vérifi que la longueur d'argv
s = argv[1];
//Ici je veux m'assurer que ma variable est conforme à
//ce que j'attends en paramètre du programme
//(argv[1]).
// Comment ferais-tu pour t'assurer que 's' contient
//la valeur voulue ?
//Réponse: tu ne peux pas. Si le programme est lancé
//sans arguments tu n'as acutellement aucun moyen de
//vérifié que 's' contient les informations voulues.
return (0);
}
Alors qu'en initialisant 's' à NULL tu peux vérifier de cette manière :
int main(int argc, char *argv[])
{
char *s = NULL;
if (argc > 2)
s = argv[1];
if (s != NULL)
{
//Ici ma donnée est conforme, ou du moins son état a
//bien été modifié, dans le cas où le programme n'est
//pas lancé avec des paramètres je suis certain que
//ma partie de code ayant besoin de l'information ne
//sera pas éxécutée.
}
return (0);
}
Je sais qu'il y a toujours un moyen de vérifier l'intégrité de ses données autrement qu'en initialisant ses variables, mais cela requiert beaucoup de code pour le vérifier.
Remarque: Je te trouve plutôt agressif sur tes réponses. Sâche que personne n'est payé pour t'apprendre les "bonnes manières" de codage ici. Je vois très bien que tu ne maîtrise pas le français c'est pourquoi j'émets un doute sur tes intentions d'être agressif.
En espèrant t'avoir éclairé sur le fait qu'il faut TOUJOURS initialisé ses variables.
Ton pointeur aux n'est PAS initialisé. Tu l'as seulement déclaré et ensuite tu essayes de stocker quelque chose dedans. Si ça fonctionne c'est seulement de la chance. Si tu initialises aux a nullptr tu verras que ça crash.
Et pour info, tu n'as rien a faire pour me satisfaire, on te dit seulement ce qu'il en est. Tu ne veux pas nous croire/écouter ? Libre à toi, mais le jour ou ton programme crashera parceque tu n'as pas initialisé un pointeur, tu comprendras.
Toujours une agressivité chez certains... d'accord ce code ne marche pas il est pourri mais ce n'est pas une raison pour s’engueuler! bref je pense que ce genre de topique est toxique pour la communauté, car est-ce que hamzasaber3 a trouvé la réponse à sa question? ce débat ne mene absolument nulle (NULL) part.
Biensur ! Tu as plusieurs façons de faire qui s'offre à toi, mais tu devras d'abord te poser quelques questions :
- Est-ce que je veux effectuer le renversement de la chaîne sans allocation mémoire ?
- Est-ce que ma chaîne est en READ_ONLY (signifiant qu'elle ne peut être modifié) ?
- Est-ce que je veux que ma fonction détecte les palindromes (aucune action à effectuer sur un palindrome -> "LOL" donnera ..... "LOL") ?
- Etc...
Voici deux exemple de code :
Cette première fonction fait appel à l'allocation mémoire, et est donc "coûteuse" mais tu as la possibilité de passer en paramètre une chaîne dite 'const' (C.A.D non modifiable). Cette fonction return une nouvelle chaîne allouée qu'il faudra 'free()' (cf. allocation mémoire).
char *reverse_with_alloc(const char *str)
{
char *result = NULL;
size_t len = strlen(str) - 1;
size_t i = 0;
//Str est NULL rien à faire ici !
if (str == NULL)
return (NULL);
//Allocation de result de la taille de str + 1 (pour le '\0')
//Si malloc retourne NULL (rare) l'allocation ne sera pas faite
//on retourne donc NULL pour signaler une erreur.
if ((result = malloc(sizeof(*result) * len + 1)) == NULL)
return (NULL);
//On boucle sur la longueur de la chaîne 'str', en décalant 'len'
//par rapport à 'i' ce qui nous permet de récupérer les caractères
//de la fin vers le début de la chaîne.
for (; i < len; i++)
{
result[i] = str[len - i];
}
//On oublie pas le caractère signalant la fin d'une chaîne '\0'
result[i] = '\0';
return (result);
}
Deuxieme fonction, beaucoup moins "coûteuse" car elle ne fait pas d'allocation mémoire; Elle ne return rien, elle modifie la chaîne passée en paramètre et la renverse. Cependant cette fonction ne peut pas s'appliquer sur une chaîne non modifiable puisque .... on modifie justement la chaîne passée en paramètre.
void reverse(char *str)
{
size_t i = 0;
size_t len = strlen(str) - 1;
char tmp = 0;
//Str est NULL rien à faire ici !
if (str == NULL)
return ;
//On échange les caractères de fin et de début (obliger de passer par une temporaire 'tmp').
while (i < len)
{
tmp = str[i];
str[i] = str[len];
str[len] = tmp;
i++;
len --;
}
}
Essaye de voir avec ces deux exemples se qu'il faudrait changer dans ta fonction pour qu'elle remplisse sa tâche.
Deuxieme fonction, beaucoup moins "coûteuse" car elle ne fait pas d'allocation mémoire; Elle ne return rien, elle modifie la chaîne passée en paramètre et la renverse. Cependant cette fonction ne peut pas s'appliquer sur une chaîne non modifiable puisque .... on modifie justement la chaîne passée en paramètre.
void reverse(char *str)
{
size_t i = 0;
size_t len = strlen(str) - 1;
char tmp = 0;
//Str est NULL rien à faire ici !
if (str == NULL)
return ;
//On échange les caractères de fin et de début (obliger de passer par une temporaire 'tmp').
while (i < len)
{
tmp = str[i];
str[i] = str[len];
str[len] = tmp;
i++;
len --;
}
}
Essaye de voir avec ces deux exemples se qu'il faudrait changer dans ta fonction pour qu'elle remplisse sa tâche.
Nicolas;
C'est pas que ce code ne marche pas, mais il y a des petites choses à arranger
faire strlen() sur un pointeur NULL, est-ce bien raisonnable ? Tester avant....
quand une variable s'appelle len, c'est normalement qu'elle représente la longueur d'une chaine. Ce n'est pas le cas ici (quand on fait len--, c'est la longueur de quoi qui change ?). Ecrire "len", c'est mettre le lecteur sur une mauvaise voie.
quand on utilise une variable auxiliaire pour, par exemple, échanger le contenu deux variables, on la déclare AU PLUS PRES de l'endroit où on fait ça. Au passage, ça évite de faire une initialisation bidon.
void reverse(char *string)
{
if (string == NULL) {
return;
}
ssize_t left = 0, // edit, bug signalé
right = strlen(string) - 1; // par marc mongenet
while (left < right)
{
char tmp = string[left];
string[left] = string[right];
string[right] = tmp;
left++;
right--;
}
}
Mieux, avec une boucle for
for (ssize_t left=0, right=strlen(string)-1; left < right; left++, right--) {
char tmp = ...:
...
}
En effet, il devrait y avoir une partie dans les règles du forum interdisant de donner des conseils lors de la pause au travail, le cerveau n'y est plus !
Il me semble que vos codes contiennent de graves erreurs. Je pense surtout au dépassement de tampon en cas de traitement de chaine vide. Sinon, le reverse_with_alloc n'alloue pas assez de RAM, et copie incomplétement.
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.