How to write a word at a time to *char? - c

I'm trying to implement a version of memset to write a word at a time instead of byte-by-byte.
The code I'm currently working with is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* set in memory one word at a time
dest: destination
ch: the character to write
count: how many copies of ch to make in dest */
void wmemset(char *dest, int ch, size_t count) {
long long int word; // 64-bit word
unsigned char c = (unsigned char) ch; // explicit conversion
int i, loop, remain;
for (i = 0, word = 0; i < 8 ; ++i) {
word |= ((long long int)c << i * 8);
}
loop = count / 8;
remain = count % 8;
for (i = 0; i < loop; ++i, dest += 8) {
*dest = word; // not possible to set 64-bit to char
}
for (i = 0; i < remain; ++i, ++dest) {
*dest = c;
}
}
int main() {
char *c;
c = (char *) malloc(100);
wmemset(c, 'b', 100);
for (int i = 0; i < 100; i++)
printf("%c", c[i]);
}
I thought the 64-bit word would overflow to the rest of the byte of the pointer but it doesn't seem so.
How do I set one word at a time?
EDIT: added a few more comments and added main function.

Related

How to convert to binary as string in code C

I am trying to convert int to binary as string but I can not.
Please help me. How to convert integer to binary, please tell me.
Input: 32
Output: 00100000
My code:
#include <stdio.h>
#include <string.h>
char converttobinary(int n)
{
int i;
int a[8];
char op;
for (i = 0; i < 8; i++)
{
a[i] = n % 2;
n = (n - a[i]) / 2;
}
for (i = 7; i >= 0; i--)
{
op = strcat(op, a[i]);
}
return op;
}
int main()
{
int n;
char str;
n = 254;
str = converttobinary(n);
printf("%c", str);
return 0;
}
I have tried to modify your solution with minimal changes to make it work. There are elegant solutions to convert Integer to Binary for example using shift operators.
One of the main issue in the code was you were using character instead of character array.
i.e char str; instead of char str[SIZE];
Also you were performing string operations on a single character. Additionally, iostream header file is for C++.
There is room for lot of improvements in the solution posted below (I only made your code work with minimal changes).
My suggestion is to make your C basics strong and approach this problem again.
#include <stdio.h>
#include <string.h>
void converttobinary(int n, char *op)
{
int i;
int a[8];
for (i = 0; i < 8; i++)
{
a[i] = n % 2;
n = (n - a[i]) / 2;
}
for (i = 7; i >= 0; i--)
{
op[i]=a[i];
}
}
int main()
{
int n,i;
char str[8];
n = 8;
converttobinary(n,str);
for (i = 7; i >= 0; i--)
{
printf(" %d ",str[i]);
}
return 0;
}
char *rev(char *str)
{
char *end = str + strlen(str) - 1;
char *saved = str;
while(end > str)
{
int tmp = *str;
*str++ = *end;
*end-- = tmp;
}
return saved;
}
char *tobin(char *buff, unsigned long long data)
{
char *saved = buff;
while(data)
{
*buff++ = (data & 1) + '0';
data >>= 1;
}
*buff = 0;
return rev(saved);
}
int main()
{
char x[128];
unsigned long long z = 0x103;
printf("%llu is 0b%s\n", z, tobin(x, z));
return 0;
}
I modify your code a little bit to make what you want,
the result of this code with
n = 10
is
00001010
In this code i shift the bits n positions of the imput and compare if there is 1 or 0 in this position and write a '1' if there is a 1 or a '0' if we have a 0.
#include <stdio.h>
void converttobinary(int n, char op[8]){
int auxiliar = n;
int i;
for (i = 0; i < 8; i++) {
auxiliar = auxiliar >> i;
if (auxiliar & 1 == 1){
op[7-i] = '1';
} else{
op[7-i] = '0';
}
auxiliar = n;
}
}
int main (void){
int n = 10;
int i;
char op[8];
converttobinary(n, op);
for(i = 7; i > -1; i--){
printf("%c",op[i]);
}
return 0;
}

How to store an ascii value of 0 in a character string without terminating it?

Taking an input as hex string and then converting it to char string in C. The hex string can contain 0x00 which translates to an 0 in Ascii when converted. This terminates the string. I have to store the value in an char string because the API uses that.
My code so far:
int hex_to_int(unsigned char c) {
int first =0;
int second =0;
int result=0;
if(c>=97 && c<=102)
c-=32;
first=c / 16 - 3;
second =c % 16;
result = first*10 + second;
if(result > 9) result--;
return result;
}
unsigned char hex_to_ascii(unsigned char c, unsigned char d){
unsigned char a='0';
int high = hex_to_int(c) * 16;
int low = hex_to_int(d);
a= high+low;
return a;
}
unsigned char* HextoString(unsigned char *st){
int length = strlen((const char*)st);
unsigned char* result=(unsigned char*)malloc(length/2+1);
unsigned char arr[500];
int i;
unsigned char buf = 0;
int j=0;
for(i = 0; i < length; i++)
{
if(i % 2 != 0)
{
arr[j++]=(unsigned char)hex_to_ascii(buf, st[i]);
}
else
{
buf = st[i];
}
}
arr[length/2+1]='\0';
memcpy(result,arr,length/2+1);
return result;
}
You can store any values in a char array. But if you want to store a value of 0x00, you cannot use the string functions on this array. So you have to use an integer variable to store the length of the data you want to store. You can then write functions that use this integer.
As you provided more information now, I can tell you that your function doesn't cut anything as it loops through the whole C-string which you provided for example as input "0a12345600a0020b12". The "problem" is that if you want to get the length (strlen()) of the output string after the conversion for example then it will stop at '\0' and you will get a "wrong" length in terms of your original input string.
It is exacly like it's written in the answer of Xaver save the length information and the string to work with that length and not the one you would get by the C-string functions like strlen().
To show that and in order to provide a right length information I've added a struct definition to your code that defines a string type consisting of a size_t len and an unsigned char* str called HexString. With the additional length information you can handle a 0 byte. Also I made little changes to your code, e.g. you don't need that character buffer arr on the stack.
With your input: "0a12345600a0020b12"
the following output you will see: <0a> <12> <34> <56> <00> <a0> <02> <0b> <12> <00>
if you print the C-string hexadecimal every single character. The last <00> is the null termination.
Look here on ideone for a live example.
The code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
size_t len; /* C-string length + '\0' */
unsigned char* str;
} HexString;
int hex_to_int(unsigned char c)
{
int first =0;
int second =0;
int result=0;
if (c >= 97 && c <= 102) /* 97 = 'a'; 102 = 'f' */
c -= 32;
first = c / 16 - 3;
second = c % 16;
result = first * 10 + second;
if (result > 9) result--;
return result;
}
unsigned char hex_to_ascii(unsigned char c, unsigned char d)
{
unsigned char a = '0';
int high = hex_to_int(c) * 16;
int low = hex_to_int(d);
a = high + low;
return a;
}
HexString HextoString(const char* const st)
{
HexString result;
size_t length = strlen(st);
result.len = length/2+1;
result.str = malloc(length/2+1);
size_t i;
size_t j = 0;
unsigned char buf = 0;
for (i = 0; i < length; i++)
{
if (i % 2 != 0)
{
result.str[j++] = hex_to_ascii(buf, st[i]);
}
else
{
buf = (unsigned char)st[i];
}
}
result.str[length/2+1] = '\0';
return result;
}
int main()
{
size_t i;
HexString hexString = HextoString("0a12345600a0020b12");
for (i = 0; i < hexString.len; ++i)
{
printf("<%02x> ", hexString.str[i]);
}
free(hexString.str);
return 0;
}

Converting unsigned char array to hex

I want to convert unsigned char to hex (using unsigned int). This is my code so far. I have a program1 that produces an unsigned char array and the other program2 only takes in only hex (using unsigned int), so what i want to achieve is getting an input of unsigned char array and converting that array into hex.
(E.g., program1 outputs "1234567812345678", program2 should output "31323334353637383132333435363738")
Sorry if this question seems dumb. Looked around for answers here but it didn't seem to be what I wanted.
uint64_t phex (unsigned char[16], long);
int main (void) {
int i;
unsigned char key[16] = "1234567812345678";
uint64_t* keyHex = phex(key,16); //store into an array here
for(i = 0; i < 16; i++)
printf("%.2x ", keyHex[i]);
free(keyHex);
return 0;
}
uint64_t phex(unsigned char* string, long len)
{
int i;
//allocate memory for your array
uint64_t* hex = (uint64_t*)malloc(sizeof(uint64_t) * len);
for(i = 0; i < len; ++i) {
//do char to int conversion on every element of char array
hex[i] = string[i] - '0';
}
//return integer array
return hex;
}
If all you need to do is print the values, then you do not need to do any conversion. Just use printf %.2xon the original array.
int main (void) {
int i;
unsigned char key[16] = "1234567812345678";
for(i = 0; i < 16; i++)
printf("%.2x", key[i]);
return 0;
}
Even if you want to use the array in some other function, the actual bytes stored in key are the ascii characters, i.e. 0x31 0x32 etc. You can generally directly use the array key
Edit: To store the output in a character array, you can use the sprintf function.
char hex[33];
for(i = 0; i < 16; i++)
sprintf(hex+2*i, "%.2x", key[i]);
Also note that the original array key should be 17 bytes to account for the \0 at the end.
Here is my take on it - the phex() function converts any data
in memory into a newly allocated string containing the hex representation.
The main() function shows an example usage. The output is "31323334353637383930" for the example data.
#include <stdlib.h> /* malloc() */
#include <stdio.h> /* sprintf() */
#include <string.h> /* strlen(), in the example main() */
/*
* Return a hex string representing the data pointed to by `p`,
* converting `n` bytes.
*
* The string should be deallocated using `free()` by the caller.
*/
char *phex(const void *p, size_t n)
{
const unsigned char *cp = p; /* Access as bytes. */
char *s = malloc(2*n + 1); /* 2*n hex digits, plus NUL. */
size_t k;
/*
* Just in case - if allocation failed.
*/
if (s == NULL)
return s;
for (k = 0; k < n; ++k) {
/*
* Convert one byte of data into two hex-digit characters.
*/
sprintf(s + 2*k, "%02X", cp[k]);
}
/*
* Terminate the string with a NUL character.
*/
s[2*n] = '\0';
return s;
}
/*
* Sample use of `phex()`.
*/
int main(void)
{
const char *data = "1234567890"; /* Sample data */
char *h = phex(data, strlen(data)); /* Convert to hex string */
if (h != NULL)
puts(h); /* Print result */
free(h); /* Deallocate hex string */
return 0;
}
I see the function signature as
uint64_t phex (unsigned char[16], long);
so I think, you do not need array of uint64_t to transform one string, representing one number (perhaps I am wrong and you want to transform each single character from its char-representation to int and show as hexadecimal number).
First, let's consider the following code to transformation in decimal (actually, number in your example - 1234567812345678 - looks like decimal number):
uint64_t phex(unsigned char* string, long len)
{
int i;
//you do not need to allocate memory for array
uint64_t hex = 0; // just one variable
for (i = 0; i < len; ++i) {
hex *= 10; // shift
hex += string[i] - '0'; // add to the smallest rank
}
//return integer Value
return hex;
}
Then for hexadecimal the program will be:
#include <stdio.h>
#include <stdint.h>
#include <string.h>
uint64_t phex(unsigned char[16], long);
int main(void) {
int i;
unsigned char key[16] = "A123B00CF1";
uint64_t keyHex = phex(key, strlen(key));
printf("%lld(dec) = %llx(hex)", keyHex, keyHex);
return 0;
}
uint64_t phex(unsigned char* string, long len)
{
int i;
uint64_t hex = 0;
for (i = 0; i < len; ++i) {
hex *= 0x10; // shift for one hexadecimal digit
// -'0' for digits 0..9 and -('A'-10) for digits `A`..`F`
hex += toupper(string[i]) - ((string[i] >= 'A') ? ('A' - 10) : '0');
// TODO: Consider making check for characters that are not hexadecimal
// e.g. use isxdigit(string[i]) in some if statement
}
return hex;
}
Note: There is a mistake in your example code - uint64_t* keyHex take the value from function that returns uint64_t (not pointer ``uint64_t*`), but if you accept my idea, you do not need pointer at all.
If the task is to transform chars ('1', '2', etc.) to their hexadecimal representation (31 for '1', 32 for '2', etc.) it is hard to understand why you need uint64_t.
But for your task code can be as follows (without uint64_t):
#include <stdio.h>
#include <string.h>
unsigned int * phex(unsigned char[16], long);
int main(void) {
int i;
unsigned char key[16] = "1234567812345678";
unsigned* keyHex = phex(key, strlen(key)); // strlen(key) to determine number of characters
for (i = 0; i < 16; i++)
printf("%.2x", keyHex[i]); // you do need space as I see from your example
free(keyHex);
return 0;
}
unsigned int * phex(unsigned char* string, long len)
{
int i;
//allocate memory for array
unsigned int * hex = (unsigned int *)malloc(sizeof(unsigned int) * len);
for (i = 0; i < len; ++i) {
//no special conversion needed
hex[i] = string[i];
}
//return array with hexadecimal representation for each character in string
return hex;
}

Loop though an array of strings and then convert to a byte using sscanf_s c

I am only learning C and I am trying to loop though an array of strings and then convert to a byte array using sscanf.
#define BYTE unsigned char
char stringarray[][3]
{
"98D9C2327F1BF03",
"98D9EC2327F1BF03",
"98D9EC2327F1BF03",
}
int main()
{
size_t i = 0;
for (i = 0; i < sizeof(stringarray) / sizeof(stringarray[0]); i++)
{
char hexstring[] = stringarray[i], *position[] = hexstring;
BYTE HexByteArray[8];
size_t count= 0;
for (count = 0; count < sizeof(HexByteArray) / sizeof(HexByteArray[0]); count++) {
sscanf(position, "%2hhx", &HexByteArray[count]);
position += 2;
}
}
return 0;
}
Error using visual studio 2013
initializing' : cannot convert from 'char [3]' to 'char []
initialization with '{...}' expected for aggregate object
Untested (but it's based on this), but it should be enough to get you started:
#include <stdio.h> // sscanf
#include <string.h> // strcpy
#define BYTE unsigned char
// you want 3 strings of a length at least 17 (+1 for null terminator)
char stringarray[3][17]
{
"98D9C2327F1BF03",
"98D9EC2327F1BF03",
"98D9EC2327F1BF03",
};
int main()
{
size_t i = 0;
for (i = 0; i < sizeof(stringarray) / sizeof(stringarray[0]); i++)
{
char hexstring[17];
// copy stringarray[i] to hexstring
strcpy(hexstring, stringarray[i]);
// use a pointer
char *position = hexstring;
BYTE HexByteArray[8];
size_t count= 0;
for (count = 0; count < sizeof(HexByteArray) / sizeof(HexByteArray[0]); count++) {
sscanf(position, "%2hhx", &HexByteArray[count]);
position += 2;
}
printf("%u\n", HexByteArray[0]);
}
return 0;
}
is what you want to use when dealing with strings in c, check it out! ;)

Replace spaces with tab character

I just finished the first chapter of The C Programming Language and there are a few exercises before moving on. I already completed the one to replace the tab character with spaces which was fairly easy, but I am stuck on the one to replace space characters with the proper amount of tabs and spaces to achieve the same spacing.
My implementation "sometimes" works, so essentially it doesn't work. Here is the function:
#define TABLEN 5
// entab: replace consecutive spaces of length TABLEN with the tab character
void entab(char string[])
{
int i, consec;
int to, from, tabloc;
consec = 0;
for (i = 0; string[i] != '\0'; ++i) {
// count consecutive spaces in a string
if (string[i] == ' ') ++consec;
else consec = 0;
if (consec >= TABLEN) {
// set location to insert tab character
tabloc = (i - TABLEN) + 1;
for (to = tabloc, from = i;
string[from] != '\0'; ++from, ++to)
{
// replace space characters
string[to] = string[from];
}
string[tabloc] = '\t';
string[to] = '\0';
i = tabloc;
consec = 0;
}
}
}
This function is extremely inconsistent in working successfully to the point where there isn't even a pattern of when it does and doesn't work. By "doesn't work", I mean one of two situations. 1.) the spaces are deleted and no tab character is inserted, or 2.) the spaces are deleted, a tab character is inserted, but somehow an extra space is added in. These issues have led me to realize that the problem exists in the loop that replaces the spaces, but I'm so new to C that I have no idea what is wrong. Can someone point me in the right direction here?
Here's how tabs work:
If you typed
Tab
v v v v
------------------------
| a
|a a
|aa a
|aaa a
|aaaa a
Notice how if there was 5, 4, 3, 2, or 1 spaces, they all could be equally represented as a tab. This is why 5 spaces doesn't equal a tab (even when the tab size is set to 5). Consider this case as well:
v v v v
------------------------
|aaaa a
| 12345
But when you replace those 5 spaces with a tab, you get:
v v v v
------------------------
|aaaa a
| 12345
Here's an working example:
#include <stdio.h>
#include <string.h>
void Print_As_String(char * buffer, unsigned int size);
void Print_As_Hex(char * buffer, unsigned int size);
void Convert_Tab_To_Space(char * buffer, unsigned int size, unsigned int tab_size);
int main(unsigned int argc, char * argv[]){
unsigned int i = 0;
unsigned int arg_length = 0;
if (argc <= 1){
printf("Usage: \"Text with spaces\", \"More text with spaces\", etc\n");
return -1;
}
for (i = 1; i < argc; i++){
arg_length = strlen(argv[i]);
Print_As_String (argv[i], arg_length);
Print_As_Hex (argv[i], arg_length);
Convert_Tab_To_Space(argv[i], arg_length, 8);
Print_As_String (argv[i], arg_length);
Print_As_Hex (argv[i], arg_length);
}
return 0;
}
void Print_As_String(char * buffer, unsigned int size){
printf("%.*s\n", size, buffer);
}
void Print_As_Hex(char * buffer, unsigned int size){
unsigned int i = 0;
const char hex_table[16] = "0123456789ABCDEF";
for (i = 0; i < size; i++){
unsigned char high_byte = 0;
unsigned char low_byte = 0;
high_byte = (buffer[i] & 0xF0) >> 4;
low_byte = (buffer[i] & 0x0F) >> 0;
putc(hex_table[high_byte], stdout);
putc(hex_table[low_byte], stdout);
putc(' ', stdout);
}
putc('\n', stdout);
}
void Shift_Characters_Left(char * buffer,
unsigned int position_start,
unsigned int position_end,
unsigned int size);
void Convert_Tab_To_Space(char * buffer, unsigned int size, unsigned int tab_size){
unsigned int i = 0;
unsigned int x = 0; /* x is used
for getting the position in
the current line. This is
different from 'i' because
there may be many lines in
one string.
*/
for (i = 0; i < size; i++){
if (buffer[i] == '\t'){ /* the x coordinates
change in this fashion when a new
tab is found.
*/
x += tab_size - (x % tab_size);
} else if (buffer[i] == ' '){
unsigned int tab_remainder = 0; // how many spots are left for a tab
unsigned int space_i = 1; // space index
tab_remainder = (x % tab_size);
while ((i + space_i) < size){
/* if the space count makes up for the
missing spots in the tab remainder,
replaces the spaces with a tab
*/
if ((tab_remainder + space_i) == tab_size){
Shift_Characters_Left(buffer, // move the spot at the end of
i + space_i, // the spaces to the spot at
i + 1, // the start of the spaces
size);
buffer[i] = '\t';
}
if (buffer[i + space_i] != ' '){
i += space_i;
break;
}
space_i++;
}
} else if (buffer[i] == '\n'){
x = 0;
} else {
x++;
}
}
}
void Shift_Characters_Left(char * buffer,
unsigned int position_start,
unsigned int position_end,
unsigned int size){
memmove(buffer + position_end,
buffer + position_start,
size - position_end);
memset(&buffer[position_start], 0, (size - 1) - position_start);
}
But there is an unaddressable error I get when I test this problem. I think it's something i'm doing wrong with memset (probably an off-by-one error).
The following works fine. Check the differences in the indexes
#include <stdio.h>
#define TABLEN 5
// entab: replace consecutive spaces of length TABLEN with the tab character
void entab(char string[])
{
int i, consec;
int to, from, tabloc;
printf("%s\n",string);
consec = 0;
for (i = 0; string[i] != '\0'; ++i) {
// count consecutive spaces in a string
if (string[i] == ' ') ++consec;
else consec = 0;
if (consec >= TABLEN) {
// set location to insert tab character
tabloc = (i - TABLEN) + 1;
for (to = tabloc+1, from = i+1;
string[from] != '\0'; ++from, ++to)
{
// replace space characters
string[to] = string[from];
}
string[tabloc] = '\t';
string[to] = '\0';
i = tabloc+1;
consec = 0;
}
}
printf("%s",string);
}
int main(void) {
// your code goes here
char a[] = "hello wor l d";
entab(a);
return 0;
}

Resources