My head is getting bad trying to find a solution for this assignment because my ideas didn't work...
I have to interlace two char strings using pointers. See the following example (this example is not code):
char s1 = "My House Black"
char s2 = "Are very near"
Result: "MAyr eH ovuesrey Bnleaacrk"
How can I do this?
Try:
int total = strlen(char1) + strlen(char2);
int i1 = 0, i2 = 0;
for(i = 0; i < total; i++)
{
if(i % 2 == 0)
{
result[i] = char1[i1];
i1++;
}
else
{
result[i] = char2[i2];
i2++;
}
}
Here's a hint (pseudocode):
result = ""
for i = 0 to longest string's length:
result += some character (whose?)
result += another character (also, whose?)
Be careful: you need a little check somewhere, otherwise bad things might happen.
Since this is homework, I will just give you an outline.
First of all declare your two strings:
const char *s1 = "My House Black";
const char *s2 = "Are very near";
Next declare two pointers to char:
char *p1 = s1;
char *p2 = s2;
Now enter a while loop. The condition should be that *p1 or *p2 are not equal to zero.
Inside the loop output *p1 if it is not zero and then output *p2 if it is not zero. Increment each pointer if it refers to a non-zero character.
That's it, you are done!
Since this is tagged homework, I don't want to directly post code. But create three character arrays, one for each input, one long enough to contain the output, and traverse the input character arrays one character at a time (use pointer arithmetic). Store the character into your output string. Continue until you reach the end of each string. Don't forget the null terminations!
You need a target string that is large enough to hold both input strings and the string terminator.
Then you should probably use a loop (while or for) where you copy one character from each input string in each iteration.
For extra credits:
Consider the case where the input strings are of unequal length.
Is this what you want?
char * s1 = "My House Black";
char * s2 = "Are very near";
char * s = (char *)malloc(strlen(s1) + strlen(s2) + 1);
char * p1 = s1;
char * p2 = s2;
char * p = s;
while (*p1 && *p2)
{
*p++ = *p1++;
*p++ = *p2++;
}
while (*p1)
{
*p++ = *p1++;
}
while (*p2)
{
*p++ = *p2++;
}
*p = '\0';
Related
so I was working on creating the raw function of concatenating a string in c. One solution that was provided to me was :
char *_strcat(char *dest, char *src)
{
int c, c2;
c = 0;
while (dest[c])
c++;
for (c2 = 0; src[c2] ; c2++)
dest[c++] = src[c2];
return (dest);
}
The part that confuses me is while (dest[c]), and other similar parts. I've already gone through pointers through various resources but I can't seem to understand this part. A good explanation will be much appreciated.
For starters the function is incorrect. It does not build a concatenated string because it does not append the terminating zero character '\0' to the result (dest) string in this for loop
for (c2 = 0; src[c2] ; c2++)
dest[c++] = src[c2];
Also the function should be declared like
char * _strcat( char *dest, const char *src );
because the appended string (src) is not changed.
This while loop
while (dest[c])
c++;
is equivalent to
while (dest[c] != '\0' )
c++;
and this for loop
for (c2 = 0; src[c2] ; c2++)
dest[c++] = src[c2];
is equivalent to
for (c2 = 0; src[c2] != '\0' ; c2++)
dest[c++] = src[c2];
That is the loops continue their iterations until the terminating zero character '\0' is encountered in the while loop in the string dest (to find its end) and in the second loop in the string src to find its end..
A non-zero scalar expression is evaluated as a logical true in conditions.
And the variables c and c2 should have the unsigned type size_t instead of the type int because objects of the type int can be not large enough to store string lengths.
Also you should not define names starting from the underscore character.
As for your question
How exactly does pointer value incrementing work?
then the pointers themselves are not incremented. There are used expressions with the subscript operator to access elements of strings as for example dest[c] or dest[c++] or src[c2].
The function can be defined the following way
char * my_strcat( char *dest, const char *src )
{
char *p = dest;
while ( *p != '\0' ) ++p;
while ( ( *p++ = *src++ ) != '\0' );
return dest;
}
In the shown function there are indeed incremented pointers p and src and neither expression with the subscript operator is used..
char *dest is an pointer to char and it's pointed to the first character by default. Then the following loop will move the pointer offset to the end of the string.
c = 0;
while (dest[c])
c++;
I am trying to replicate the strcmp() function from the string.h library and here is my code
/**
* string_compare - this function compares two strings pointed
* by s1 and s2. Is a replica of the strcmp from the string.h library
* #s1: The first string to be compared
* #s2: The second string to be compared
*
* Return: On success, it returns:
* 0 if s1 is equal to s2
* negative value if s1 is less that s2
* positive value if s1 is greater than s2
*/
int string_compare(char *s1, char *s2)
{
int sum = 0, i;
for (i = 0; s1[i] != '\0' && s2[i] != '\0'; i++)
sum += (s1[i] - s2[i]);
for ( ; s1[i] != '\0'; i++)
sum += (s1[i] - 0);
for ( ; s2[i] != '\0'; i++)
sum += (0 - s2[i]);
return (sum);
}
I tried my function using this sample code:
#include <stdio.h>
int main(void)
{
char s1[] = "Hello";
char s2[] = "World!";
printf("%d\n", string_compare(s1, s2));
printf("%d\n", string_compare(s2, s1));
printf("%d\n", string_compare(s1, s1));
return (0);
}
And I get the following output,
-53
-500
0
But I should be getting:
-15
15
0
Why am I getting such a result??
This approach is incorrect.
Let's assume that the first string is "B" and the second string is "AB".
It is evident that the first string is greater than the second string in the lexicographical order.
But the result will be negative due to this for loop
for ( ; s2[i] != '\0'; i++)
sum += (0 - s2[i]);
though the function shall return a positive value.
Moreover there can occur an overflow for the variable sum of the type int.
Also the function should be declared at least like
int string_compare( const char *s1, const char *s2);
because passed strings are not changed within the function.
The function can be defined the following way
int string_compare( const char *s1, const char *s2 )
{
while ( *s1 && *s1 == *s2 )
{
++s1;
++s2;
}
return ( unsigned char )*s1 - ( unsigned char )*s2;
}
You are overcomplicating very simple function.
#define UC unsigned char
int mystrcmp(const char *s1, const char *s2)
{
int result;
while(!(result = (UC)*s1 - (UC)*s2++) && *s1++);
return result;
}
Strings in C are arrays of characters terminated with a null character (\0).
When you pass a string to a function, you are passing a pointer to its first element. That pointer is passed by value. You can modify that pointer within the function without any side-effects on the string it points to, as long as you don't dereference and assign to the address it points to.
That's why the pointer math from
0___________'s answer works.
int mystrcmp1(const char *s1, const char *s2) {
int result = 0;
while(!(result = *s1 - *s2++) && *s1++);
return result;
}
*s1++ could be rewritten as *(s1++) to disambiguate. s1++ returns the current pointer to the beginning of the first string, and then increments the pointer so it points to the next character. That pointer is then dereferenced to give us the character. The same happens with the s2 pointer.
Then we're comparing them by subtraction. If they're the same, we get 0, which in C is false in a boolean context. This result is assigned to result.
We can now see that the loop continues while corresponding characters in the two strings are equal and while dereferencing s1 does not give us the null terminator.
When the loop continues it means there was either a difference or we reached the end of the first string.
The difference will be stored in result, which the function returns.
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.
This question already has answers here:
Extra characters added to end of string in c
(3 answers)
Closed 5 years ago.
I am writing a function in C which takes two strings of the same length,
for example:-
S1 = "Hello" and S2 = "12345"
and returns a result that mixes the characters from the input strings so that the first char in the result string is the first char from S1, the second char is the first char from S2, the third char in r is the second char from S1 and the fourth char in r is the second char from S2, and so on....
So if:-
S1 = "Hello"
S2 = "12345"
Result = "H1e2l3l4o5"
My function looks like this:
#include <stdio.h>
#include <string.h>
char* mix(char *s1, char *s2)
{
int length = strlen(s1);
char* result = malloc(sizeof(char) * length * 2);
int i, j;
for(i = 0, j = 0; i < (length); i++, j = j + 2)
{
result[j] = s1[i];
result[j + 1] = s2[i];
}
return result;
}
For the values of S1 and S2 above it produces:
`H1e2l3l4o5:=C:\Uºt6▄╘º`
Which confuses me as I didn't allocate "result" enough memory for that many chars and wasn't warned of a segmentation fault or anything of that nature. Have I obviously done something wrong?
This happens because you did not null-terminated the string in the result. Add this line to fix this problem:
result[j] = '\0';
Another issue you need to fix is allocating the space for null terminator:
char* result = malloc(length * 2 + 1);
C standard requires sizeof(char) to be 1, so multiplying by it is not necessary.
Finally, you need to make sure that s2 has enough length to be copied into the result, i.e. strlen(s2) >= strlen(1).
You didn't allocate memory for the null character required to terminate a C string and, of course, you didn't put it after the string. This is why the code prints garbage from memory until it reaches the first null character.
char* mix(char *s1, char *s2)
{
int length = strlen(s1);
char* result = malloc(sizeof(char) * (length * 2 + 1));
int i, j;
for(i = 0, j = 0; i < length; i ++, j = j + 2)
{
result[j] = s1[i];
result[j + 1] = s2[i];
}
// Put the null character to end the the string
result[j] = 0;
return result;
}
Apparently the code should also check the length of s2 but, by chance, this is not needed.
If s1 is longer than s2, the null-terminating character of s2 is copied during the loop and the length of the resulting string is 2*strlen(s2). If s2 is longer than s1, the code copies only its first length characters.
Is this possible? That is, append a single char to a char*?
char temp[10] = "";
while (isalnum(*x)) {
strcat(temp, *x);
x++;
}
enqueue(&head,temp);
I have a queue which has a char* as a variable. Then I have a char* to be read, and if the char that it's pointing to is alphanumeric, I want it to append to temp. And after that, enqueue it.
Since x appears to be a char *, you can use strncat().
while (isalnum(*x)) {
if (bytes_left_in_temp > 0) {
strncat(temp, x, 1);
}
}
More efficiently, you can count how items in x can be copied, and then pass the count instead of 1.
int k = 0;
while (isalnum(x[k])) {
if (k >= bytes_left_in_temp) break;
++k;
}
strncat(temp, x, k);
However, you should make sure you take care not to append past what temp can hold, as illustrated above.
Assuming temp will allways be large enough:
char temp[10] = "";
char *p = temp;
while (isalnum(*x)) {
*p++ = *x++;
}
*p = '\0';
enqueue(&head,temp);
If you're not sure if temp will allways be large enough, add some checks (which shouldn't need
detailed explanation).
If x is char*, then you can use strcat(temp,x)