How to convert a list to a string - c

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.

Related

How can I multiply numbers in a string by grouping them according to intervals?

I want to get a result of dividing a string of numbers by a specific interval and multiplying it. I know how to change one character into a number.
Here's the code
#include<stdio.h>
int main(void) {
char str[] = "123456";
int a, b, c;
a = str[0] - '0';
b = 23; // desired to be changed. str[1] ~ str[2]
c = 456; // desired to be changed. str[3] ~ str[5]
printf("%c * %c%c * %c%c%c = %d", str[0], str[1], str[2], str[3], str[4], str[5], a * b * c);
}
I designated the index interval to be divided as 0, 1 to 2, 3 to 5.
I didn't know how to convert characters into numbers, so I stored values directly for the variables.
Here's the output: 1 * 23 * 456 = 10488
Here's the desired result:
In str, change the number corresponding to index 0 to int type.
In str, change the number corresponding to index 1 to 2 to int type.
In str, change the number corresponding to index 3 to 5 to int type.
Multiply the changed numbers.
This question is related. However, I am curious about how the user intentionally divides and multiplies the sections rather than dividing them according to spaces.
to convert two digit string into number you need to multiple first digit by 10 and add second digit, the same for 3 digit, something like this:
#include<stdio.h>
// converts number stored between start/end indexes into integer
int parse(char* str, int start, int end) {
int result = 0;
for (int i=start; i<=end; i++) {
result = result*10 + (str[i] - '0');
}
return result;
}
int main(void) {
char str[] = "123456";
int a, b, c;
a = parse(str, 0, 0);
b = parse(str, 1, 2);
c = parse(str, 3, 5);
printf("%d * %d * %d = %d", a, b, c, a * b * c);
}
"I didn't know how to convert characters into numbers"
Based on your example algorithm enumerated in steps 1, 2, 3 & 4, without including any user input instructions, here is an implementation that extracts the 3 integers from the source string by using string parsing, copying and string to number conversion.
int main(void)
{
char str[] = "123456";
char num1[10]={0};//note {0} initializes all memory locations in buffer to NULL
char num2[10]={0};
char num3[10]={0};
int n1, n2, n3;
char *tmp;
//1. In str, change the number corresponding to index 0 to int type
strncpy(num1, str, 1);
n1 = atoi(num1);
//2. In str, change the number corresponding to index 1 to 2 to int type.
tmp = strchr(str, '2');
strncpy(num2, tmp, 2);
n2 = atoi(num2);
//3. In str, change the number corresponding to index 3 to 5 to int type.
tmp = strchr(str, '4');
strncpy(num3, tmp, 3);
n3 = atoi(num3);
//4. Multiply the changed numbers.
int result = n1*n2*n3;
printf("%d", result);
return 0;
}
Outputs;
10488

Why do i get this stack smashing error in my program?

I am practicing my use of strcpy() in C and wrote this program.
#include <stdio.h>
#include <string.h>
int main(){
int array[4] = {3,7,1,5};
char str[4], temp[5];
for (int i = 0; i < 4; i++){
sprintf(&str[i],"%d", array[i]);
}
for (int i = 0; i < 4; i++){
strcpy(&temp[i],&str[i]);
printf("%c", temp[i]);
}
return 0;
}
~
Unfortunately i get a 'stack smashing' error why is this ?
Strings in C must be terminated by a NUL byte ('\0'), and you must account for that when you size your buffers.
Given the contents of array, the following code
for (int i = 0; i < 4; i++) {
sprintf(&str[i], "%d", array[i]);
}
will write bytes as follows, remembering that arrays are indexed from 0:
'3' to the 0th index, '\0' to the 1st index
'7' to the 1st index, '\0' to the 2nd index
'1' to the 2nd index, '\0' to the 3rd index
'5' to the 3rd index, '\0' to the 4th index
You write over the previously placed NUL with the current integer. Do you see the problem, though? There is not a 4th index in str[4]. You're going to write a byte to memory that you should not be accessing.
Even with str[5], so that there is room for the final NUL, the second part of your code would work in a very counter productive way.
The results of the first loop would have the contents of str be equal to "3714", such that
strcpy(&temp[i], &str[i]);
would then copy the strings as such:
"3714" to temp + 0
"714" to temp + 1
"14" to temp + 2
"4" to temp + 3
See how you're just walking along the same string, recopying the same tails to the same locations? printf("%c", temp[i]); is just going to print the first character of whichever tail you're on.
With enough room in str, this program is essentially a very round about way of writing:
int array[] = { 3, 7, 1, 5 };
for (int i = 0; i < 4; i++)
printf("%d", array[i]);
Additionally, if array were to contain any integers whose representation as a string required more than a single byte (e.g., -5, 32), this code would not scale at all.
You'll want to change str to be a 2d array, containing space for all the strings you will create from the integers in array
#include <stdio.h>
#include <string.h>
int main(void) {
int array[4] = {3, 7, 1, 5};
char str[4][12], temp[12];
for (int i = 0; i < 4; i++)
sprintf(str[i], "%d", array[i]);
for (int i = 0; i < 4; i++){
strcpy(temp, str[i]);
printf("[%d] %s\n", i, temp);
}
}
though this is still not a very interesting exercise for the use of strcpy, seeing as we could just print str[i] directly.
Here's an example to play around with of using strcpy when searching for the last integer in an array whose string representation is longer than than two characters.
#include <stdio.h>
#include <string.h>
int main(void) {
int array[] = { 3, 7, 123, 4, 13, -55, 29, 55 };
char string[12] = "0", temp[12];
for (int i = 0; i < (sizeof array / sizeof *array); i++)
if (sprintf(temp, "%d", array[i]) > 2)
strcpy(string, temp);
printf("Final value: %s\n", string);
}
Each str[i] can only hold a single character, not a string - when you write
sprintf( &str[i], "%d", array[i] );
you are attempting to write a 2-character string1 to a 1-character buffer; the string terminator is "spilling" into the array element str[i+1] until you get to str[3], in which case the terminator spills over the end of the array.
To store an array of strings, you need to set aside a 2D array of char:
char str[4][N+1]; // can hold 4 strings of length N, +1 for the string terminator
Then in your sprintf statement, you'd write
sprintf( str[i], "%d", array[i] ); // no & operator on str[i]
All the values in array are only one digit - for larger values, you would need more characters in your array. A string representation of a 32-bit int can have up to 10 digit characters, plus a sign character, plus the string terminator, so you need to set aside an array that can hold 12 elements, so ideally str should be declared as char str[4][12];

How to convert elements in const unsigned char array to char

I am trying to iterate over a single const unsigned char array and assign/convert each element to a new char array using typecasting, every thread I've read suggests using typecasting however it's not working for me, here's my attempt:
#include <stdio.h>
#include <stdlib.h>
char *create_phone_number(const unsigned char nums[10]) {
char *new = malloc(11);
int i = 0;
for (; i<10; i++)
new[i] = (char)nums[i];
new[i] = '\0';
return new;
}
int main(void) {
char *num = create_phone_number((const unsigned char[]){ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 });
printf("%s\n", num);
free(num);
return 0;
}
The above code's stdout:
Expected stdout:
1111111111
How do I convert the elements in nums to type char and assign/store the converted values in the new array (efficiently)?
Casting to char doesn't mean casting the integer value to the corresponding ASCII character; the numeric value 1 is the ASCII code SOH (start of heading) which has no printable representation, thus your empty output. If you know all the values will be in the range 0 to 9, you can add them to ASCII '0' to get the char value that produces the associated ASCII digit:
char *create_phone_number(const unsigned char nums[10]) {
char *new = malloc(11);
for (int i=0; i<10; i++)
new[i] = '0' + nums[i];
new[i] = '\0';
return new;
}
You don't actually need to cast it at all; the result of the + will be int and it will store back to a char that can fit it without issue (so just make sure they're really all 0-9 values, or you'll get weird results).

Converting string to one with escape sequences

I have a char string containing hexadecimal characters (without 0x or \x):
char *A = "0a0b0c";
from which I want to obtain
const char *B = "\x0a\x0b\x0c";
Is there an efficient way to do this? Thanks!
EDIT: To be clear, I want the resultant string to contain the 3 characters \x0a, \x0b, \x0c, not a 12 character string that says "\x0a\x0b\x0c" where the \ and x are read as individual characters.
This is what I have tried:
const char *B[12];
for (j = 0; j < 4; ++j) {
B[4 * j + 0] = '\\';
B[4 * j + 1] = 'x';
B[4 * j + 2] = A[2 * j];
B[4 * j + 3] = A[2 * j + 1];
};
B[12] = '\0';
which gives me a 12 character string "\x0a\x0b\x0c", but I want B to be as if it was assigned thus:
const char *B = "\x0a\x0b\x0c";
There are multiple confusions in your code:
the input string has 6 characters and a null terminator
the output string should be defined as const char B[3]; or possibly const char B[4]; if you intend to set a null terminator after the 3 converted bytes.
the definition const char *B[12]; in your code defines an array of 12 pointers to strings, which is a very different beast.
The for is fine, but it does not do what you want at all. You want to convert the hexadecimal encoded values to byte values, not insert extra \ and x characters.
the trailing ; after the } is useless
you set a null terminator at B[12], which is beyond the end of B.
Here is a corrected version using sscanf:
const char *A = "0a0b0c";
const char B[4] = { 0 };
for (j = 0; j < 3; j++) {
sscanf(&A[j * 2], "%2hhx", (unsigned char *)&B[j]);
}
The conversion format %2hhx means convert at most the first 2 bytes at A[j * 2] as an unsigned integer encoded in hexadecimal and store the resulting value into the unsigned char at B[j]. The cast is only necessary to avoid a compiler warning.
You can write a function that would sprintf the desired into a string, and then concat that with the destination string.
Something along these lines...
#include <stdio.h>
#include <string.h>
void createB (char B[10], const char *start)
{
char temp[10];
sprintf(temp, "\\x%c%c", start[0], start[1]);
strcat(B, temp);
}
int main ()
{
char A[] = "0a0b0c";
char B[10] = {'\0'};
for (int i=0; A[i] != '\0'; i = i+2)
{
createB(B, A+i);
}
printf("%s\n", B);
return 0;
}
$ ./main.out
\x0a\x0b\x0c
You can modify that to suit your needs or make it more efficient as you feel.
Please make edits as you please; to make it safer with necessary checks. I have just provided a working logic.
If you simply want to add "\x" before each '0' in the string-literal A with the result in a new string B, a simple and direct loop is all that is required, and storage in B sufficient to handle the addition for "\x" for each '0' in A.
For example:
#include <stdio.h>
#define MAXC 32
int main (void) {
char *A = "0a0b0c",
*pa = A,
B[MAXC],
*pb = B;
do { /* loop over all chars in A */
if (*pa && *pa == '0') { /* if chars remain && char is '0' */
*pb++ = '\\'; /* write '\' to B, adv ptr */
*pb++ = 'x'; /* write 'x' to B, adv ptr */
}
*pb++ = *pa; /* write char from A, adv ptr */
} while (*pa++); /* while chars remain (writes nul-termining char) */
puts (B); /* output result */
}
You cannot simply change A to an array with char A[] = 0a0b0c"; and then write back to A as there would be insufficient space in A to handle the character addition. You can always declare A large enough and then shift the characters to the right by two for each addition of "\x", but it makes more sense just to write the results to a new string.
Example Use/Output
$ ./bin/straddescx
\x0a\x0b\x0c
If you need something different, let me know and I'm happy to help further. This is probably one of the more direct ways to handle the addition of the character sequence you want.
#include <stdio.h>
int main(void)
{
char str1[] = "0a0b0c";
char str2[1000];
int i, j;
i = j = 0;
printf("sizeof str1 is %d.\n", sizeof(str1)-1);
for(i = 0; i < sizeof(str1)-1; i += 2)
{
str2[j] = '\\';
str2[j+1] = 'x';
str2[j+2] = str1[i];
str2[j+3] = str1[i+1];
j+=4;
}
str2[j] = '\0';
printf("%s\n", str2);
return 0;
}
I think you can do like this.
Assuming no bad input, assuming 'a' to 'f' are sequentially in order, assuming no uppercase:
// remember to #include <ctype.h>
char *input = "0a0b0c";
char *p = input;
while (*p) {
v = (isdigit((unsigned char)*p) ? *p-'0' : *p-'a'+10) * 16;
p++;
v += isdigit((unsigned char)*p) ? *p-'0' : *p-'a'+10;
p++;
printf("0x%d", v); // use v
}
While using char A[] = "0a0b0c";, as proposed by kiran, would make it possible to change the string, it wil not yet allow to insert characters. Because that would make the string longer and hence not fit into the available memory. This in turn is a problem, if you cannot create the target string right away with the needed size.
You could know the needed size in advance, if the input is always of the same length and always requires the same number of inserted characters, e.g. if like in your example, the target string is double the size of the input string. For a simple character array definition, you would need to know the size already at compile time.
char A[7] = "0a0b0c"; /* not 6, because size for the termianting \0 is needed */
char B[13] = ""; /* 2*6+1 */
So you can stay with char *A = "0a0b0c"; and make your life easier by setting up memory of appropriate size to serve as target. For that you need to first determine the length of the needed memory, then allocate it.
Determining the size if easy, if you know that it will be twice the input size.
/* inside a function, this does not work as a variable definition */
int iLengthB = 2*length(A);
char* B = malloc(iLengthB+1); /* mind the terminator */
Then loop over A, copying each two characters to B, prepending them with the two characters "\x". I assume that this part is obvious to you. Otherwise please show how you setup the program as described above and make a loop outputting each character from A separatly. Then, after you demonstrated that effort, I can help more.

How do I print all array elements on the same line?

I had to delete all the code. What I' looking is how to sprintf all elements of an array in the same line.
The display has 2 lines, I need to print the array 10,24,32,40,51, .....first line
and 10,51 .....second line
sample
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *join(int n, const int array[n], const char *format, const char *sep){
if(!format)
format = "%d";
if(!sep)
sep = ", ";
size_t len = strlen(sep)*(n-1)+1;//+1 for EOS
int i;
for(i=0;i<n;++i)
len += snprintf(NULL, 0, format, array[i]);
char *result = malloc(len);
if(!result)return NULL;
size_t pos = 0;
for(i=0;i<n;++i){
pos += sprintf(result + pos, format, array[i]);
if(i != n-1)
pos += sprintf(result + pos, "%s", sep);
}
return result;
}
int main (void){
int array[][5]={{10,24,32,40,51},{10,1,99,77,88}};
int row_size = sizeof(array)/sizeof(array[0]);
int col_size = sizeof(array[0])/sizeof(int);
char *join_str;
int i;
for(i=0;i<row_size;++i){
char *join_str = join(col_size, array[i], "%2d", ", ");
printf("%s\n", join_str);
free(join_str);
}
return 0;
}
Your array has 10 elements
#define N 10
int V[N] = {10,34, 34, 11};
However, it is partially explicitly initialised so that indices 0, 1, 2 and 3 contain 10, 34, 34 and 11 respectively. A partially explicitly initialised array in C will have the remaining elements (4 .. 9 inclusive) implicitly initialised to 0.
You then:
sprintf (str, "%d %d ... %d %d", V[0], V[1], V[N-2], V[N-1];
This isn't code you are actually running, as it is missing a ), and str is undefined. However, what this would do is write four values to str (not the screen), being values 0, 1, 8 and 9 (i.e. the first 2 and last 2 values), i.e. the characters 0 1 0 0 plus a terminating NULL.
As you are using sprintf() not snprintf() you have no way of checking whether this will overflow str.
It's difficult to tell what you are then doing because of the formatting of the question, but it appears you are calling a function array that might or might not modify the array and print it out again. However, your assembler function is defined as:
__asm void array (int V[], int N, int V) ....
which has an array / pointer parameter called V, a second parameter called N (though the main program #defines this to 10 (so that won't work), and a third parameter also called V which won't work as that's the name of the first parameter.
You also have a mysterious X defined to 10, which is then unused.
It's not particularly clear what you are asking and it would be better if you posted a small working code snippet, but I hope the above is of help.

Resources