How to do hex8 encoding in c? - c

I am trying to encode a string in hex8 using c. The script I have right now is:
int hex8 (char str) {
str = printf("%x", str);
if(strlen(str) == 1) {
return printf("%s", "0", str);
} else {
return str;
}
}
In this function, I will need to add a 0 ahead of the string if the length is less than 1. I don't know why I'm getting:
passing argument 1 of 'strlen' makes pointer from integer without a cast
Does anyone know why?

I don't know exactly what hex8 encoding is, but it looks like you're trying to turn a char into a two-byte hex string? In that case, you don't need anything as complicated as you have there. Just do something like this:
char hexstring[3];
char character = 'f';
sprintf(hexstring, "%02x", character);
After that code fragment, hexstring will be "66". If you have a whole string, something like this should work (assuming you've allocated appropriate memory before calling the function):
void string2hex(char *hex, char *in)
{
while (*in)
{
hex += sprintf(hex, "%02x", *in);
in++;
}
}

The second line is a problem:
str = printf("%x", str);
printf outputs text to stdout, and returns an integer representing the number of characters that it output, not the actual value that was printed. You should replace this line with a call to sprintf instead, to load the output into str:
sprintf(str, "%x", str);
You can read about the various standard output functions here: Formatted Output Functions
Note that sprintf returns the number of characters that it stored into str, so you can actually use this to check whether you need to add the 0, instead of using strlen at all, like this:
if (sprintf(str, "%x", str) == 1)
{
...

The parameter str is a char. strlen expects a char const * argument. From the context it would seem you need to change the prototype to char *str.
EDIT: You will also need to change the function return type to char *.

Related

Usage of pointers as parameters in the strcpy function. Trying to understand code from book

From my book:
void strcpy (char *s, char *t)
{
int i=0;
while ((s[i] = t[i]) != ’\0’)
++i;
}
I'm trying to understand this snippet of code from my textbook. They give no main function so I'm trying to wrap my head around how the parameters would be used in a call to the function. As I understand it, the "i-number" of characters of string t[ ] are being copied to the string s[ ] until there are no longer characters to read, from the \0 escape sequence. I don't really understand how the parameters would be defined outside of the function. Any help is greatly appreciated. Thank you.
Two things to remember here:
Strings in C are arrays of chars
Arrays are passed to functions as pointers
So you would call this like so:
char destination[16];
char source[] = "Hello world!";
strcpy(destination, source);
printf("%s", destination);
i is just an internal variable, it has no meaning outside the strcpy function (it's not a parameter or anything). This function copies the entire string t to s, and stops when it sees a \0 character (which marks the end of a string by C convention).
EDIT: Also, strcpy is a standard library function, so weird things might happen if you try to redefine it. Give your copy a new name and all will be well.
Here's a main for you:
int main()
{
char buf[30];
strcpy(buf, "Hi!");
puts(buf);
strcpy(buf, "Hello there.");
puts(buf);
}
The point of s and t are to accept character arrays that exist elsewhere in the program. They are defined elsewhere, at this level usually by the immediate caller or one more caller above. Their meanings are replaced at runtime.
Your get compile problems because your book is wrong. Should read
const strcpy (char *s, const char *t)
{
...
return s;
}
Where const means will not modify. Because strcpy is a standard function you really do need it to be correct.
Here is how you might use the function (note you should change the function name as it will conflict with the standard library)
void my_strcpy (char *s, char *t)
{
int i=0;
while ((s[i] = t[i]) != ’\0’)
++i;
}
int main()
{
char *dataToCopy = "This is the data to copy";
char buffer[81]; // This buffer should be at least big enough to hold the data from the
// source string (dataToCopy) plus 1 for the null terminator
// call your strcpy function
my_strcpy(buffer, dataToCopy);
printf("%s", buffer);
}
In the code, the i variable is pointing to the character in the character array. So when i is 0 you are pointing to the first character of s and t. s[i] = t[i]copies the i'th character from t to the i'th character of s. This assignment in C is self an expression and returns the character that was copied, which allows you to compare that to the null terminator 0 ie. (s[i] = t[i]) != ’\0’ which indicates the end of the string, if the copied character is not a null terminator the loop continues otherwise it will end.

C - Freshly allocated char* contains existing data

C programming newbie here...
I have a function which does some maths and stores the result in an output variable:
void myFunction(char* output) {
unsigned char myData[64]={0};
// Call to another function which fills the 'myData' array
compute(myData);
// Now let's format the result in our output variable
for (int n=0; n<64; n++) {
sprintf(output, "%s%02x", myData[n]);
}
}
The output char array is allocated by the caller in a variable called result:
void main(void) {
char* result = NULL;
result = malloc(129 * sizeof(unsigned char)); // twice the size of myData + 1 ending byte
myFunction(result);
// process result here
// (...)
free(result);
}
Problem is I always get some garbage stuff at the beginning of result, for instance:
���˶ang/String;8fb5ab60ed2b2c06fa43d[...]
Here the expected data starts at 8fb5ab60ed2b2c06fa43d. After doing some logs, I know that result already contains ���˶ang/String; before the sprintf() loop.
I don't understand how this can occur: isn't the malloc() function supposed to reserve memory for my variable? I guess this garbage comes from another memory area, which will eventually lead to some funky behavior...
That said, I've found a workaround just by adding a null ending byte at the 1st position of result, before calling the function:
result[0]='\0'; // initialisation
myFunction(result);
Now it works perfectly but I highly doubt that's good practice... Any advice?
Here's your problem:
for (int n=0; n<64; n++) {
sprintf(output, "%s%02x", myData[n]);
}
Your format specifier to sprintf expects a char * followed by an unsigned int. You're only passing in an unsigned char (which is converted to an int), so this character value is being interpreted as an address. Using the wrong format specifier to sprintf invokes undefined behavior.
It looks like you were attempting to append to output. The way to do that would be to only include the %02x format specifier, then on each loop iteration increment the pointer value output by 2 so that the next write happens in the correct place:
for (int n=0; n<64; n++, output+=2) {
sprintf(output, "%02x", myData[n]);
}

How to use a pointer to point only at half of an array

I'm new to C and pointers, so i have this problem. I want to tell to pointer how much memory it should point to.
char * pointer;
char arr[] = "Hello";
pointer = arr;
printf("%s \n", pointer);
This pointer will point to whole array, so i will get "Hello" on the screen. My question is how can i make pointer to only get "Hel".
You may try this:
char * pointer;
char arr[] = "Hello";
pointer = arr;
pointer[3] = '\0'; // null terminate of string
printf("%s \n", pointer);
If you always work with strings, then have a look at strlen for getting length of a string. If a string arr has length l, then you may set arr[l/2] = '\0', so that when you print arr, only its first half will be shown.
You may also want to print the last half of your string arr? You can use pointer to point to any place you want as the start. Back to your example, you may try:
char * pointer;
char arr[] = "Hello";
pointer = arr + 2; // point to arr[2]
printf("%s \n", pointer);
Have a check what you will get.
printf has the ability to print less than the full string, using the precision value in the format string. For a fixed number of characters (e.g. 3), it's as simple as
printf( "%.3s\n", pointer );
For a variable number of characters, use an asterisk for the precision, and pass the length before the pointer
int length = 3;
printf( "%.*s\n", length, pointer );
You don't know what a pointer is so I'll explain.
A pointer does not point to a string. It points to a char! Yes, a char. A string in C is really just a set of chars all one after the other in the memory.
A char* pointer points to the beginning of a string. The string ends when there is a '\0' (aka null) char. When you printf("%s",s), what printf does is a cycle like this:
int i;
for(i=0;1;i++) //infinite cycle
{
if(s[i]=='\0')
break;
printf("%c",s[i]);
}
Meaning it will not print a string but all the chars in a char array until it finds a null char or it goes into memory space that is not reserved to it (Segmentation fault).
To print just the 1st 3 characters you could do something like this:
void printString(char* s,int n) //n=number of characters you want to print
{
if(n>strlen(s))
n=strlen(s);
else if(n<0)
return;
char temp=s[n]; //save the character that is in the n'th position of s (counting since 0) so you can restore it later
s[n]='\0'; //put a '\0' where you want the printf to stop printing
printf("%s",s); //print the string until getting to the '\0' that you just put there
s[n]=temp; //restore the character that was there so you don't alter the string
}
Also, your declaration of pointer is unnecessary because it is pointing to the exact same position as arr. You can check this with printf("%p %p\n",arr,pointer);
How much of the string is printed is controlled by the NULL-character "\0", which C automatically appends to every string. If you wish to print out just a portion, either override a character in the string with a "\0", or use the fwrite function or something similar to write just a few bytes to stdout.
You could achieve the objective with a small function, say substring.
#include<stdio.h>
#include<string.h> // for accessing strlen function
void substring(char* c,int len)
{
if (len <= strlen(c)){
*(c+len)='\0';
printf("%s\n",c);
}
else{
printf("Sorry length, %d not allowed\n",len);
}
}
int main(void)
{
char c[]="teststring";
char* ptr=c;
substring(ptr,4); // 4 is where you wish to trim the string.
return 0;
}
Notes:
In C++ a built-in function called substring is already available which shouldn't be confused with this.
When a string is passed to a function like printf using a format specifier %s the function prints all the characters till it reaches a null character or \0. In essence, to trim a string c to 4 characters means you put c[4] to null. Since the count starts from 0, we are actually changing the 5th character though. Hope the example makes it more clear.

Removing character from array using strchr, does not return right value in plain C

I am trying to remove first semicolon from a character arrary whose value is:
Input: ; Test: 876033074, 808989746, 825766962, ; Test1:
825766962,
Code:
char *cleaned = cleanResult(result);
printf("Returned BY CLEAN: %s\n",cleaned);
char *cleanResult(char *in)
{
printf("Cleaning this: %s\n",in);
char *firstOccur = strchr(in,';');
printf("CLEAN To Remove: %s\n",firstOccur);
char *restOfArray = firstOccur + 2;
printf("CLEAN To Remove: %s\n",restOfArray); //Correct Value Printed here
char *toRemove;
while ((toRemove = strstr(restOfArray + 2,", ;"))!=NULL)
{
printf("To Remove: %s\n",toRemove);
memmove (toRemove, toRemove + 2, strlen(toRemove + 2));
printf("Removed: %s\n",toRemove); //Correct Value Printed
}
return in;
}
Output (first semicolon still there): ; Test: 876033074,
808989746, 825766962; Test1: 825766962;
Regarding sizeof(cleaned): using sizeof to get the capacity of an array only works if the argument is an array, not a pointer:
char buffer[100];
const char *pointer = "something something dark side";
// Prints 100
printf("%zu\n", sizeof(buffer));
// Prints size of pointer itself, usually 4 or 8
printf("%zu\n", sizeof(pointer));
Although both a local array and a pointer can be subscripted, they behave differently when it comes to sizeof. Thus, you cannot determine the capacity of an array given only a pointer to it.
Also, bear this in mind:
void foo(char not_really_an_array[100])
{
// Prints size of pointer!
printf("%zu\n", sizeof(not_really_an_array));
// Compiles, since not_really_an_array is a regular pointer
not_really_an_array++;
}
Although not_really_an_array is declared like an array, it is a function parameter, so is actually a pointer. It is exactly the same as:
void foo(char *not_really_an_array)
{
...
Not really logical, but we're stuck with it.
On to your question. I'm unclear on what you're trying to do. Simply removing the first character of a string (in-place) can be accomplished with a memmove:
memmove( buffer // destination
, buffer + 1 // source
, strlen(buffer) - 1 // number of bytes to copy
);
This takes linear time, and assumes buffer does not contain an empty string.
The reason strcpy(buffer, buffer + 1) won't do is because the strings overlap, so this yields undefined behavior. memmove, however, explicitly allows the source and destination to overlap.
For more complex character filtering, you should consider traversing the string manually, using a "read" pointer and a "write" pointer. Just make sure the write pointer does not get ahead of the read pointer, so the string won't be clobbered while it is read.
void remove_semicolons(char *buffer)
{
const char *r = buffer;
char *w = buffer;
for (; *r != '\0'; r++)
{
if (*r != ';')
*w++ = *r;
}
*w = 0; // Terminate the string at its new length
}
You are using strcpy with overlapping input / output buffer, which results in undefined behavior.
You're searching for a sequence of three characters (comma space semicolon) and then removing the first two (the comma and the space). If you want to remove the semicolon too, you need to remove all three characters (use toRemove+3 instead of toRemove+2). You also need to add 1 to the strlen result to account for the NUL byte terminating the string.
If, as you say, you just want to remove the first semicolon and nothing else, you need to search for just the semicolon (which you can do with strchr):
if ((toRemove = strchr(in, ';')) // find a semicolon
memmove(toRemove, toRemove+1, strlen(toRemove+1)+1); // remove 1 char at that position

Append formatted string to string in C without pointer arithmetic

I wrote a very simple C function to illustrate what I would like to simplify:
void main(int argc, char *argv[])
{
char *me = "Foo";
char *you = "Bar";
char us[100];
memset(us, 100, 0x00);
sprintf(us, "You: %s\n", you);
sprintf(us + strlen(us), "Me: %s\n", me);
sprintf(us + strlen(us), "We are %s and %s!\n", me, you);
printf(us);
}
Is there a standard library function to handle what I'm doing with sprintf and advancing the pointer?
sprintf returns the number of non-NUL characters written.
int len = 0;
len += sprintf(us+len, ...);
len += sprintf(us+len, ...);
...
char *me="Foo";
char *you="Bar";
char us[100];
char* out = us;
out += sprintf(out,"You: %s\n",you);
out += sprintf(out,"Me: %s\n",me);
out += sprintf(out,"We are %s and %s!\n",me,you);
printf("%s", us);
You could just use something like this:
sprintf(us, "You: %s\nMe: %s\nWe are %s and %s!\n", you, me, me, you);
You are probably looking for strcat (or even better strncat).
Never use a non-constant string as the first argument to printf (or second argument to fprintf. This is bad practice. Try changing the me variable to "Muahaha %n%d%n%d%n%d%n%d%n" and say goodbye to your stack and say hello to SEGFAULT. printf will try and format the string but you haven't provided any arguments for it to deal with, and even though there are format specifiers in the string printf has no idea that you haven't given it any arguments.
If you want to output a 'pre-formatted' string, use fputs(str,stdout). There is rarely a case to use printf with a non-constant format string.

Resources