assign zero in unsigned short int in c - c

I try to assign zero to a field in a structure called list
list.ultimo = 0;
but when I use printf
printf("%d", list.ultimo);
I get the result
32766
but when I add
unsigned short int cero = 0;
the result of printf is correct, no matter that does not use cero. why?
lista.h
#ifndef LISTA_H
#define LISTA_H
typedef struct{
elemento lista[TAMANOMAX];
unsigned short int ultimo;
}LISTA;
void Insertar(elemento, unsigned short int posicion, LISTA);
#endif
lista.c
#include<stdio.h>
typedef short int elemento;
#ifndef TAMANOMAX
#define TAMANOMAX 10
#endif
#include"lista.h"
void Insertar(elemento x, unsigned short int p, LISTA lista){
if (lista.ultimo >= TAMANOMAX){
puts("full list");
printf("%hu",lista.ultimo);
}
}
main.c
#include<stdio.h>
typedef unsigned short int elemento;
#define TAMANOMAX 4
#include"lista.h"
int main(){
LISTA esferas;
esferas.ultimo = 0;
Insertar(2,0,esferas);
printf("\n%hu\n", esferas.ultimo);
return 0;
}
the result is
$gcc -Wall lista.c main.c
full list
32765
0
I'm new to this, I'm slow for now, I regret the delay

Use %hd to print a short int and %hu to print an unsigned short int. %d is for int.
EDIT: Now that you have posted the full code, it appears that TAMANOMAX is set to 10 in lista.c, but set to 4 in main.c, leading to an incompatibilty between your main() function and the Insertar one. You should have the same value in all files. And if you want to work with different array lengths, add a length member in your LISTA structure. But TAMANOMAX should absolutely be the same everywhere, else you're in fact working with different data types and your program won't work.

Using mismatched format specifier with the type of the argument invokes undefined behavior.
Quoting C11 standard, chapter ยง7.21.6.1, fprintf() function
[..] If any argument is
not the correct type for the corresponding conversion specification, the behavior is
undefined.
and about %d format specifier,
d,i The int argument [....]
so, %d expects an int.
As per your question title, ultimo is unsigned short int and you're using %d to print the value.
You should use %hu to print unsigned short int.

Related

Why does the compiler complain about this `sprintf` argument?

The following code used to compile fine. I migrated the project to a new version and now the compiler is complaining about one of my sprintf arguments. Here is the warning:
warning: format '%02d' expects type 'int', but argument 12 has type 'double'
FYI, the IDE is MPLAB X 2.35 and the compiler is XC 1.34. I have optimizations turned off and I have tried clean/build. I can only suspect that maybe the struct alignment is out of whack. I am hoping I am just missing the obvious, such as not being able to count.
Offending code:
typedef struct _AnalysisEvent
{
unsigned short id;
unsigned char day;
unsigned char month;
unsigned char year;
unsigned char hour;
unsigned char minute;
unsigned char second;
unsigned int duration;
double min;
double max;
double avg;
} AnalysisEvent;
AnalysisEvent AnalysisEvents[ANALYSIS_MAX_COUNT][ANALYSIS_EVENTS_MAX_COUNT];
unsigned char AnalysisEventGetValueStrAlt(unsigned short id, unsigned char index, char *buffer, int length)
{
if (Analysis[id].count > index)
{
sprintf(buffer, "Analysis ID: %d\r\nEvent ID: %d\r\nMin: %.2f\r\nMax: %.2f\r\nAvg: %.2f\r\nTime: %02d/%02d/%02d %02d:%02d:%02d\r\nDuration: %d\r\n",
id,
index,
AnalysisEvents[id][index].min,
AnalysisEvents[id][index].max,
AnalysisEvents[id][index].avg,
AnalysisEvents[id][index].month,
AnalysisEvents[id][index].day,
AnalysisEvents[id][index].year,
AnalysisEvents[id][index].hour,
AnalysisEvents[id][index].min,
AnalysisEvents[id][index].second,
AnalysisEvents[id][index].duration
);
return index;
}
else
{
return 0;
}
}
Argument 12 is:
AnalysisEvents[id][index].min,
You probably want:
AnalysisEvents[id][index].minute,
In your case, the offending part is
%02d/%02d/%02d %02d:%02d:%02d\r\
^^^
The corresponding argument is AnalysisEvents[id][index].min, type double. You used %d.
FWIW, maybe the answer you want is
"the argument number in the warning message is the total of the ones supplied to sprintf(), counting from buffer itself, not only the ones supplied as the argument to the format."

Compilation in C

What will be output if you will compile and execute the following c code?
void main(){
int huge*p=(int huge*)0XC0563331;
int huge*q=(int huge*)0xC2551341;
*p=200;
printf("%d",*q);
}
Assuming you meant to write the following:
#include <stdio.h>
int main(void){
int *p=(int *)0XC0563331;
int *q=(int *)0xC2551341;
*p=200;
printf("%d",*q);
return 0;
}
then the output should be whatever integer value is stored starting at address 0xC2551341.
I'm not sure what int huge is supposed to represent; wider integer types are long int and long long int (or just long and long long). Note that these wider types use the %ld and %lld conversion specifiers for output, respectively.

printf char as hex in c

I expect ouput something like \9b\d9\c0... from code below, but I'm getting \ffffff9b\ffffffd9\ffffffc0\ffffff9d\53\ffffffa9\fffffff4\49\ffffffb0\ffff
ffef\ffffffd9\ffffffaa\61\fffffff7\54\fffffffb. I added explicit casting to char, but it has no effect. What's going on here?
typdef struct PT {
// ... omitted
char GUID[16];
} PT;
PT *pt;
// ... omitted
int i;
for(i=0;i<16;i++) {
printf("\\%02x", (char) pt->GUID[i]);
}
Edit: only casting to (unsigned char) worked for me. Compiler spits warnings on me when using %02hhx (gcc -Wall). (unsigned int) had no effect.
The reason why this is happening is that chars on your system are signed. When you pass them to functions with variable number of arguments, such as printf (outside of fixed-argument portion of the signature) chars get converted to int, and they get sign-extended in the process.
To fix this, cast the value to unsigned char:
printf("\\%02hhx", (unsigned char) pt->GUID[i]);
Demo.
Use:
printf("\%02hhx", pt->GUID[i]);
Because printf() is a variadic function, its arguments are promoted to int. The hh modifier tells printf() that the type of the corresponding value is unsigned char and not int.
Cast to unsigned char instead, to avoid a leading 1 bit being interpreted as a negative value.
I noticed that you were getting the F's when the number was larger than 99x.
I wrote this to test it out and discovered the hh prefix at http://www.cplusplus.com/reference/cstdio/printf/
#include "stdio.h"
char GUID[16];
int main() {
int i;
for(i=0;i<16;i++) {
GUID[i]=i*i;
}
for(i=0;i<16;i++) {
printf("\\%02.2hhx\n", GUID[i]);
}
return 0;
}
Use a small own implementation to solve this problem on all platforms:
char hex[] = "0123456789abcdef";
void printHex(unsigned char byte) {
printf("%c%c", hex[byte>>4], hex[byte&0xf]);
}

Why won't this C program print the unsigned int?

I wrote this function to reverse a number. I will have test cases that are up to 2^32. I need the function to return unsigned ints. My question is this: why wont this print?
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
unsigned int reverse(unsigned int a);
int main(){
printf("%u\n",reverse(987654321));
//printf("%ui\n",reverse(987654321)); //this wont work either
return 0;
}
unsigned int reverse(unsigned int a)
{
int temp=0;
while(a>0)
{
temp=10*temp+a%10;
a/=10;
}
return temp;
}
Yes I did forget about the proto-type... Bear with me I have been doing Java and Lisp lately. However, my compiler keeps giving me a warning saying I have extra characters in the format string. It also does this if I have type "long long int" and I use "%lli% in the format string, which I also tried.
You forgot to include prototype for your function before main.
unsigned int reverse(unsigned int a);
The number probably is just too big for an unsigned on your architecture.
Remember to always enable maximum warning level for your compiler. This should have told you that reverse is not known where you use it, that you are passing an int to the %u format and also that your number ist too big.

Fail to read a value from a struture in C after assigning it

I have strange program behavior while trying to read a value from a structure after assigning a value to it. I'm showing the related structure and function below:
/*Data struct for cor_entry */
struct cor_entry {
struct cor_entry * pre_entry;
struct cor_entry * next_entry;
long long unsigned int entry_data;
};
I've commented out most of my function to highlight the problem:
/* update correlation table */
void cor_table_update(long long unsigned int cor_table_data,
struct cor_entry **cor_table_head_ptr,
struct cor_entry **cor_table_tail_ptr,
int *entry_num,
const int MAX_NUM)
{
struct cor_entry *cor_table_entry;
int cor_hit=0;
//test code
//cor_table_head=cor_table_tail=(struct cor_entry*)calloc(1, sizeof(struct cor_entry));
//printf("original cor_entry_num=%d\n",*entry_num);
////////////////////////code for test///////////////////////////////
cor_table_entry=(struct cor_entry*)calloc(1, sizeof(struct cor_entry));
printf("The cor_table_entry=%x\n",cor_table_entry);
cor_table_entry->entry_data=cor_table_data;
if (cor_table_entry->entry_data==cor_table_data)
{
printf("The assignment is correct!\n");
printf("the cor_enrty_data=%x, stored data=%x,\n",
cor_table_data,
cor_table_entry->entry_data);
}
// ... rest of function
}
And I get this output while running the program:
The cor_table_entry=8c09a58
The assignment is correct!
the cor_enrty_data=8ffc8, stored data=0,
The cor_table_entry=8c09a70
The assignment is correct!
the cor_enrty_data=8ffc8, stored data=0,
The cor_table_entry=8c09a88
The assignment is correct!
the cor_enrty_data=8ffc8, stored data=0,
The cor_table_entry=8c09ae8
Could someone shed some light on this problem? I'm using the GCC-3.4.6 compiler.
Try to compile with -Wall. GCC should then tell you that the sizes of the % format specifiers and the printf() arguments don't match. Try %llx instead of %x. That should fix the issue.
Your problem is probably with the printf, %x is not designed for showing long long unsigned. Split the value before printing it and it shall be what you expect.
You could also use %llx format specifier if your compiler support it.

Resources