J'ai ce code:
int main(){ char buffer[1024]; char port = 1; int length = 255; char * record = "$TAG ,0 ,89 ,0, 1\n"; if(length < 0 || length > 255){ printf("Error - length out of range for an unsigned char.\n"); exit(1); } snprintf(buffer, 1024, "%c%c%s", port, (unsigned char) length, record); int port_rc = buffer[0]; int length_rc = buffer[1]; printf("port_rc: %d\n",port_rc); printf("length_rc: %d\n",length_rc); return 0;
}
Sortie lorsque je l'exécute:
port_rc: 1
length_rc: -1
Je pense qu'il me manque quelque chose ici en termes de snprintf () car je ne vois pas la valeur 255 lors de la lecture du tableau qu'il a créé. Je suppose que snprintf () promeut la variable «length» en un int ou quelque chose. Quelqu'un sait-il comment je peux y parvenir?
Merci.
3 Réponses :
Je ne pense pas que vous puissiez utiliser sprintf ()
pour stocker 255
dans le tampon. L'argument buffer de sprintf ()
est un tableau de char
. Le fait que char
soit signé
ou unsigned
par défaut est défini par l'implémentation; voir Le caractère est-il signé ou non signé par défaut? . Si 255
est supérieur à CHAR_MAX
, essayer de stocker 255
entraîne un comportement non défini; si l'implémentation par défaut est signé
alors CHAR_MAX
sera probablement 127
.
Je suggère de ne pas utiliser sprintf () code > pour stocker des nombres dans le tampon. Déclarez-le comme:
buffer[0] = port; buffer[1] = length; snprintf((char *)(buffer + 2), sizeof buffer - 2, "%s", record);
Ensuite, vous pouvez faire:
unsigned char buffer[127];
Bien, mais cela ne renvoie pas 255 dans la variable 'length_rc'. Veuillez consulter le code modifié ci-dessus. Et si je change la «longueur» en 127 (le plus grand nombre de caractères signés), la sortie est produite comme prévu.
Je vois le problème. Le tampon est char []
, pas unsigned char []
. Donc buffer [1]
est signé. Le stockage de 255
dans la mémoire tampon entraîne un comportement indéfini.
J'ai mis à jour la réponse pour montrer comment vous pouvez le faire de manière plus sûre.
Merci beaucoup @Bamar - j'ai intégré votre solution. Mon message est mis à jour pour refléter les changements de travail.
Vous devez mettre la solution de travail dans une réponse, pas dans la question.
Terminé. Merci encore.
SOLUTION DE TRAVAIL:
int main(){ unsigned char buffer[1024]; char port = 1; int length = 255; char * record = "$TAG ,0 ,89 ,0, 1\n"; if(length < 0 || length > 255){ printf("Error - length out of range for an unsigned char.\n"); exit(1); } buffer[0] = port; buffer[1] = length; snprintf((char *)(buffer), sizeof buffer - 2, "%c%c%s", port,length,record); int port_rc = buffer[0]; int length_rc = buffer[1]; char char_first = buffer[2]; printf("port_rc: %d\n",port_rc); printf("length_rc: %d\n",length_rc); printf("char_first: %c\n",char_first); return 0;
}
RETOURS:
port_rc: 1
longueur_rc: 255
char_first: $
"Soyez prudent, cependant," lorsque vous jugez une telle "solution".
À mon humble avis, le problème fondamental - dans votre message d'origine - est que les variables port_rc
et length_rc
auraient dû être déclarées comme non signées entiers. Vous ne voulez pas qu'une valeur telle que $ FF
soit à tort "sign-extended" pour devenir $ FFFFFFFF == -1
...
Votre "solution" est assez différente de l'original car, comme vous le voyez, elle stocke désormais à la fois le buffer [0]
et le buffer [1]
avant de récupérer et d'examiner ces valeurs!
Je suis d'accord mais je m'assure que le retour valide est compris entre 0 et 255 pour être sûr.
Le premier caractère de
"255"
est'2'
qui a la valeur50
en ascii.@tkausl Qu'est-ce qui vous empêche de répondre?
Allez-vous jamais obtenir
255
en utilisant un autre spécificateur de format? Lechar
est présumé signé, puisque vous utilisez un cast de(unsigned char)
plutôt que(char)
. Vous obtiendrez donc-1
.buffer [1]
a le typechar
, il est littéralement impossible pour lui de stocker 255 (en supposant que votre système a un caractère simple comme signé)@ M.M - oui c'est pourquoi j'essayais d'utiliser un caractère non signé. J'ai compris et vous pouvez voir ma solution dans ma réponse.