Impression de type int avec% lu – C + XINU

J’ai un code donné, à mon avis, il y a un problème avec ce code: je comstack sous XINU.

Les variables suivantes sont pertinentes:

unsigned long ularray[]; int num; char str[100]; 

Il y a une fonction retourne int:

 int func(int i) { return ularray[i]; } 

maintenant le code est comme ça:

 num = func(i); sprintf(str, "number = %lu\n", num); printf(str); 

Le problème, c’est que j’obtiens de gros chiffres en imprimant avec% lu, ce qui n’est pas correct.

Si je change le % lu en % d , j’obtiens le nombre correct. Par exemple: avec% lu, je reçois 27654342, alors que pour% di, obtenez 26, ce dernier est correct;

Les variables sont données, la déclaration de la fonction est donnée, j’écris le corps mais il doit renvoyer int;

Mes questions sont:

  1. Je ne suis pas familier avec ‘sprintf’ peut-être que le problème est là?

  2. J’ai assigné unsigned long à int puis j’imprime l’int avec% lu, est-ce exact?

  3. Comment puis-je résoudre le problème?

Merci d’avance.

Merci à tous pour votre réponse. Je veux juste mentionner que je travaille sous XINU, eh bien, j’ai changé l’ordre de compilation des fichiers et ce que vous savez … cela fonctionne et affiche les mêmes chiffres sur% lu et% d.

Je suis bien conscient du fait qu’atsortingbuer ‘unsigned long’ à int, puis imprimer avec% lu est un codage incorrect et peut entraîner une perte de données. Mais comme je l’ai dit, le code est donné, je ne pouvais pas changer les variables et la commande d’impression.

Je n’ai eu aucune erreur ou avertissement d’ailleurs. Je ne sais pas pourquoi la modification de l’ordre de compilation a résolu le problème, si quelqu’un a une idée que vous êtes plus que bienvenu à partager.

Je tiens à remercier tous ceux qui ont essayé de m’aider.

J’ai assigné unsigned long à int puis j’imprime l’int avec% lu, est-ce exact?

Non, ce n’est pas correct du tout. Pensez-y un peu! Printf essaie d’accéder à la mémoire représentée par les variables que vous transmettez. Dans votre cas, unsigned long est représenté sur plus de bits que int. C’est pourquoi, lorsque printf est invité à imprimer un unsigned int, il lira au-delà de votre int autre mémoire qui est probablement des ordures, d’où les nombres aléatoires. Si printf avait un prototype mentionnant exactement un unsigned long, le compilateur pourrait effectuer une conversion implicite et remplir le rest de la mémoire non désirée avec des zéros, mais comme ce n’est pas le cas, vous devez utiliser l’une des solutions suivantes:

Un casting explicite de votre variable:

 printf("%lu", (unsigned long)i); 

Deuxièmement, utilisez le spécificateur de format correct:

 printf("%d", i); 

En outre, l’affectation d’un long non signé à un entier pose des problèmes – si le long contient un nombre trop grand, il ne rentrera pas dans le int et ne sera pas tronqué.

1) le malentendu concerne les spécificateurs de format en général

2) num est un int. Par conséquent, %d est correct lorsqu’un int correspond à ce que vous voulez imprimer.

3) idéalement

  • int func(int i) serait unsigned long func(size_t i)
  • et int num serait unsigned long num
  • et sprintf(str, "number = %d\n", num); serait sprintf(str, "number = %lu\n", num);

De cette façon, il n’y aurait pas de ressortingction ni de conversion – le type / les valeurs seraient conservés correctement tout au long de l’exécution.

et pour être pédant, printf doit être printf("%s", str);

si vous augmentez vos niveaux d’avertissement, votre compilateur vous avertira de certaines de ces choses. Je programme depuis longtemps et je laisse toujours le niveau d’avertissement excessivement élevé (selon les normes de certaines personnes).

Si vous avez un int , utilisez %d (ou %u pour unsigned int). Si vous avez un long terme, utilisez %ld (ou %lu pour long unsigned).
Si vous dites à printf que vous lui donnez un long mais ne passez qu’un int, vous allez imprimer des ordures aléatoires. (Techniquement, ce serait un comportement indéfini.)

Peu importe que cet int “vienne d’une” manière ou d’une autre. Une fois que vous l’avez assigné à quelque chose de plus court, les octets supplémentaires sont perdus. Vous avez seulement un int gauche.

J’ai assigné unsigned long à int puis j’imprime l’int avec% lu, est-ce exact?

Non, et je suggère de ne pas lancer le traitement sur int en premier ou d’utiliser simplement int comme type de tableau. Il semble insensé de stocker une représentation beaucoup plus grande et d’en utiliser une plus petite. Dans tous les cas, les résultats du sprint seront toujours désactivés jusqu’à ce que vous associez correctement le type (techniquement l’ encodage ) de la variable au spécificateur de conversion du format. Cela signifie que si vous passez un long non signé, utilisez %ul , s’il s’agit d’un entier, utilisez %i ou %d (la différence est que %d est toujours en base 10, %i peut prendre des spécificateurs supplémentaires pour imprimer dans d’autres bases. .

Comment puis-je résoudre le problème?

Changez le retour de votre fonction et l’encodage de num sur unsigned long

 unsigned long ularray[]; unsigned long num; char str[100]; unsigned long func(int i) { return ularray[i]; }