Transform an array of integers into a string - c

A function returns an aray of integers and I want it to pass to another function which searches for some pattern. But the second function expects a string.
Example:
int IArray = {1, 2, 3};
// should be coverted into "123"
Is there a direct function available? If not, how do I convert the array of integers into a string?

There is no direct function to do that.
You'll have to use sprintf.

There is nothing in the C stdlib to do this, but it isn't hard to write the string manipulations:
#include <assert.h>
int transform_ints_to_string(int const* data, int data_length,
char* output, int output_length)
{
// if not enough space was available, returns -1
// otherwise returns the number of characters written to
// output, not counting the additional null character
// precondition: non-null pointers
assert(data);
assert(output);
// precondition: valid data length
assert(data_length >= 0);
// precondition: output has room for null
assert(output_length >= 1);
int written = 0;
for (; data_length; data_length--) {
int length = snprintf(output, output_length, "%d", *data++);
if (length >= output_length) {
// not enough space
return -1;
}
written += length;
output += length;
output_length -= length;
}
return written;
}
Example:
int main() {
char buf[100] = "";
int data[] = {1, 2, 3};
if (transform_ints_to_string(data, 3, buf, sizeof buf) == -1) {
puts("not enough room");
}
else {
printf("%s\n", buf);
}
return 0;
}

Is there a direct function available I
can use?
NO

most c and c++ compilers support itoa function, which converts an int to a char*, or you can use sprintf to do this. The next thing is to concatenate all strings into a single string, you can use strcat . Follow the links, you will find examples for these two functions.

If your IArray variable contains integer values in the range [0,9], then you can do something like this (pseudocode):
string := ""
While more numbers:
string.append(next + '0')
In C, it is guaranteed that '0', '1', ..., '9' have consecutive integral values.
If this is not what you want, you need to define your problem more clearly.

int IArray = {1, 2, 3};
That's not C!
Do you mean;
int IArray[3] = {1, 2, 3};
You could do this...
for( loop = 0 ; loop < 3 ; loop++ )
*(((char *) IArray)+loop) = '0' + IArray[loop];
*(((char *) IArray)+loop) = 0;
printf( "%s\n", (char *) IArray );
...but I wouldn't if I were you :-)

Related

Length of an array

I need to find the length of an array, how would I do this without using the sizeof function.
eg if
Array 1 = [0 1 2 3 4 5 6]
the size of this array would be 7.
If you can't use sizeof (tell us why, please), you can use a loop and a sentinel (-1 or some number that can not be used in the array):
int arr[] = {0, 1, 2, 3, 4, 5, 6, -1};
int count = 0;
while (arr[count] != -1) count++;
Many high-level programming language save the length of an array once it is created.
/* e.g. Java */
int[] foo = new int[10];
assert(foo.length == 10);
But the length of an array is not saved in C! This is useful as you can decide how you want to save the length with respect to optimization. You basically have three possibilities to get/save the length:
mark the end of the array with a certain value (i.e. \0 is used for strings)
char foo[] = "bar";
/* foo has length 4(sic!) as '\0' is automatically added to the end*/
int i = 0;
while(foo[i] != '\0'){
printf("%c",foo[i]);
i++;
}
save the length of the array in a variable
int foo[] = {1,2,3,4};
int length = 4;
for(int i = 0; i < length;i++){
printf("%i, ",foo[i]);
}
use sizeof (warning: sizeof is (mostly) computed at compile time and its use is restricted. you can only use sizeof within the function where the array has been created. when you pass an array to a function you only pass the pointer to the first element. therefore you can loop through this array as you know what offset must be used(type of its elements), but you do not know how big it is unless you also passed the length or added a sentinel value)
/* ok */
int foo[] = {1,2,3,4};
for(int i = 0; i < sizeof(foo)/sizeof(int);i++){
printf("%i, ",foo[i]);
}
/* not ok */
void foo(int bar[]);
void foo(int bar[]){
for(int i = 0; i < sizeof(bar)/sizeof(int);i++){
printf("%i, ",bar[i]);
}
}
int main()
{
int arr[] = {1,2,3,4};
foo(arr);
return 0;
}

combine the whole elements in the array and store it in index 0

I have an array of values:
array1[] = {1, 32, 4, 12};
Which I want to store as a string of hexadecimal representations of each value (with format "%02x") :
string = "0120040c";
I can print the string using a for loop just fine:
for (int i=0;i<array_size;++i)
printf("%02x", array[i]);
But haven't been able to assign the resulting string to a char array. How can I do this?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *join(int n, char *a[n]){
int i;
size_t lens[n], len=1;
for(i=0;i<n;++i)
len += (lens[i] = strlen(a[i]));
char *cat = malloc(len);
char *p = cat;
for(i=0;i<n;++i){
memcpy(p, a[i], lens[i]+1);
p += lens[i];
}
return cat;
}
int main(void){
char *array1[] = {"a", "p", "p", "l", "e"};
char *string;
int n = sizeof(array1)/sizeof(*array1);
string = join(n, array1);
puts(string);
free(string);
return 0;
}
Apparently you want to create a string showing the values in an array as hexadecimals. This can be done, relatively easily by looping over the string, and with some snprintf magic. But first, let's establish what we need to know, and how to obtain that info:
Why size is the array
How many chars will each value take up in our target string
How are we accessing the array, as an array or a pointer (ie: is it passed to a function or not)
If you have a compiler that supports C99 or C11, you can use a VLA. First, let's assume that you have an array (And not a pointer):
const char * format = "%02x";//each value will be 2 chars + terminating 0
int array[] = { 123, 32, 4354, 544};
size_t arr_len = sizeof array/ sizeof *array;//get the nr of elements in the array
char string[arr_len*2 + 1];//nr of array elements *2 (chars) + terminating 0
for (int i=0;i<arr_len;++i)
{//this is where the magic happens:
snprintf(string + (i*2), 3, format, array[i]);
}
printf("The full hex string is: %s\n", string);
Now let's look at this bit: snprintf(string + (i*2), 3, format, array[i]);
I'm using the string array, as if it were a pointer, as if string contained a memory address pointing to string[0]. By adding i*2 to it, I'm telling snprintf that the target memory to where it should write the output starts at the N-th element of the array. On the first iteration, i is 0, so string + 0*2 == string + 0 == string, the second time, it's string + (1*2) == string + 2 == &string[2]. Effectively, concatenating the output.
Then, I pass 3 to snprintf, telling the function that the max length of the output is 3 chars (including the terminating \0 char). That's a perfect fit for the 2 hex chars + \0 coming from our format "%02x". Then it's a simple matter of passing array[i] to add the hex value to the end of the string.
Great, now what if array is passed to a function, and/or you don't have VLA's? same as above, with a few differences. You'll have to compute and pass the length of the array to the function (computation method shown above). You'll also have to allocate the memory for the string yourself (and free it), which shouldn't be too difficult either:
char * get_hex_string(int *arr, size_t arr_len)
{
char * string = malloc((arr_len * 2 + 1) * sizeof *string);//the sizeof *string is optional
if (string == NULL)
return NULL;
string[0] = '\0';//clear first char, just in case
for (int i=0;i<arr_len;++i)
snprintf(string + i*2, 3, "%02x", arr[i]);//same as before
string[arr_len*2] = '\0';//optional, just a habit of mine
return string;//return string
}
int main( void )
{
int array[] = {12, 32, 54, 1, 6};
char *as_string = get_hex_string(array, sizeof array/sizeof *array);
if (as_string == NULL)
{
fprintf(stderr, "Failed to get hex-string\n");
exit( EXIT_FAILURE );
}
printf("Hex-string: %s\n", as_string);
free(as_string);//optional here, but good habit
return EXIT_SUCCESS;
}
Demo
It's a bit unclear why you've written array2[0], that implies that array2 should be an array of strings, declared like so:
char array2[N][M];
Where N is at least 1 and M is at least 6 to hold "apple\0".
If you just meant that array2 should be a single string, declared like so:
char array2[32];
for instance, then you can create that by copying the characters from array1 and then ending the string by putting in the '\0' character at the end:
memcpy(array2, array1, 5);
array2[5] = '\0';
At this point, doing e.g. printf("'%s'\n", array2); will print 'apple'.
If I have understood correctly you then the definition of a two-dimensional array will look like
char a[M][N] = { "apple" };
where M and N some integral constants that specifies sizes of the array. (In C you may use also Varaiable Length Arrays if the compiler supports them)
Or if you want to copy the first array in the first element of a two dimensional array defined like above then you need to write
memcpy( a[0], array1, 5 );
a[0][5] = '\0';
If array1 would contain a zero terminated string then you could use strcpy instead of memcpy
Note
I think you mean for example
array1[0] = 'a';
instead of
array1[0] = "a"
If so then the code can look like
#include <stdio.h>
#include <string.h>
int main(void)
{
char array1[5];
char array2[10][6];
array1[0] = 'a';
array1[1] = 'p';
array1[2] = 'p';
array1[3] = 'l';
array1[4] = 'e';
memcpy( array2[0], array1, 5 );
array2[0][5] = '\0';
printf( "array2[0] = %s\n", array2[0] );
return 0;
}
Otherwise if array1 is a two-dimensional array itself then you should use standard function strcat and the code could look like
#include <stdio.h>
#include <string.h>
int main(void)
{
char array1[5][2] = { "a", "p", "p", "l", "e" };
char array2[10][6] = { { '\0' } };
for ( int i = 0; i < 5; i++ ) strcat( array2[0], array1[i] );
printf( "array2[0] = %s\n", array2[0] );
return 0;
}
In both cases the output will be
apple
Or if the second array is a one dimensional array then you can write
#include <stdio.h>
#include <string.h>
int main(void)
{
char array1[5][2] = { "a", "p", "p", "l", "e" };
char string[6] = { '\0' };
for ( int i = 0; i < 5; i++ ) strcat( string, array1[i] );
printf( "string = %s\n", string );
return 0;
}
This should work for you:
#include <stdio.h>
#include <string.h>
#define MAX_SIZE 6
int main() {
char array1[MAX_SIZE];
char array2[1][MAX_SIZE];
array1[0] = 'a';
array1[1] = 'p';
array1[2] = 'p';
array1[3] = 'l';
array1[4] = 'e';
//...
array1[MAX_SIZE-1] = '\0';
strcpy(array2[0], array1);
array2[0][MAX_SIZE-1] = '\0';
printf("%s", array2[0]);
return 0 ;
}

Creating a string in C of the form "1,2,3,4,5"

I'm having difficulty in generating a string of the form "1,2,3,4,5" to pass to a command line program.
Here's what I have tried:
int N=100;
char list[200];
for (i=0; i<2*N; i+=2) {
char tmp;
sprintf(tmp,'%d', i);
strcpy(list[i], tmp);
strcpy(list[i+1], ',');
}
Edit:
I don't feel this question is a duplicate as it is more to do with appending strings into a list and managing that memory and than literally just putting a comma between to integers.
The following code will do what you need.
#include <stdlib.h>
#include <stdio.h>
char* CommaSeparatedListOfIntegers(const int N)
{
if (N < 1)
return NULL;
char* result = malloc(1 + N*snprintf(NULL, 0, "%d,", N));
char* p = result;
for (int i = 1; i <= N; i++)
p += sprintf(p, "%d,", i);
*(p-1) = '\0';
return result;
}
Note that the function returns a heap allocated block of memory that the caller is responsible for clearing up.
Some points of note:
We put a crude upper bound on the length of each number when converted to text. This does mean that we will over allocate the block of memory, but not by a massive amount. If that is a problem for you then you can code a more accurate length. That would involve looping from 1 to N and calling snprintf for each value to determine the required length.
Note that we initially write out a comma after the final value, but then replace that with the null-terminator.
Let's forget about writing strings for the moment and write a function that just prints that list to the screen:
int range_print(int begin, int end, const char *sep)
{
int len = 0;
int i;
for (i = begin; i < end; i++) {
if (i > begin) {
len += printf("%s", sep);
}
len += printf("%d", i);
}
return len;
}
You can call it like this:
range_print(1, 6, ", ");
printf("\n");
The function does not write a new-line character, so we have to do that. It prints all numbers and a custom separator before each number after the first. The separator can be any string, so this function also works if you want to separate your numbers with slashes or tabs.
The function has printf semantics, because it returns the number of characters written. (That value is often ignored, but it can come in handy, as we'll see soon.) We also make the upper bound exclusive, so that in order to print (1, 2, 3, 4, 5) you have tp pass 1 and 6 as bounds.
We'll now adapt this function so that it writes to a string. There are several ways to do that. Let's look at a way that works similar to snprintf: It should tabe a pre-allocated char buffer, a maximum length and it should return the number of characters written or, if the output doesn't fit, the number of characters that would have been written had the buffer been big enough.
int range(char *buf, int n, int begin, int end, const char *sep)
{
int len = 0;
int m, i;
for (i = begin; i < end; i++) {
m = snprintf(buf, n, "%s%d",
(i > begin) ? sep : "", i);
len += m;
buf += m;
n -= m;
if (n < 0) n = 0;
}
return len;
}
This function is tricky because it has to keep track of the number of characters written and of the free buffer still available. It keeps printing after the buffer is full, which is a bit wasteful in terms of performace, but it is legal to call snprintf with a buffer size of zero, and that way we keep the semantics tidy.
You can call this function like this:
char buf[80];
range(buf, sizeof(buf), 1, 6, ", ");
printf("%s\n", buf);
That means that we need to define a buffer that is large enough. If the range of numbers is large, the string will be truncated. We might therefore want a function that allocates a string for us that is long enough:
char *range_new(int begin, int end, const char *sep, int *plen)
{
int len = (end - begin - 1) * strlen(sep) + 1;
char *str;
char *p;
int i;
for (i = begin; i < end; i++) {
len += snprintf(NULL, 0, "%d", i);
}
str = malloc(len);
if (str == NULL) return NULL;
p = str;
for (i = begin; i < end; i++) {
if (i > begin) p += sprintf(p, "%s", sep);
p += sprintf(p, "%d", i);
}
if (plen) *plen = len - 1;
return str;
}
This function needs two passes: in the first pass, we determine how much memory we need to store the list. Next, we allocate and fill the string. The function returns the allocated string, which the user has to free after use. Because the return value is already used, we lose the information on the string length. An additional argument, a pointer to int, may be given. If it is not NULL, the length will be stored.
This function can be called like this.
char *r;
int len;
r = range_new(1, 6, ", ", &len);
printf("%s (%d)\n", r, len);
free(r);
Note that the same can be achieved by calling our old range function twice:
char *r;
int len;
len = range(NULL, 0, 1, 6, ", ");
r = malloc(len + 1);
range(p, len + 1, 1, 6, ", ");
printf("%s (%d)\n", r, len);
free(r);
So, pick one. For short ranges, I recommend the simple range function with a fixed-size buffer.

How to convert a list to a string

Problem in C programming
I have following list:
int a[] = {0,0,1,0,0,1,0,2}
How do i convert following list items to char variable b?
Like this:
printf(%c, b)
OUTPUT: 00100102
I need this for printing the values of list in embedded system lcd screen where normal print options aren't available. Couldn't find similar example from www.stackoverflow.com. Vice versa there were many solutions to convert a string into a list.
#include <stdio.h>
#include <stdlib.h>
int main(){
int a[] = {0,0,1,0,0,1,0,2};
const char *table = "0123456789";
size_t size = sizeof(a)/sizeof(*a);
char *b = malloc(size+1);
int i;
for(i=0;i<size;++i)
b[i]=table[a[i]];
b[i]='\0';
printf("%s\n", b);
free(b);
return 0;
}
int a = [0,0,1,0,0,1,0,2]
That is not valid C. Perhaps you meant:
const int a[] = { 0, 0, 1, 0, 0, 1, 0, 2 };
Converting a decimal digit to a printable character in C is easy, just add '0':
printf("%c", '0' + a[0]);
will print 0.
You can iterate through the elements of your array, and printf() each one, considering it as an offset from '0':
/*
'0' + 0 = '0'
'0' + 1 = '1'
'0' + 2 = '2'
*/
const int a[] = {0,0,1,0,0,1,0,2};
const int count = sizeof(a) / sizeof(a[0]);
int i;
for (i = 0; i < count; i++) {
printf("%c", '0' + a[i]);
}
printf("\n");
When you convert each value in an array of int to a corresponding value in an array of char, you just have an array of char. When you append the null terminator \0 (or 0) to the array of char, it becomes a C string.
int a[] = {0,0,1,0,0,1,0,2}; //use curly braces to assign values to new array.
char b[sizeof(a)/sizeof(a[0])+1];//Accomodates any size of a. note extra space for terminating \0
int i;
//EDIT 5 following lines
b[0]=0; //ensure string is null terminated
for(i=0;i<sizeof(a)/sizeof(a[0]);i++)
{
sprintf(b, "%s%d", b, a[i]);//copy one char per loop to concatenate string with all elements of `a`
}
Now you have a string, sized according to number of array elements in a that looks like:
"00100102"
In memory you would see |48|48|49|48|48|49|48|50|0|
(the integer values of each character representation of the integers 0, 1, & 2, with the null character 0 in the last position to mark the end of string.)
Note also, the phrase sizeof(array)/sizeof(array[0]) is used to get the number of elements in an array.

C Library function for converting a string of hex digits to ints?

I have a variable length string where each character represents a hex digit. I could iterate through the characters and use a case statement to convert it to hex but I feel like there has to be a standard library function that will handle this. Is there any such thing?
Example of what I want to do. "17bf59c" -> int intarray[7] = { 1, 7, 0xb, 0xf, 5, 9, 0xc}
No, there's no such function, probably because (and now I'm guessing, I'm not a C standard library architect by a long stretch) it's something that's quite easy to put together from existing functions. Here's one way of doing it decently:
int * string_to_int_array(const char *string, size_t length)
{
int *out = malloc(length * sizeof *out);
if(out != NULL)
{
size_t i;
for(i = 0; i < length; i++)
{
const char here = tolower(string[i]);
out[i] = (here <= '9') ? (here - '\0') : (10 + (here - 'a'));
}
}
return out;
}
Note: the above is untested.
Also note things that maybe aren't obvious, but still subtly important (in my opinion):
Use const for pointer arguments that are treated as "read only" by the function.
Don't repeat the type that out is pointing at, use sizeof *out.
Don't cast the return value of malloc() in C.
Check that malloc() succeeded before using the memory.
Don't hard-code ASCII values, use character constants.
The above still assumes an encoding where 'a'..'f' are contigous, and would likely break on e.g. EBCDIC. You get what you pay for, sometimes. :)
using strtol
void to_int_array (int *dst, const char *hexs)
{
char buf[2] = {0};
char c;
while ((c = *hexs++)) {
buf[0] = c;
*dst++ = strtol(buf,NULL,16);
}
}
Here's another version that allows you to pass in the output array. Most of the time, you don't need to malloc, and that's expensive. A stack variable is typically fine, and you know the output is never going to be bigger than your input. You can still pass in an allocated array, if it's too big, or you need to pass it back up.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
/* str of length len is parsed to individual ints into output
* length of output needs to be at least len.
* returns number of parsed elements. Maybe shorter if there
* are invalid characters in str.
*/
int string_to_array(const char *str, int *output)
{
int *out = output;
for (; *str; str++) {
if (isxdigit(*str & 0xff)) {
char ch = tolower(*str & 0xff);
*out++ = (ch >= 'a' && ch <= 'z') ? ch - 'a' + 10 : ch - '0';
}
}
return out - output;
}
int main(void)
{
int values[10];
int len = string_to_array("17bzzf59c", values);
int i = 0;
for (i = 0; i < len; i++)
printf("%x ", values[i]);
printf("\n");
return EXIT_SUCCESS;
}
#include <stdio.h>
int main(){
char data[] = "17bf59c";
const int len = sizeof(data)/sizeof(char)-1;
int i,value[sizeof(data)/sizeof(char)-1];
for(i=0;i<len;++i)
sscanf(data+i, "%1x",value + i);
for(i=0;i<len;++i)
printf("0x%x\n", value[i]);
return 0;
}

Resources