How can I merge character by character two strings of different sizes to the n-th element of A and m-th element of B. I can easily do it when they have the same size (assuming here n=m). But cannot figure out how to handle this exception.
My working zip code is as follows:
char * zip(char *A, char *B, int n)
{
char *C;
int i;
C = malloc((2*n) * sizeof *A);
for(i=0; i<n; i++) {
C[(2*i)]=A[i];
C[(2*i)+1]=B[i];
}
return C;
}
But instead to pass just int n, I would like to pass also int m where n is to merge the n first elements of A and the m first elements of B. Hence passing the following input to the new_zip(char *A, char *B, int n, int m). A="rslxyzkw"; B="eutingxyz";n=3; m=6, I would get "resulting".
like this:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
char *new_zip(char *A, char *B, int n, int m){
assert(A != NULL && B != NULL && n >= 0 && m >= 0);
char *C = malloc(n + m + 1);//+1 for NUL
if(!C){
perror("malloc:");
return NULL;
}
int i = 0;
while(n + m > 0){
if(n > 0 && *A){
C[i++] = *A++;
--n;
}
if(m > 0 && *B){
C[i++] = *B++;
--m;
}
}
C[i] = 0;
return C;
}
int main (void){
char *result = new_zip("rslxyzkw", "eutingxyz", 3, 6);
printf("'%s'\n", result);
free(result);
return 0;
}
Instead of looping until a certain length you can loop until you run out of characters. C strings have a null character at the end so after you allocate the memory you can loop as long as both aren't a null character. All you need to do then is only add non-null characters to your output string.
#include <stdio.h> /* printf */
#include <stdlib.h> /* malloc, free */
#include <string.h> /* strlen */
char *zip(char *a, char *b)
{
char *c = malloc( (strlen(a)+strlen(b)+1) * sizeof(char) ), *p = c;
if(c)
{
while(*a || *b) /* while either string has characters */
{
if(*a) *p++ = *a++; /* add a character from a if non-null */
if(*b) *p++ = *b++; /* add a character from b if non-null */
}
*p='\0'; /* finish the string with a null character */
}
return c;
}
int main()
{
char *a = "This is a string";
char *b = "This is another longer string";
char *c = zip(a,b);
if(c)
{
printf("zip(%s,%s) = %s\n",a,b,c);
free(c);
}
return 0;
}
The following could work.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* zip(char* A, char* B) {
char *C;
int k = 0;
C = (char*)malloc(strlen(A)+strlen(B)+1);
while (*A != '\0' || *B != '\0') {
if (*A != '\0') {
C[k++] = *A;
++A;
}
if (*B != '\0') {
C[k++] = *B;
++B;
}
}
C[k] = '\0';
return C;
}
int main() {
char *A = "123456", *B = "abcd", *C;
C = zip(A, B);
puts(C);
return 0;
}
The below code would work in the following way:
First do alternate merging from strings s1 and s2 based on the minimum value of m and n.
The second part would take care of appending the remaining elements either from s1 or from s2.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char* merge (char *s1, char *s2, int m, int n)
{
char *s = (char *) malloc(m + n + 1);
int min = (m < n)? m: n;
int i = 0, j = 0, k = 0;
int count = 0;
/* Alternate merge from s1 and s2 to s*/
while (count < 2 * min) {
if (count % 2 == 0) {
s[k++] = s1[i++];
} else {
s[k++] = s2[j++];
}
count++;
}
/* Append the remaining elements from s1 or s2 to s*/
if (m > min) {
for (count = 0; count < m - min; count++) {
s[k++] = s1[i++];
}
} else if (n > min) {
for (count = 0; count < n - min; count++) {
s[k++] = s2[j++];
}
}
s[k++] = '\0';
return s;
}
int main()
{
char *s1 = "rslxyzkw";
char *s2 = "eutingxyz";
char *s = merge(s1, s2, 3, 6);
printf ("%s\n", s);
}
Related
bool in_array(char a[], char input, int len){
for (int l = 0; l < len; l++){
}
}
return false;
}
int main(void) {
char i = 'l';
int count = 0;
int count_d = 0;
char a[1000] = {0};
else{
count_d++;
}
}
printf("%d\n", count_d);
}
this is the code i have but this returns numbers of times it has duplicated
as there are two characters a and b
If you have learnt only arrays and do not know how to allocate memory dynamically then use a second array to store unique duplicated characters.
Here is a demonstrative program.
#include <stdio.h>
#include <stdbool.h>
bool in_array( const char a[], size_t n, char c )
{
size_t i = 0;
while ( i != n && a[i] != c ) i++;
return i != n;
}
int main(void)
{
enum { N = 128 };
char a[N];
char b[N / 2];
size_t count_duplicates = 0;
size_t count = 0;
char c;
while ( count < N && scanf( " %c", &c ) == 1 )
{
if ( !in_array( a, count, c ) )
{
a[count++] = c;
}
else if ( !in_array( b, count_duplicates, c ) )
{
b[count_duplicates++] = c;
}
}
printf( "There are %zu duplicated character(s).\n", count_duplicates );
return 0;
}
If to enter the sequence of characters
aaabbaaac
then the program output will be
There are 2 duplicated character(s).
i hope it will help you :
`#include <unistd.h>
#include <stdio.h>
#include <string.h>
int in_a(char *a, char c)
{
for (int i = 0; i < strlen(a); i++)
if (a[i] == c)
return 0;
return (1);
}
int main(int ac, char **av)
{
int count_duplicates = 0;
int same = 0;
char old = 0;
char new[128] = {0}; // i
int count = 0;
char *a = av[1];
while (a[count] != '\0') {
if (old != a[count] && in_a(new, a[count])) {
same = 0;
}
if (a[count] == old && same != 1) {
count_duplicates += 1;
same = 1;
}
old = a[count];
new[count] = a[count];
count += 1;
}
printf("%i\n", count_duplicates);
return (0);
}`
Given two sorted strings, I need to merge these strings to one string, and make it sorted.
sort by the ASCII value. for example:
acdty, berz => abcdertyz
My code:
#include <stdio.h>
#include <stdlib.h>
char* PairSortedArrays(char a[], char b[]) {
char* c = (char*)malloc((sizeof(a) + sizeof(b)) * sizeof(char));
int i, aPos = 0, bPos = 0;
for (i = 0; i < sizeof(*c); i++) {
if ((int)(a[aPos]) <= (int)(b[bPos])) {
c[i] = a[aPos];
aPos++;
}
else {
c[i] = b[bPos];
bPos++;
}
}
return c;
}
int main()
{
printf("%s", PairSortedArrays("acdty", "berz"));
return 0;
}
The first problem is with sizeof(a). if I code: printf("%d", sizeof(a)); it prints 8, while I expect it to print 5.
The expression i < sizeof(*c) controling the for loop is the main culprit. The corrected version of your program could be: (I edited the code a bit)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* PairSortedArrays(const char a[], const char b[])
{
size_t i;
const size_t total_len = strlen(a)+strlen(b);
char *c = malloc(total_len + 1);
size_t aPos = 0, bPos = 0;
for (i = 0; i < total_len; i++) {
if (a[aPos] == '\0') {
strcpy(c + i, b + bPos);
break;
}
if (b[bPos] == '\0') {
strcpy(c + i, a + aPos);
break;
}
c[i] = a[aPos] < b[bPos] ? a[aPos++] : b[bPos++];
}
return c;
}
int main()
{
printf("%s\n", PairSortedArrays("acdty", "berz"));
printf("%s\n", PairSortedArrays("az", "ks"));
return 0;
}
The return value of malloc must be checked against NULL in a real program. Also there is a memory leak (easy to fix).
When working with strings in C, you will want to be using strlen() to see how long they are, not sizeof (which merely tells you what the size of a pointer is).
Also note that sizeof(char) is 1 by definition, so there's no need to say "* sizeof(char)" in your malloc
sizeof(a) will return the size of a pointer in this case which will be 8 bytes if you compile for 64 architecture.
you have to either pass the size of each string or loop the string characters until you reach the '\0' if the string is null-terminated.
You should consider using qsort:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int compare_chars(const void *p1, const void *p2)
{
return *(const char *)p1 - *(const char *)p2;
}
char *PairSortedArrays(char *a, char *b)
{
char *c = malloc(strlen(a)+strlen(b)+1);
strcpy(c, a);
strcat(c, b);
qsort(c, strlen(c), sizeof(char), compare_chars);
return c;
}
int main()
{
printf("%s", PairSortedArrays("acdty", "berz"));
return 0;
}
ok so I am learning C and I try to use simple functions to understand basics and here I am stuck whith a segmentation fault I can't manage to make this code working h3lp please thanks you all !!!
#include <stdio.h>
#include <stdlib.h>
int ft_sqrt(int nb) //square root
{
unsigned int i;
i = nb;
while (nb < (i * i))
i--;
if (nb == (i * i))
return (i);
if (nb > (i * i))
return (0);
}
void ft_strcpy(char *d, char *s) // string copy
{
while((*d++ == *s++))
;
}
int ft_strlen(char *s) // string length
{
int i = 0;
while(s[i] != '\0')
i++;
return (i);
}
char *ft_itoa(int n) // integer to ascii
{
char *s;
s = (char *)malloc(99);
s += ft_strlen(s);
*s = 0;
while((*--s == n % 10 + '0') && (n /= 10))
;
return (s);
}
int ft_atoi(char *s) //ascii to integer
{
int i = 0;
while(*s)
i = 10 * i + *s++ - '0';
return (i);
}
int main()
{
int ft_sqrt(int nb);
void ft_strcpy(char *d, char *s);
char *ft_itoa(int n);
int ft_atoi(char *s);
int ft_strlen(char *s);
int a, *x;
a = 0;
char c[40], d[4];
c[40] = 0;
d[4] = 0;
a = ft_sqrt(1764); //42 in a
ft_strcpy(d, ft_itoa(a)); // a in d
ft_strcpy(c, "The square root of 1764 is: ");
x = ft_atoi(d);
printf("\n\n\t%s%sand%cin ascii\n\n\n", c, d, x);
return 0;
}
Just hack my code just wanna learn !!
There are many bugs in your code
When the nb is not a perfect square number, then it will give 0 always. Try it yourself. Use sqrt() instead (available under math.h header file)
Your ft_strcpy() is not properly framed, use strcpy() under string.h header file instead. Prototype : void strcpy(char *str1, char *str2),here the content of str2 will be copied to the str1.
char *ft_itoa(int n) may not properly work because you have provided wrong value to ft_strlen() which may turn out wrong value to be added to the pointer *s ( Why ?. Think your self , i'm not gonna tell you that elementary concept).
Do re-code your program and let me know if still can't fix the Error.
Hey #BLUEPIXY thanks for your help you fixed my atoi ! #psyco thank you here is my code fixed btw with the same value to ft_strlen() for *ft_itoa(int n).
#include <stdio.h>
#include <stdlib.h>
int ft_sqrt(int nb)
{
unsigned int i;
i = nb;
while (nb < (i * i))
i--;
if (nb = (i * i))
return (i);
if (nb > (i * i))
return (0);
}
void ft_strcpy(char *d, char *s)
{
while((*d++ = *s++))
;
}
int ft_strlen(char *s)
{
int i = 0;
while(s[i] != '\0')
i++;
return (i);
}
char *ft_itoa(int n)
{
char *s;
s = (char *)malloc(99);
s += ft_strlen(s);
*s = 0;
while((*--s = n % 10 + '0') && (n /= 10))
;
return (s);
}
int ft_atoi(char *s)
{
int i = 0;
while(*s)
i = 10 * i + *s++ - '0';
return (i);
}
int main()
{
int ft_sqrt(int nb);
void ft_strcpy(char *d, char *s);
char *ft_itoa(int n);
int ft_atoi(char *s);
int ft_strlen(char *s);
int a;
a = 0;
char c[40], d[4];
c[40] = 0;
d[4] = 0;
a = ft_sqrt(1764);
ft_strcpy(d, ft_itoa(a));
ft_strcpy(c, "The square root of 1764 is: ");
printf("\n\n\t%s%s and %c in ascii\n\n\n", c, d, ft_atoi(d));
return 0;
}
BugFixed thank you all
I have created two arrays that need to be concatenated after the second array (y in this case) has been rotated. However I want to rotate only the last 4 bytes of this array. This is my code:
char x[]={"hello"};
char y[]={"goodmorning"};
char combine[20];
strcpy(combine, x);
strcat(combine, y);
printf(combine);
Here before the concatenation into combine I want to do the rotation operation.
before rotation
combine= hellogoodmorning
after rotation
combine= gninhellogoodmor
I have tried to look for a logic to do this online but could not find anything specific. Can anybody please help.
void strRev(char *s)
{
char temp, *end = s + strlen(s) - 1;
while( end > s)
{
temp = *s;
*s = *end;
*end = temp;
--end;
++s;
}
}
char x[]={"hello"};
char y[]={"goodmorning"};
char combine[20];
strcpy(combine, x);
strcat(combine, y);
strRev(combine);
strRev(combine+4);
printf(combine);
I use
#define swap(a, b) { a ^= b; b ^= a; a ^= b; }
void reverse(char * s, int beg, int end) {
while (beg < end) {
swap(s[beg], s[end]);
++beg, --end;
}
}
void rotate(char * s, int k) {
if (!s || !*s) return;
int len = strlen(s);
k %= len;
reverse(s, 0, len - 1);
reverse(s, 0, k - 1);
reverse(s, k, len - 1);
}
and call rotate(combine, 4); to rotate 4 bytes in combine.
Try something like this shown below. I use strncpy instead of strcpy() and strcat(). Try to debug for better understanding. Run Live.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ROTATION_LEN 4
int main() {
char x[] = { "hello" };
char y[] = { "goodmorning" };
char c;
char combine[20] = {0}; // init with null
char * com = combine;
int i;
int leny = strlen(y);
int lenx = strlen(x);
for (i = 0; i < ROTATION_LEN; ++i) {
c = y[leny -1 - i];
combine[i] = c;
}
com += ROTATION_LEN; // forward address of combine by ROTATION_LEN
strncpy(com, x, lenx);
com += lenx; // forward address of combine by x length
strncpy(com, y, leny - ROTATION_LEN);
printf(combine);
return 0;
}
Output:
gninhellogoodmor
If you define a function like this:
void rotate_last_four(char *string)
{
char old_four[4];
char new_four[4];
strncpy(old_four, string + strlen(string) - 4, 4);
new_four[0] = old_four[3];
new_four[1] = old_four[2];
new_four[2] = old_four[1];
new_four[3] = old_four[0];
memmove(string + 4, string, strlen(string) - 4);
strncpy(string, new_four, 4);
}
Then you only need to add this line to your code before printing combine:
rotate_last_four(combine);
And the output is: gninhellogoodmor
I have a program that takes a char array and calls the function convert. The function determines whether the character is a letter or number. The program is supposed to output the first letter it finds in the string. and the first numbers it finds in the string. My loop to stop looking for letters after it finds one isn't working.
Any thoughts?
Code is written in C using the Borland Compiler.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int convert (char array[],char **);
int main()
{
int intval;
char array[512], *charptr;
printf("Input a string that starts with a series of decimal digits:\n>");
while ( gets( array ) != NULL ){
intval = convert(array, &charptr );
printf ("Intval contains %d, Charptr contains '%s'\n", intval, charptr);
}
system("pause");
return 0;
}
int convert (char array[],char ** charptr)
{
int i, x, c = 0;
char b[512];
for (i=0;i<strlen(array);i++){
if (isalpha(array[i]))
{
if(c >= 1){
*charptr = &array[i];
c++;
}
else
break;
}
else if ( isdigit(array[i]))
x = 10*x + array[i] - '0';
}
return x;
}
UPDATE:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int convert (char array[],char ** charptr);
int main()
{
int intval;
char array[512], *charptr;
printf("Input a string that starts with a series of decimal digits:\n>");
while ( gets( array ) != NULL ){
intval = convert(array, &charptr );
printf ("Intval contains %d, Charptr contains '%s'\n", intval, charptr);
}
system("pause");
return 0;
}
int convert (char array[],char ** charptr)
{
int i, x, c;
char b[512];
for (i=0;array[i] != 0;i++){
if ( isdigit(array[i]))
x = 10*x + array[i] - '0';
else if (isalpha(array[i]))
{
c++;
if(c >= 1){
*charptr = &array[i];
}
}
}
return x;
}
You have a logic error. c is initialized to 0. There is a line to increment c but it is inside an if block that will never be true.
if(c >= 1){
*charptr = &array[i];
c++;
}
Catch 22???
Perhaps you meant to use:
int convert (char array[],char ** charptr)
{
int i, x, c = 0;
char b[512];
for (i=0;i<strlen(array);i++){
if (isalpha(array[i]))
{
// No need for checking the value of c
// return as soon you find an alphabet.
*charptr = &array[i];
break;
}
else if ( isdigit(array[i]))
// If you are looking for an alphabet only,
// why do you have this block of code???
x = 10*x + array[i] - '0';
}
return x;
}
Update
Perhaps, this is what you are looking for.
int convert (char array[], char ** charptr)
{
size_t i;
int x = 0;
size_t len = strlen(array);
// Set charptr to NULL in case there are no letters in the input.
*charptr = NULL;
for (i=0;i<len;i++){
if ( isalpha(array[i]))
{
*charptr = &array[i];
return x;
}
else if ( isdigit(array[i]))
{
x = 10*x + array[i] - '0';
}
}
return x;
}
int scanString(char array[],char * charptr)
{
int len = strlen(array);
int digs = 0;
int x = 0;
*charptr = 0;
for (int i=0;i<len;i++){
if (charptr == 0 && isalpha(array[i]))
{
*charptr = array[i];
}
else if (digs == 0 && isdigit(array[i])){
x = array[i] - '0';
digs = 1;
}
if(digs > 0 && charptr != 0)
break;
}
return x;
}
the spec says return the first character found so changed the charptr.