c printf size_t - c

My code compiles, though the printf doesn't display anything?
If I take out the formatter part of the printf then it works just fine.
#include <stdio.h>
size_t MyStrlen(const char *s1)
{
const char *s1Copy = s1;
while (*s1)
{
*s1Copy++;
}
return s1Copy -s1;
}
int main(void)
{
const char str[] = "HELLO";
printf("Length: %d \n", (unsigned int)MyStrlen(str));
return 0;
}

In your loop test you want to test *s1Copy for non-NULL, not *s1, which you aren't incrementing. As it is, since *s1 never changes, you're walking right off the end of your string argument with s1Copy++ and the code won't terminate normally.
Unless of course you pass the empty string: your MyStrlen method will work for the empty string.
while (*s1Copy)
s1Copy++;

This:
printf("Length: %d \n", (unsigned int)MyStrlen(str));
is ok; %d expects an int argument, but it's guaranteed that int and unsigned int have the same representation for values that are in the range of both. This:
printf("Length: %u\n", (unsigned int)MyStrlen(str));
is better, since %u expects an unsigned int argument.
The correct format for size_t is "%zu":
printf("Length: %zu\n", MyStrlen(str));
but this is a "new" feature in C99, and there are likely still some implementations that don't support it. (In particular, Microsoft has been very slow to support C99.) For maximum portability (assuming your string is no more than 232-1 bytes long) you can use this:
printf("Length: %lu\n", (unsigned long)MyStrlen(str));
This answers the question you asked about printf; pb2q ably diagnosed the actual cause of the problem you're seeing (and beat me to it!).

Related

Newline Constants in C

My code:
#include <stdio.h>
int main() {
const int LENGTH = 10;
const int WIDTH = 5;
const char NEWLINE ='\n';
int area;
area = LENGTH * WIDTH;
printf("value of area : %d", area);
printf("%c", NEWLINE);
return 0;
}
In the above code the output:
value of area: 50
Process returned 0 (0x0) execution time : 2.909 s
Press any key to continue.
There is a new line inserted, but when I change NEWLINE="\n" despite knowing it is a char type, there is no error prompted by the compiler and no newline printed out. Why???
Also, I modified my code as,
#include <stdio.h>
int main() {
const int LENGTH = 10;
const int WIDTH = 5;
const char NEWLINE ='\n';
const char k="hjk";
int area;
area = LENGTH * WIDTH;
printf("value of area : %d", area);
printf("%c", NEWLINE);
printf("%c", k);
return 0;
}
The output is only the area calculated and the new line but k is not printed out. I also find this very weird! Can you please give suggestions?
Please be kind enough with the suggestions and point out my mistakes because I am a beginner at C.
The problem is that you are trying to save a string as a char, so you have to change const char k = "hjk" to const char k[]="hjk" and print it using %s instead of %c.
#include<stdio.h>
int main() {
const int LENGTH = 10;
const int WIDTH = 5;
const char NEWLINE ='\n';
const char k[]="hjk";
int area;
area = LENGTH * WIDTH;
printf("value of area : %d", area);
printf("%c", NEWLINE);
printf("%s", k);
return 0;
}
Some clarification: if you save a "string" without specifying that it is an array of characters char[], if you try to print it as a char %c a warning would be generater (warning: incompatible pointer to integer conversion initializing 'const char' with an expression of type 'char [4]') and if you try to print it as a array of characters %s (string) you are going to receive a segmentation fault.
when I change NEWLINE="\n" despite knowing it is a char type, there is no error prompted by the compiler
const char NEWLINE = "\n"; is invalid C. The reason why it is invalid is explained in detail here: "Pointer from integer/integer from pointer without a cast" issues
The compiler is not required to produce an "error", but it is required to produce some sort of diagnostic message. See What must a C compiler do when it finds an error?
Why your compiler decided to spew out a binary regardless of getting fed invalid C is anyone's guess. You have to ask the people who made the compiler. In case of gcc, you won't find an answer, because this is completely undocumented behavior.
And therefore, any output you get from such a "non C" program is also completely non-deterministic, unless a compiler documented the behavior among non-standard compiler extensions. gcc did not.
Similarly, const char k="hjk"; is also invalid C.
k seems an array of char.
Try to use:
const char k[] = "something";
printf("%s", k);
The statement const char k="hjk"; is not valid C code. Apparently, your compiler accepts it and assigns the memory address where the literal string "hjk" begins to k. Both a memory address and a char are implemented as integer numbers, so the memory address is interpreted as the numeric code for a character.
Because k is now, most likely, an unprintable character, printf("%c", k); will print nothing.
Exactly the same happens when you do const char NEWLINE ='\n';.

sprintf can't change static variable inside printf call

I can't seem to understand what exactly is going on here
#include <stdio.h>
const char* mes(int a)
{
static char mess[100];
sprintf(mess, "%d", a);
return mess;
}
const int* hes(int a)
{
static int arr[100];
arr[0] = a;
return arr;
}
int main()
{
printf("%s %s\n", mes(55), mes(25)); //55 55
printf("%s\n", mes(55)); //55
printf("%s\n", mes(25)); //25
printf("%d %d\n", hes(55)[0], hes(25)[0]); //55 25
}
In the first printf the second function seems to be ignored and the output of the earlier input gets printed again.
At first I assumed it was a static variable issue, so I tried printing them separately and then they seem to work fine.
Then I assumed it was a printf issue so I tried to simulate the same behavior with an integer array, and it worked fine there too.
I've run this program a couple of times with various inputs, ruling out the possibility of UB.
So, what exactly am I missing here?
EDIT:
I encountered this issue somewhere else and couldn't understand what was happening. So I reproduced the issue in a short sample code. But my question stands, (as many have mentioned) are all the parameters evaluated before printing? If so there should be an overwrite in both cases (int and char array) regardless of evaluation order.
The order of evaluation of function parameters is unspecified, meaning that you can theoretically see 25 25 instead. That's first thing.
Second, when printf is called, both functions have been already evaluated, and the same pointer is passed as first and the second string (because it is a static location), which is the result of the last evaluation (55 in your case). So identical text is printed.
This is pretty much equivalent to the following:
char* a = mes(25);
char* b = mes(55);
// Note, the above can swap depending on the order of evaluation
printf("%s %s\n", a, b);
But here a equals b as both are pointing to a static array.
As for the second example this is not happening as it will be equivalent to the following (up to the order of evaluation):
int *ap = hes(55);
int a = ap[0];
int *bp = hes(25);
int b = bp[0];
printf("%d %d\n", a, b);
Note, that here the pointed values are passed and not the pointer itself. So even though ap equals bp, a is not the same as b.
The why code is wrong is well explained by others.
An alternative to static char mess[100] is to use a compound literal as an argument. Then the return value from mes(), hes() is valid until the end of the block of code - well after the printf().
#include <stdio.h>
const char* mes_helper(char mess[100], int a) {
sprintf(mess, "%d", a);
return mess;
}
const int* hes_helper(int arr[100], int a) {
arr[0] = a;
return arr;
}
// compound literal v-------------v
#define mes(a) mes_helper( (char [100]){0}, (a))
#define hes(a) hes_helper( (int [100]){0}, (a))
// No changes to `main() code
int main(void) {
printf("%s %s\n", mes(55), mes(25)); //55 55
printf("%s\n", mes(55)); //55
printf("%s\n", mes(25)); //25
printf("%d %d\n", hes(55)[0], hes(25)[0]); //55 25
}
Output
55 25
55
25
55 25
There is only one variable mess.
When you call:
printf("%s %s\n", mes(55), mes(25));
You are filling in that one variable two different times, once with "25" and once with "55" (overwriting the "25"). As a result, when printf goes to format with %s %s, it finds the same string twice, "55" and again "55" because the "25" has already been overwritten.
You need to be aware that all parameters to a function are evaluated before the function is called. The order of parameter evaluation is not defined, but is often right-to-left. Breaking down that printf into little steps:
Evaluate the mes(25); now static char mess is now "25".
Evaluate the mes(55), now static char mess is overwritten to "55".
Evaluate the parameter "%s %s\n" (there isn't much to evaluate here. Its just a string)
Call printf with parameters: "%s %s\n", and "55" and "55"
When you call:
printf("%s %s\n", mes(55), mes(25));
mes(55) and mes(25) get evaluated before their result is populated into the string. And since you're pointing to the same static memory, when it's time to populate the string, you get the same value.
Returning the address of a static variable is almost always a bad pattern as you'e found. There's only one such static allocation for the whole program, so for example calling mes twice causes the second call to overwrite the results of the first.
A more reasonable pattern is having the caller furnish a buffer. This is also needed for thread safety:
#include <stdio.h>
const char* mes(char *buf, int a)
{
sprintf(buf, "%d", a);
return buf;
}
const int* hes(int *arr, char *buf, int a)
{
arr[0] = a;
return arr;
}
int main()
{
char buf1[100], buf2[100];
int arr[100];
printf("%s %s\n", mes(buf1, 55), mes(buf2, 25)); //55 55
printf("%s\n", mes(buf1, 55)); //55
printf("%s\n", mes(buf1, 25)); //25
printf("%d %d\n", hes(arr, 55)[0], hes(arr, 25)[0]); //55 25
}

Printing integers passed as arguments in function in C

I am very new to C programming and having trouble compiling what should be a very simple function. The function, called printSummary, simply takes 3 integers as arguments, then prints some text along with those integers. For example, if hits=1, misses=2, and evictions=3, then printSummary(hits,misses,evictions) should print the following:
hits:1 misses:2 evictions:3
Here is the code I'm using. Thanks in advance for any advice.
#include<stdio.h>
void printSummary(int hits, int misses, int evictions)
{
printf('hits: %d\n');
printf('misses: %d\n');
printf('evictions: %d\n');
}
int main()
{
int hit_count = 1;
int miss_count = 2;
int eviction_count = 3;
printSummary(hit_count, miss_count, eviction_count);
return 0;
}
Compiling this code gives me several warnings, but no errors. When I run the code, I get a segmentation fault. Like I said, I am fairly new to C so there is most likely a simply solution that I am just missing. Thanks in advance for any advice.
Make the below changes .
printf("hits: %d\n",hits);
printf("misses: %d\n",misses);
printf("evictions: %d\n",evictions);
printf has a
int printf(const char *format, ...)
prototype. So in the first argument you can pass format specifiers and in the next provide the actual variables/values to be printed out
errors are:
void printSummary(int hits, int misses, int evictions)
{
/* Name: printf
Prototype: int printf (const char *template, ...)
Description:
The printf function prints the optional arguments under the
control of the template string template to the stream stdout.
It returns the number of characters printed,or a negative value if
there was an output error.*/
printf("hits: %d\n", hits); // don't use ' it is used only for char variable for example: char a = 'c';
printf("misses: %d\n", misses);
printf("evictions: %d\n", evictions);
}
Your printf function is not being called correctly. You have to include the integers needed to print:
printf("hits: %d\n", hits);
printf("misses: %d\n", misses);
printf("evictions: %d\n", evictions);
Read more about the printf function here.

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]);
}

LLVM Compiler 2.0 bug?

When the following code is compiled with LLVM Compiler, it doesn't operate correctly.
(i doesn't increase.)
It operates correctly when compiling with GCC 4.2.
Is this a bug of LLVM Compiler?
#include <stdio.h>
#include <string.h>
void BytesFromHexString(unsigned char *data, const char *string) {
printf("bytes:%s:", string);
int len = (int)strlen(string);
for (int i=0; i<len; i+=2) {
unsigned char x;
sscanf((char *)(string + i), "%02x", &x);
printf("%02x", x);
data[i] = x;
}
printf("\n");
}
int main (int argc, const char * argv[])
{
// insert code here...
unsigned char data[64];
BytesFromHexString(data, "4d4f5cb093fc2d3d6b4120658c2d08b51b3846a39b51b663e7284478570bcef9");
return 0;
}
For sscanf you'd use %2x instead of %02x. Furthermore, %2x indicates that an extra int* argument will be passed. But you're passing an unsigned char*. And finally, sscanf takes a const char* as first argument, so there's no need for that cast.
So give this a try :
int x;
sscanf((string + i), "%2x", &x);
EDIT : to clarify why this change resolves the issue : in your code, sscanf tried to write sizeof(int) bytes in a memory location (&x) that could only hold sizeof(unsigned char) bytes (ie. 1 byte). So, you were overwriting a certain amount of memory. This overwritten memory could very well have been (part of) the i variable.
From the compiler side of things the reason for this code behaving differently is that gcc and llvm (or any other compiler) may lay out the stack differently. You were likely just clobbering something else on the stack before that you didn't need for this example, but with the different layout for the llvm compiler you were clobbering something more useful.
This is another good reason to use stack protectors when debugging a problem (-fstack-protector-all/-fstack-protector). It can help flush out these issues.

Resources