memcpy() to copy integer value to char buffer - c

I am trying to copy the memory value of int into the char buffer. The code looks like below,
#define CPYINT(a, b) memcpy(a, &b, 4)
............
char str1[4];
int i = 1;
CPYINT(str1, i);
printf("%s",s);
...........
When I print str1 it’s blank. Please clarify.

You are copying the byte representation of an integer into a char array. You then ask printf to interpret this array as a null terminating string : str1[0] being zero, you are essentially printing an empty string (I'm skipping the endianness talk here).
What did you expect ? Obviously, if you wanted to print a textual representation of the integer i, you should use printf("%d", i).

try
printf("%02X %02X %02X %02X\n", str1[0], str1[1], str1[2], str1[3]);
instead.
The binary representation of the integer 1, probably contains leading NULs, and so your current printf statement terminates earlier than you want.

What is your intention here? Right now you are putting arbitrary byte values into the char array, but then interpreting them as a string, as it happens the first byte is probably a zero (null) and hence your print nothing, but in all probability many of the characters will be unprintable, so printf is the wrong tool to use to check if the copy worked.
So, either: loop through the array and print the numeric value of each byte, %0xd might be useful for that or if your intention is actually to create a string representation of the int then you'll need a larger buffer, and space for a null terminator.

Maybe you need convert intger to char* in that way tou can use itoa function
link text

Related

error when printing special characters in C. The problem is %c vs %s

I'm starting with C, I have found a little difference between %c and %s, when must print special characters. I dont know if I'm doing something wrong, or it's a C limitation:
unsigned char str1[]="á";
printf("str1 c (%c)\n", str1[0]);
printf("str1 s (%s)\n", &str1[0]);
unsigned char str2[]="áéíóúñ";
printf("str2 s (%s)\n", str2);
And the output is:
str1 c ( )
str1 s (á)
str2 s (áéíóúñ)
In conclusion: when I try write special characters with %c, I cannot see it.
The %c format string for printf causes the corresponding argument to be converted to and interpreted as an unsigned char. An unsigned char is 1 byte long. One byte from your non-ASCII string does not necessarily correspond to anything you would recognize as a character.
It is likely that your editor, which you used to place some representation of those strings into your source code, encodes the two strings with some Unicode encoding scheme. This SO answer has some information to get you started on dealing with Unicode in C.
The reason things work fine with the %s formatting string is that printf will just start dumping out bytes until it hits the null byte terminator. Your output terminal is probably set to the same encoding scheme as your editor, so it's able to correctly interpret those bytes the way you intended.
Ok, now I understand it.
If I write:
unsigned char str3[]="a";
printf("%d\n", strlen((char *)str3));
The output is:
1
But I write:
unsigned char str1[]="á";
printf("%d\n", strlen((char *)str1));
The output is:
2
I understood that the character sizes can be 1, or 2 if are special characters , no?

Convert subsections of array of char to int

Is there a strtol() or sscanf() equivalent where you can specify the no. of chars to convert?
I have a use case where I need to convert sub sections of an array of chars to ints, so I don't have the terminating null char present
In other words, I'd like the equivalent of strncmp() in relation to strcmp()
i.e. strntol() or snscanf() but they don't seem to exist
I imagine i'll just have to copy and append a '\0' and use strtol() or sscanf() but just wanted to check I hadn't missed an existing function for this purpose
question is really do they exist? am i just searching for the wrong thing?
There is no equivalent for strtol, but you can use format specifier to limit the number of characters considered by sscanf:
char *str = "1234567890";
int n;
sscanf(&str[3], "%3d", &n);
printf("%d\n", n);
The %3d specifier instructs sscanf to take only three digits from str, while &str[3] tells sscanf to start at the index 3.
The above code prints 456 (demo).

can't read first character of array in c

I'm trying to read the characters of a character array by number in c. I've stripped the program down to isolate the problem. I know this is about my misunderstanding of how arrays and memory works and I am ready to be called clueless but I would like to know what I am misunderstanding here. Here is what I have:
#include <stdio.h>
int main(int argc, char **argv) {
char buffer[] = "stuff";
printf("buffer is %s\n", buffer);
printf("first character of buffer is %s", (char)buffer[0]);
return 0;
}
You have to write the correct format specifier. Now you used %s ...what happens?
It looks for an string which is null terminated. But it doesn't find one. So it simply cant put anything in the output . That's it.
Use %c instead.
In C there is a very big difference between a character and a string.
A character is simply a number in a range of 256 different options.
A string is not really a type of its own, it is merely an array of chars (which, in C, is simply evaluated as a pointer to the first character of the string).
Now, when you type buffer[0], this is evaluated to the value at the beginning of the string (first value in the array). Indeed, this is of char type (and therefore you do not need the (char) casting, because this will not do anything in the case of your code).
What you need is to tell printf() how to evaluate the input that you give it. %s is for a string (an array of chars). But note and remember that buffer[0] is not an array of chars, but rather a char.
So you actually want to use %c, instead of %s. This tells printf() to evaluate the parameter as a char type.
What your code currently does is take the value buffer[0] (which is just a number) and consider it as a pointer to a location in memory where a string is kept, and printf() tries to print this string. But this memory location is simply invalid. It is not a location you've accessed before.
In conclusion you want:
printf("first character of buffer is %c", (char)buffer[0]);
or even simpler:
printf("first character of buffer is %c", buffer[0]);
For other specifiers of the printf() function, look here:
http://www.tutorialspoint.com/c_standard_library/c_function_printf.htm
If you want to print only a single char use %c format.
printf("first character of buffer is %c\n", (char)buffer[0]);

Copying binary data with memcpy in c

I have the following problem when using memcpy:
Suppose that an hexadecimal data must be copied in binary, e.g.: 203800000E820006, then apply the following instruction:
unsigned char buffer[8];
memcpy(buffer,"\x20\x38\x00\x00\x0E\x82\x00\x06",8);
However, when I write the data in binary, it only prints the 2 first bytes in binary, because \x00 is interpreted as a string terminator. How to avoid or fix this in order to represent the 16-char string in a 8-char binary format?
The buffer you have is not a string. You can't treat it like one by passing it to functions expecting a string such as strcat, strcpy, strcmp, or the %s format specifier of printf.
You have an array of characters, so print them as such:
int i;
for (i=0;i<sizeof(buffer);i++) {
printf("%02hhX ", buffer[i]);
}
printf("\n");

Why does C's printf format string have both %c and %s?

Why does C's printf format string have both %c and %s?
I know that %c represents a single character and %s represents a null-terminated string of characters, but wouldn't the string representation alone be enough?
Probably to distinguish between null terminated string and a character. If they just had %s, then every single character must also be null terminated.
char c = 'a';
In the above case, c must be null terminated. This is my assumption though :)
%s prints out chars until it reaches a 0 (or '\0', same thing).
If you just have a char x;, printing it with printf("%s", &x); - you'd have to provide the address, since %s expects a char* - would yield unexpected results, as &x + 1 might not be 0.
So you couldn't just print a single character unless it was null-terminated (very inefficent).
EDIT: As other have pointed out, the two expect different things in the var args parameters - one a pointer, the other a single char. But that difference is somewhat clear.
The issue that is mentioned by others that a single character would have to be null terminated isn't a real one. This could be dealt with by providing a precision to the format %.1s would do the trick.
What is more important in my view is that for %s in any of its forms you'd have to provide a pointer to one or several characters. That would mean that you wouldn't be able to print rvalues (computed expressions, function returns etc) or register variables.
Edit: I am really pissed off by the reaction to this answer, so I will probably delete this, this is really not worth it. It seems that people react on this without even having read the question or knowing how to appreciate the technicality of the question.
To make that clear: I don't say that you should prefer %.1s over %c. I only say that reasons why %c cannot be replaced by that are different than the other answer pretend to tell. These other answers are just technically wrong. Null termination is not an issue with %s.
The printf function is a variadic function, meaning that it has variable number of arguments. Arguments are pushed on the stack before the function (printf) is called. In order for the function printf to use the stack, it needs to know information about what is in the stack, the format string is used for that purpose.
e.g.
printf( "%c", ch ); tells the function the argument 'ch'
is to be interpreted as a character and sizeof(char)
whereas
printf( "%s", s ); tells the function the argument 's' is a pointer
to a null terminated string sizeof(char*)
it is not possible inside the printf function to otherwise determine stack contents e.g. distinguishing between 'ch' and 's' because in C there is no type checking during runtime.
%s says print all the characters until you find a null (treat the variable as a pointer).
%c says print just one character (treat the variable as a character code)
Using %s for a character doesn't work because the character is going to be treated like a pointer, then it's going to try to print all the characters following that place in memory until it finds a null
Stealing from the other answers to explain it in a different way.
If you wanted to print a character using %s, you could use the following to properly pass it an address of a char and to keep it from writing garbage on the screen until finding a null.
char c = 'c';
printf('%.1s', &c);
For %s, we need provide the address of string, not its value.
For %c, we provide the value of characters.
If we used the %s instead of %c, how would we provide a '\0' after the characters?
Id like to add another point of perspective to this fun question.
Really this comes down to data typing. I have seen answers on here that state that you could provide a pointer to the char, and provide a
"%.1s"
This could indeed be true. But the answer lies in the C designer's trying to provide flexibility to the programmer, and indeed a (albeit small) way of decreasing footprint of your application.
Sometimes a programmer might like to run a series of if-else statements or a switch-case, where the need is to simply output a character based upon the state. For this, hard coding the the characters could indeed take less actual space in memory as the single characters are 8 bits versus the pointer which is 32 or 64 bits (for 64 bit computers). A pointer will take up more space in memory.
If you would like to decrease the size through using actual chars versus pointers to chars, then there are two ways one could think to do this within printf types of operators. One would be to key off of the .1s, but how is the routine supposed to know for certain that you are truly providing a char type versus a pointer to a char or pointer to a string (array of chars)? This is why they went with the "%c", as it is different.
Fun Question :-)
C has the %c and %s format specifiers because they handle different types.
A char and a string are about as different as night and 1.
%c expects a char, which is an integer value and prints it according to encoding rules.
%s expects a pointer to a location of memory that contains char values, and prints the characters in that location according to encoding rules until it finds a 0 (null) character.
So you see, under the hood, the two cases while they look alike they have not much in common, as one works with values and the other with pointers. One is instructions for interpreting a specific integer value as an ascii char, and the other is iterating the contents of a memory location char by char and interpreting them until a zero value is encountered.
I have done a experiment with printf("%.1s", &c) and printf("%c", c).
I used the code below to test, and the bash's time utility the get the runing time.
#include<stdio.h>
int main(){
char c = 'a';
int i;
for(i = 0; i < 40000000; i++){
//printf("%.1s", &c); get a result of 4.3s
//printf("%c", c); get a result of 0.67s
}
return 0;
}
The result says that using %c is 10 times faster than %.1s. So, althought %s can do the job of %c, %c is still needed for performance.
Since no one has provided an answer with ANY reference whatsoever, here is a printf specification from pubs.opengroup.com which is similar to the format definition from IBM
%c
The int argument shall be converted to an unsigned char, and the resulting byte shall be written.
%s
The argument shall be a pointer to an array of char. Bytes from the array shall be written up to (but not including) any terminating null byte. If the precision is specified, no more than that many bytes shall be written. If the precision is not specified or is greater than the size of the array, the application shall ensure that the array contains a null byte.

Resources