modifier un char * - C - Programmation
Marsh Posté le 28-09-2017 à 14:15:07
nanataw a écrit : normal je peux pas modifier parce que j'utilise un pointeur pour déclarer ma variable. |
"blabla" est une constante, donc effectivement tu peux pas modifier.
(Entre parenthèses, si tu as vraiment utilisé des guillemets simples tu devrais te prendre une erreur de compilation, je suppose que c'est une faute d'inattention en écrivant ton message.)
Citation : Mais si je le fais sur un argument de la ldc qui pourtant est aussi un char * là ça marche je peux modifier ... |
ldc? Donne un exemple pour que ce soit clair (code le plus court possible mais complet et qu'on peut compiler/exécuter).
Marsh Posté le 29-09-2017 à 01:03:55
Citation : Mais si je le fais sur un argument de la ldc qui pourtant est aussi un char * là ça marche je peux modifier ... |
ligne de commande, je veux dire au lieu de dire char * chaine = "blabla" je lance le code compilé avec un argument (qui est aussi un char * on est d'accord, donc un const, donc normalement non modifiable)
là ça marche, je vais pouvoir remplacer le premier caractère du 2eme argument de la ligne de commande :
Code :
|
Mais là ça ne marche pas (erreur segmentation) :
Code :
|
Pourtant ma variable test est de même nature que args, ce sont des char * donc pourquoi je peux modifier quand ça vient de la ldc ?
J'espère avoir été clair et court.
Merci beaucoup en tout cas.
Marsh Posté le 29-09-2017 à 01:38:57
(edit: connerie )
nanataw a écrit : là ça marche, je vais pouvoir remplacer le premier caractère du 2eme argument de la ligne de commande : |
Pas chez moi (sous Windows), le programme se plante. J'ai pas envie de vérifier vu l'heure, mais il me semble que le standard dit qu'on peut pas modifier les arguments passés en ligne de commande, si on veut faire ça il faut faire une copie avant (exemple sur demande).
De manière générale, quelque remarques:
-Tu utilises des noms de variables inhabituels pour main. C'est pas faux, mais en principe (par convention) c'est toujours int main(int argc, char **argv) ou char * argv[], ça revient au même. Mais ce que tu fais n'est pas faux, libre à toi de modifier les noms!
-Attention à la mise en forme du code! Indentation etc. C'est important de partir sur des bonnes bases dès le début, sinon ça devient vite le bazar.
-Ton code est un peu étrange, modif retournera toujours 1, en cas d'erreur de segmentation le programme est stoppé net, il n'est plus question de if et de return alors.
-C'est bien d'avoir écrit un prototype de fonction comme il faut!
Marsh Posté le 29-09-2017 à 16:33:21
rat de combat a écrit : Pas chez moi (sous Windows), le programme se plante. J'ai pas envie de vérifier vu l'heure, mais il me semble que le standard dit qu'on peut pas modifier les arguments passés en ligne de commande, si on veut faire ça il faut faire une copie avant (exemple sur demande). |
Merci pour tes remarques. oui code un peu étrange mais c'est juste parce que j'ai juste isolé la question que je me pose qui est que d'après ce que j'ai compris je peux pas modifier un char * mais on peut modifier un char x[]
Tu lances bien le code compilé avec un argument ? genre moi avec mon premier exemple quand "nomduscript argument", moi si je fais ça j'obtiens bien "argument hrgument"
Faudrait que je teste sous windows pour voir.
Du coup si ça marche pas sous windows, la solution serait de copier char * argv dans un char copieargvs[] de la taille de char * argv pour pouvoir le modif tranquillement ?
Marsh Posté le 29-09-2017 à 16:45:33
nanataw a écrit : Tu lances bien le code compilé avec un argument ? |
Je devrais vraiment pas poster à 1h du mat'. J'avais pas mis d'argument, avec argument ça marche. Et en tout cas en C99 on peut modifier les arguments à priori: https://stackoverflow.com/questions [...] modifiable
Désolé pour les conneries de ma part.
Marsh Posté le 29-09-2017 à 16:55:29
rat de combat a écrit : Je devrais vraiment pas poster à 1h du mat'. J'avais pas mis d'argument, avec argument ça marche. Et en tout cas en C99 on peut modifier les arguments à priori: https://stackoverflow.com/questions [...] modifiable |
Aucun souci ! Mais alors pourquoi ça marche ? Alors que pourtant c'est bien un char * ? et pourtant ça marche pas si je déclare mon char * dans le code ? Tu sais ?
Marsh Posté le 29-09-2017 à 17:15:52
Pour répondre à tes questions, en espérant ne pas me tromper cette fois...
Citation : d'après ce que j'ai compris je peux pas modifier un char * mais on peut modifier un char x[] |
Non. Tu peux modifier toute chaîne de caractère ("string" ) qui n'est pas un "literal", autrement dit constant (ou déclaré comme tel). La différence entre char* et char[] c'est que c'est pas la même chose: char* est un pointeur, tu réserves donc de la place en mémoire pour y placer une adresse, mais pas de place pour mettre des chars (caractères). Avec char x[42] tu réserves au contraire de la mémoire à une adresse qui sera placée dans x. x est un tableau mais peut devenir un pointeur (quand on le passe comme argument à une fonction p.ex.). Si je passe x à une fonction je "reçois" un char* - mais je peux bien sûr modifier la chaîne de caractère vers laquelle pointe x!
Code :
|
En espérant ne pas créer de confusion supplémentaire... Les pointeurs etc c'est pas forcément évident mais très important en C.
Autre chose, tu as activé les warnings sur ton compilateur? Très utile et je dirais même obligatoire, surtout pour un débutant! Pour GCC: Rajouter -Wall en ligne de commande (voire -Werror aussi pour s'arrêter au moindre problème).
Marsh Posté le 29-09-2017 à 17:18:04
nanataw a écrit : Aucun souci ! Mais alors pourquoi ça marche ? Alors que pourtant c'est bien un char * ? et pourtant ça marche pas si je déclare mon char * dans le code ? Tu sais ? |
Voir ma réponse juste au dessus. Il ne faut pas se fixer sur char* et char[]. Les arguments du programme ne sont pas considérés comme des "literal", donc on peut (à priori, cf lien avec la citation du standard C99) les modifier. Certes tu as un char* (qui en soit est un pointeur qui ne "réserve" pas de place pour des chars en mémoire) pour les arguments mais il y a bien de la place mémoire réservée quelque part et qui contient les arguments, c'est automatique quand on lance le programme (et ton char* pointe vers cet espace mémoire).
(Sachant que on a en fait un double pointeur pour argc ou un tableau de pointeurs si on veut, car on a / peut avoir plusieurs arguments.)
Marsh Posté le 01-10-2017 à 01:48:47
rat de combat a écrit : Voir ma réponse juste au dessus. Il ne faut pas se fixer sur char* et char[]. Les arguments du programme ne sont pas considérés comme des "literal", donc on peut (à priori, cf lien avec la citation du standard C99) les modifier. Certes tu as un char* (qui en soit est un pointeur qui ne "réserve" pas de place pour des chars en mémoire) pour les arguments mais il y a bien de la place mémoire réservée quelque part et qui contient les arguments, c'est automatique quand on lance le programme (et ton char* pointe vers cet espace mémoire). |
J'ai compris ! Merci beaucoup pour ces explications claires et détaillées, et tous tes conseils.
Marsh Posté le 28-09-2017 à 01:47:30
Bonsoir,
Question de débutant mais qui m'intrigue pas mal ...
si je dis genre char * x = 'blabla' ; puis x[0] ='g' j'ai une erreur de segmentation... normal je peux pas modifier parce que j'utilise un pointeur pour déclarer ma variable.
Mais si je le fais sur un argument de la ldc qui pourtant est aussi un char * là ça marche je peux modifier ...
Comment ça s'explique ?