snprintf + Pebble - c

I'm developing for Pebble and I'm off to a rough start.
I'm trying to populate a text_layer with 2 strings and 2 values, something like this:
WAIT AVG: 3 MAX: 5
Since malloc is not supported in Pebble SDK, I can't use sprintf, hence I'm stuck with snprintf. The following code only prints "4":
srand(time(NULL));
int average = (rand()%6)+1;
int maximum = average + 2;
static char *avgText="WAIT AVG: ";
static char *maxText="MAX: ";
snprintf(labelText,sizeof(avgText) + sizeof(average) + sizeof(maxText) + sizeof(maximum),"%s %d %s %d",avgText,average,maxText,maximum);
Any help would be greatly appreciated. I know that I can create 4 separate TextLayers but that's kind of a last resort for me.

You're just using snprintf wrong. ;-)
The second parameter (which you're trying to calculate, badly) is the length of the character array that you're printing into, not the number of characters you're trying to write.
Something like this should work:
char labelText[64]; // Is this big enough?
snprintf(labelText, 64,"%s %d %s %d",avgText,average,maxText,maximum);

sizeof(avgText) and sizeof(maxText) are sizes of pointers, not array sizes. See e.g. here. Change your code to
static char avgText[] = "WAIT AVG: ";
static char maxText[] = "MAX: ";
in order to make them arrays.
edit:
Further note, that sizeof(average) is the size in bytes average covers internally, not how many bytes a decimal representation would consume.
edit2:
As Roddy's answer says, it's wrong to calculate the size we want to have and pass that size to snprintf as an actual buffer size. We can, however, calculate the size we want to have provided there is a reasonable upper bound (e.g. with 32 bit int, 10 bytes (without 0-terminator) are always sufficient, but maybe you can give a lower upper bound in your use case):
char labelText [
sizeof avgText - 1 + 10 +
sizeof maxText - 1 + 10 + 3 + 1
];
/* sizeof avgText counts the 0-terminator, so does sizeof maxText, hence
the -1, two times 10 for the `int` (or any reasonable upper bound you have),
3 spaces and the 0-terminator. */
and you could even use sprintf. With snprintf, you can do:
snprintf(labelText, sizeof labelText,"%s %d %s %d", avgText, average, maxText, maximum);
HTH

read the man page of snprintf() properly. it says, the second argument size is used to refer to the number of bytes to be written.
sizeof (avgText) and sizeof(maxText)is not gonna work here. It refers to the size of the pointer, not the length of the array it holds. Maybe you want to use strlen() for the string length.

So this worked:
srand(time(NULL));
static char labelText[]="WAIT AVG: xxxxx MAX: xxxxxx";
int average = (rand()%6)+1;
int maximum = average + 2;
static char avgText[]="WAIT AVG: ";
static char maxText[]="MAX: ";
snprintf(labelText,sizeof(labelText),"%s %d %s %d",avgText,average,maxText,maximum);
text_layer_set_text(waitField,labelText);
thanks guys

Related

Is it true that the amount of necessary binary digits for any given positive integer is ceil( log_2 n)?

Title pretty much says it. I can only guess but I have no proof that this holds. In Python math.ceil(math.log(n) / math.log(2)).
Context: I'm creating a intbyte-to-char*binary function which only displays the necessary digits (id est no trailing zeros), thus I would need to dynamically allocate memory for the char array. However I assume there exists an upper bound which I could use to determine the length statically.
Edit: It seems my approach was wrong. To check the amount of digits necessary, it is way faster just to divide the number by 2 successively until it is 0 and keep track of the amount of divisions.
The formula is almost correct but you'll be out by one digit for exact powers of 2. The formula
1 + math.floor(math.log(n) / math.log(2))
would, I think, work better. But I wouldn't dwell on that too much simply because I'd never rely on a computer to compute math.floor(math.log(n) / math.log(2)) without the risk of the result being one less due to imprecision centred around floating point and the computation of a log: for the latter you're at the mercy of your chipset.
Testing the length by repeated integer division by 2 until zero is attained would be more robust, and possibly faster. log is not a cheap function computationally. You could even use the flashy bit fiddle x & (x - 1) (Google it).
You have a nice answer from #Bathsheba, for the second part of the question:
I would need to dynamically allocate memory for the char array.
However I assume there exists an upper bound which I could use to
determine the length statically.
You can use snprintf (with NULL as buffer and 0 as maximum num of bytes) to count the number of characters / digits:
#include <stdio.h>
int main(void)
{
size_t len = snprintf(NULL, 0, "%d", 1234) + 1;
char str = malloc(len);
snprintf(str, len, "%d", 1234);
puts(str);
free(str);
return 0;
}
Another way (if you can use GNU extensions) is asprintf:
#define _GNU_SOURCE
#include <stdio.h>
int main(void)
{
char *str;
asprintf(&str, "%d", 1234);
puts(str);
free(str);
return 0;
}

Coverity deflect: - String length miscalculation (BAD_ALLOC_STRLEN)

I have a coverity deflect to be fixed but I am not sure about it. I have a function (void my_function(a_type *my_variable)) with the following problematic line of code:
body = malloc(strlen(&((my_type*) *my_variable)->Param2.body[1]) +1);
where body is an unsigned char*.
The Coverity message:
String length miscalculation (BAD_ALLOC_STRLEN)
Using "strlen(((my_type *)*my_variable)->Param2.body + 1)"
instead of "strlen(((my_type *)*my_variable)->Param2.body) + 1"
as an argument to "malloc" might be an under-allocation.
Now, given the strlen function call, which looks like this:
strlen(&((my_type*) *my_variable)->Param2.body[1])
and this line is identical to:
strlen(&((my_type*) *my_variable)->Param2.body + 1)
So this should be changed according to the message, and the result would be:
body = malloc((strlen(&((my_type*) *my_variable)->Param2.body)+1) +1);
Why is bad such an argument for malloc? I do not see what is the actual problem here so I am unsure about this solution and/or its necessity.
Additional information is that, &((my_type*) *my_variable)->Param2.body[1] (simply &Param2.body[1]) will be copied into body using strcpy, like:
strcpy(body, &((my_type *) *my_variable)->Param2.body[1]);
No, ...body[1] and ...body + 1 are not identical. The first has a type that is the element type of the body array, the second has type ptr-to-element-type. Read your C book again :-)
Coverity tries to tell you that you make the same error as in
char foo[42];
/* write a string to foo */
bar = malloc (strlen(foo + 1)); /* which is strlen(&foo[1]) */
when the correct code is
bar = malloc (strlen(foo) + 1);
I think you misunderstood the paranthesis.
The + 1 in the coverity suggestion is outside the strlen(...)
I think coverity gets worried because you want to take strlen from index 1 instead of index 0. Coverity would expect index 0 as starting point - like:
body = malloc(strlen(&((my_type*) *my_variable)->Param2.body[0]) +1);
^
which is also
body = malloc(strlen(((my_type*) *my_variable)->Param2.body) +1);
^ ^
No & operator No [0]
as suggested by coverity
I have reached that conclusion #rici was correct. Considering the following simulation:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct Param2{
char* body;
}Param2;
int main()
{
Param2 test;
test.body = "test_string\0";
printf("%s, size: %d + 1 terminating null\n\n",test.body, strlen(test.body));
printf("original: %d \n", (strlen(&test.body[1]) + 1));
printf("what coverity thinks: %d \n", strlen(test.body + 1));
printf("what coverity suggests: %d \n", (strlen(test.body) + 1));
printf("a more transparent way: %d \n\n", (strlen(test.body + 1) + 1));
return 1;
}
This is the output:
There are three cases (4th is the same as 1st). The allocated memory can be seen on the image above for all cases. Now, if we want to copy the source string from the 2. byte (&body[1]), that would mean 10 bytes of data in the example. And according to the strcpy documentation:
To avoid overflows, the size of the array pointed by destination shall
be long enough to contain the same C string as source (including the
terminating null character), and should not overlap in memory with
source.
We need one more for the null termination giving us 11 bytes to be allocated. Coverity believes that we are allocating 10 bytes, and suggest to allocate 12.
But as we can see, the original code allocates 11 bytes which is the exact number of bytes we need here, making the coverity deflect false positive.

Printing int values with a user determined padding? [duplicate]

This question already has answers here:
Set variable text column width in printf
(2 answers)
Closed 9 years ago.
I'm pretty sure there's no way to do this, but I was wondering, so here goes...
Say I get several int values from the user, and I know for a fact that the 1st
value is the largest.
Any way I can use the length of the first int value as the padding when printing
the rest of the numbers?
Browsing the forum I found that you can determine the length of an int (n) like
this:
l = (int) log10(n) + 1;
Using padding of 5 a print would look like:
printf("%5d", n);
So what I want to know is whether or not there's a way to use l instead of 5...
Thank you!
Do it like so:
int n = <some value>;
int i = (int) log10(n) + 1;
printf("%*d", i, n);
The * serves as a placeholder for the width being passed as an argument to printf().
You can use also snprintf() to get the number of characters printed for a value thus:
char buff[100];
int width = snprintf (buff, sizeof(buff), "%d", number1);
But, however you get the desired width, you can just use the * format modifier:
printf( "%*d %*d\n", width, number1, width, number2);
That modifier uses the next argument to specify a dynamic width rather than one fixed in the format string.

string to integer

I have made a program which converts numbers entered into a string into an integer like atoi does, but its giving wrong output.
#include<stdio.h>
#include<conio.h>
#include<math.h>
#include<string.h>
void main(void)
{
static int sum;
int i,x,y,z;
char string[10];
printf("Enter a string:\n");
gets(string);
x=strlen(string);
for(i=0; ;i++)
{
if(string[i]=='\0')
{
break;
}
y=pow(10,i);
z=string[x-i+1]*y;
sum+=z;
}
printf("%d",sum);
getch();
}
Ok. Here is a quick review of your code. Comments embedded.
#include<stdio.h>
Leave a space between #include and <stdio.h>.
#include<conio.h>
This is a non-standard Windows-only header that you don't need. Don't include this.
#include<math.h>
#include<string.h>
Again use a space, when including your headers.
void main(void)
While this is legal, it is more common to find the signature int main(int argc, char* argv[]) as the signature for the main function. I would suggest that you use that signature.
{
static int sum;
Why are you making this static? Are you planning to invoke main repeatedly and have the previous result for sum persist from one invocation of main to another? If not, then don't make it static.
int i,x,y,z;
char string[10];
Consider allocating more space for your string. Ten characters is quite small. Also consider creating a variable to represent the size of your string, rather than using a magic number, since you will likely have to reference the buffer size in multiple places.
printf("Enter a string:\n");
gets(string);
No. Don't do that!!! The function gets is a major security vulnerability!. It makes your program susceptible to buffer overflow attacks. Instead, use fgets, and specify the size of the buffer that you want to fill, so that it doesn't overrun your buffer. You should never, ever use plain gets.
x=strlen(string);
Consider choosing a more descriptive name for x. Perhaps len. It is perfectly ok (and good) to create variables that have identifiers longer than a single letter.
for(i=0; ;i++)
{
if(string[i]=='\0')
{
break;
}
Consider putting the termination condition in the for-loop; for(i = 0; string[i]!='\0'; i++).
y=pow(10,i);
z=string[x-i+1]*y;
Hint: there is a smarter way to do this than using pow.
sum+=z;
}
printf("%d",sum);
Ok. The above is fine, although you might want to use "%d\n".
getch();
You really shouldn't be doing this on all systems. Instead, do:
#ifdef _WIN32
system("pause");
#endif
If possible, though, I would suggest you avoid that weird pausing behavior. Suppose your professor uses an automated script to validate the output of your program. Putting any sort of pause in the program (even on Windows), will break such a script. If you don't want the terminal window to disappear while on Windows, you should invoke your program from the command prompt.
}
If you were to change the signature to something returning int as I suggested, then you would want to add the statement return 0; before the end of the function.
Your string do not contain the int values 0, 1, 2, ... 9.
They contain the char values '0', '1', '2', ... '9'. Encoded in e.g. ASCII, '0' == 48.
You need to convert the char to int; one way to do this is by subtracting '0', e.g.:
z = (string[x-i+1] - '0') * y;
Related questions
Please explain what this code is doing (someChar - 48)
How to convert a single char into an int
Language showdown: Convert string of digits to array of integers?
Many examples of digit conversion, using subtraction with both '0' and 48!
On Horner's Scheme
You can also do better by not using the pow, by using Horner scheme.
Here's an example (here ^ denotes exponentiation instead of bitwise-xor):
8675309 = 8*10^6 + 6*10^5 + 7*10^4 + 5*10^3 + 3*10^2 + 0*10^1 + 9*10^0
= (((((8*10 + 6)*10 + 7)*10 + 5)*10 + 3)*10 + 0)*10 + 9
It may look complicated at first, but it really isn't. You basically read the digits left to right, and you multiply your result so far by 10 before adding the next digit.
In table form:
step result digit result*10+digit
1 init=0 8 8
2 8 6 86
3 86 7 867
4 867 5 8675
5 8675 3 86753
6 86753 0 867530
7 867530 9 8675309=final
I'll leave you to implement this simple algorithm on your own, since this is homework.
See also
Wikipedia/Horner Scheme
Related questions
What does the ^ operator do in Java?
it should be:
z=(string[x-(i+1)]-'0')*y;

How can I get the sizes of various types in c?

I would like to know the size of following types in C,
sizeof(int), sizeof(float), sizeof(double), sizeof(char), sizeof(167), sizeof(3.1415926) and sizeof(‘$’).
Sure. You can use the following code. I'm answering in C since that's what the question asked for, despite the C# tag. If you really want C#, someone else will have to help.
#include <stdio.h>
int main (void) {
// Use %zu for size_t if your compiler supports it.
printf("sizeof(int) = %d\n",sizeof(int));
printf("sizeof(float) = %d\n",sizeof(float));
printf("sizeof(double) = %d\n",sizeof(double));
printf("sizeof(char) = %d\n",sizeof(char));
printf("sizeof(167) = %d\n",sizeof(167));
printf("sizeof(3.1415926) = %d\n",sizeof(3.1415926));
printf("sizeof('$') = %d\n",sizeof('$'));
return 0;
}
This outputs (on my system):
sizeof(int) = 4
sizeof(float) = 4
sizeof(double) = 8
sizeof(char) = 1
sizeof(167) = 4
sizeof(3.1415926) = 8
sizeof('$') = 4
Keep in mind that this gives you the values in terms of bytes which, under the C standard, are not necessarily 8 bits. You should examine CHAR_BITS from limits.h to see how many bits are in a byte.
Something like
#include <stdio.h>
int main()
{
printf("sizeof(int) = %ul\n", (unsigned long) sizeof(int));
}
with a lot of similar lines will do. Save, compile, and run.
One common mistake is printf("sizeof(int) = %d", sizeof(int));, but this is a mismatch. The result of sizeof() is size_t, which is an unsigned integral type that's big enough to hold any possible object size. The %d specifier asks for an int, which is a signed integral type that's convenient for calculation. It's not all that rare for size_t to be bigger than int, and then you're passing arguments of a size that the function doesn't expect, and that can be bad.
If it's a console application, you could use writeline that takes a string and displays it:
Console.WriteLine(sizeof(int));
Console.WriteLine(sizeof(int));
Console.WriteLine(sizeof(float));
Console.WriteLine(sizeof(double));
Console.WriteLine(sizeof(char));
Console.WriteLine(sizeof (167));
Console.WriteLine(sizeof(3.1415926));
Console.WriteLine(sizeof(‘$’));
I am not working on C from last three years. But following is the answer of your question.
You can print size of different data types as follows:
printf("Size of integer: %ul",sizeof(int));
printf("Size of float: %ul",sizeof(float));
printf("Size of double: %ul",sizeof(double));
printf("Size of char: %ul",sizeof(char));
printf("Size of 167: %ul",sizeof (167));
printf("Size of 3.1415926: %ul",sizeof(3.1415926));
printf("Size of integer: %ul",sizeof(‘$’));
Just paste above printf lines in your program. You will get the size of the datatypes.
Here sizeof() is a function which returns the total memory required to store that datatype or literal.

Resources