Insert char into char array C (string) - c

I got the char array "anana" and I am trying to get a "B" into the beginning in the char array so it spells "Banana" but I cannot wrap my head around how to construct a simple while loop to insert the B and then move every letter one step to the right

Assuming:
char array[7] = "anana";
Then:
memmove(array+1, array, 6);
array[0] = 'B';
The memmove function is specifically for cases where the data movement involves an overlap.

You can use a more traditional approach using...
#include <stdio.h>
int main()
{
char s[] = "ananas";
char b[7] = "B";
for(int i = 0; i < 7; ) {
char temp = s[i++];
b[i] = temp;
}
printf("%s", b);
return 0;
}

Please follow these steps:
Create a new array of size 7 (Banana + terminator). You may do this dynamically by finding the size of the input string using strlen().
Place your desired character say 'B' at newArray[0].
Loop over i=1 -> 7
Copy values as newArray[i] = oldArray[i-1];

Related

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.

Assigning a char* to a char

So I'm very new to C, and I'm just starting to use pointers. I'm using a 2D array to convert a set of strings from hexadecimal to decimal, letter by letter. However, in the process, I have to take the first character of each string, and to do that I'm trying to assign them to a char.
This line specifically is giving me trouble.
aChar = input[j][i];
It keeps saying I can't convert from const char* to char, but no matter how I change it, I can't seem to get it to work.
Heres the full program:
#include <stdio.h>
#include "catch.hpp"
#include <unistd.h>
TEST_CASE("Listing 2.2")
{
int x;
int j = 0;
int i = 0;
x = 0;
const int N = 8;
char aChar;
const char* input[N][5] = {"a000", "ffff", "0400", "1111", "8888", "0190", "abcd", "5555"};
int answers[N] = {40960, 65535, 1024, 4369, 34952, 400, 43981, 21845};
for (j=0; j>N; j++){
for(i=0; i>5; i++){
aChar = input[j][i];
x = x << 4;
if (aChar <= '9')
{
x = x + (int)(aChar & 0x0f);
}
else
{
aChar = aChar & 0x0f;
aChar = aChar + 9;
x = x + (int)aChar;
}
CHECK(answers[j] == x);
}//end for 1
}//end for 2
printf("End of program.\n");
}
Any help would be appreciated!
input is a 2D array of pointer to characters. Effectively it has 3 dimensions. Two Dimensions of strings of N*5 and the third dimension will traverse the characters in each string.
const char* input[N][5]
If you want the first character of each string, you need to use
aChar = input[j][i][0];
Here is the culprit:
const char* input[N][5] = {"a000", "ffff", "0400", "1111", "8888", "0190", "abcd", "5555"};
You want to declare an array to 8 strings of size 5 (4 digits + terminating null) but actually declare an array of 8 arrays of 5 pointers.
What you want is:
const char input[N][5] = {"a000", "ffff", "0400", "1111", "8888", "0190", "abcd", "5555"};
I'm using a 2D array
In order to use a 2D array of char you should declare: const char input[N][5]. const char* input[N][5] is a 2D array of char* (instead of an array of strings you get a 2D array of strings).
Given your declaration, no wonder that a aChar = input[j][i]; results in an assignment of a char* to a char, which is an error.
You used the wrong condition for your for loops.
You initialized your loop variable (i/j) with 0 but you ask for the loops to be terminated if the i/jis bigger than 5/N.
If you want to iterate over your whole 2 dimensional array it should look like this:
( '<' instead of '>')
for (j=0; j<N; j++){
for(i=0; i<5; i++){
//... your code
}//end for 1
}//end for 2
aChar = input[j][i];
In this statement, you are trying to assigning const pointer address to char,
It is wrong statement.
You need to reference the pointer variable then assign to the corresponding variable,
Can you change the statement as,
aChar = *input[j][i];

Creating an int value from multiple char array fields in C

I'm working on a C program and i am struggling with it (I've been spoiled by the concept of object orientation).
What i want to do is this:
I want to put values in a char array into an int. So for example i have char[0] == '1' and char[1] == '2'. I want to put these values in an int variable so its value is 12. I have tried looking but I am not sure how to get this done.
I really am poor at explaining so please ask for more info if necessary.
If your char array is made with characters '1' and '2':
char a[2];
a[0] = '1';
a[1] = '2';
int b = (a[0]-'0')*10 + (a[1]-'0');
If your char array is made with numbers 1 and 2:
char a[2];
a[0] = 1;
a[1] = 2;
int b = a[0] * 10 + a[1];
also, see: Why does subtracting '0' in C result in the number that the char is representing?
If the character array contains a string that is if it is zero-terminated then you can apply standard C function atoi declared in header <stdlib.h>.
For example
char s[] = "12";
int x = atoi( s );
If the array is not zero-terminated as
char s[2] = "12";
then you can convert its content to an integer manually.
For example
int x = 0;
for ( size_t i = 0; i < sizeof( s ) / sizeof( *s ); i++ )
{
x = 10 * x + s[i] - '0';
}
What you are trying to do is called parsing. In c this can be done with the atoi() function like this:
char s[] = "12";
int num = atoi(s);

Strange printf output in C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char * reverse(char *string);
int main(int argc, char *argv[])
{
char array[10];
array[0] = 'a';
array[1] = 'b';
array[2] = 'c';
array[3] = 'd';
array[4] = 'e';
printf("1%s\n",array);
char *p = reverse(array);
printf("4%s\n",p);
printf("5%s\n",array);
}
char * reverse(char *string)
{
int size = strlen(string);
char reversed[size];
int i;
int j = 0;
for(i = size-1; i >= 0; i--)
{
reversed[j] = string[i];
j++;
}
printf("2%s\n",reversed);
string = reversed;
printf("3%s\n",string);
return reversed;
}
This code basically just initializes an array of values and passes it into a method that reverses these values.
I am not sure if this is the best way to execute the task, since I am new to pointers and arrays in C.
But the real question is this:
Can anyone figure out why in this line
printf("4%s\n",p);
if you remove the preceding '4', so it looks like so
printf("%s\n",p);
the line won't print at all?
You are returning a pointer to local variable(reversed) in the function reverse the question should actually be: Why did it work in the first place?.
This code string = reversed; will only copy the pointer, and again the local copy of the pointer so it has no effect outside the function.
To reverse a string you don't need additional memory - this can be done in-place.
Strings in C must end with the null character. You're using strlen on a non null-terminated string.
Furthermore, you just a very lucky person, because there is a serious problem with you code: you forget to add \0 symbol at the end of string.
UPD: the main problem is with code line char reversed[size];.
It's a regular local variable, it has automatic duration, which means that it springs into existence when the function is called and disappears when the function returns (see this link).
You need to change it to:
char *reversed = malloc((size+1)*sizeof(char));
UPD-2: another bug fixing will be:
1) add array[5] = '\0'; after all other array initializing lines
2) add reversed[j] = '\0'; after for...loop:
for(i = size-1; i >= 0; i--)
{
reversed[j] = string[i];
j++;
}
reversed[j] = '\0';
UPD-3: But in general it will much more correctly initialize your string in appropriate way:
char array[10] = "abcde";

Issues with reversing a string in place

I am writing a code to reverse a string in place:
void ReverseInPlace(char * x)
{
char * end = x;
int i;
i = 0;
char temp;
while(*end)
{
++end;//point tol end
++i;//count the lenght
}
--end;
printf("%s",end);
printf("%d",i);
while(i)
{
temp = *end;
printf("%s","\n");
printf("%c",temp);
end--;
x++;
i--;
}
printf("%s","\n");//blank line
printf("%s","\n");//blank line
printf("%s","-----");//blank line
printf("%s",x);//print original
}
Here are my confusions:
Even though I am able to print the characters in reverse, I want to reverse the string without using an array
I get error when I try to do the following:
*x = temp;
You say you are doing this:
ReverseInPlace("123456789");
You need to do something like this:
char str[] = "123456789";
ReverseInPlace(str);
Doing it the latter way allocates storage which you can modify, as opposed to modifying a literal string, which is illegal.
My proposal
#include <stdio.h> // printf
#include <string.h> // strlen
void swap(char* a , char* b)
{
char tmp;
tmp=*a;
(*a) = (*b);
(*b) = tmp;
}
void ReverseInPlace(char * x)
{
char * end = x;
int i,j,length;
char temp;
length = strlen(x);
//swap 1st with last, then 2nd with last-1, etc. Till we reach the middle of the string.
for(i=0,j=length-1 ; i<j ; ++i,--j)
swap( &x[i] , &x[j]);
}
main (){
char str[] = "123456789";
ReverseInPlace(str);
//ReverseInPlace("1234"); // this would lead to error, because "1234", can not be modified
printf("%s\n",str);
}
After middle is reached, you would swap elements which were already swapped by previous iterations. For illustration:
char* x = "1234";
1 2 3 4
4 2 3 1
4 3 2 1 // already reversed!
4 2 3 1
1 2 3 4 // if we continue till i==length-1 && j=0 , then we just get where we started
char *p="abcd123"; // ........string literal stored in read only memory mostly in text segment(where the code is stored) so you should never change value here as it may crash your program by writing onto code. Here p is pointing to address which maybe in text segment.
char q[]="abcd1234"; //..... the values can be changed and array size can be modified but address cant be changed because the array is nothing but a constant pointer. That's the problem with your code .....you are calling the function and parameter is a string literal whereas it should be a constant pointer. Further the storage class here is stack so u can modify the values.

Resources