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 valeur50en ascii.@tkausl Qu'est-ce qui vous empêche de répondre?
Allez-vous jamais obtenir
255en utilisant un autre spécificateur de format? Lecharest 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.