Zusaetlich
Zusaetlich

Reputation: 3

How to add string elements successively in C?

I want to add string elements successively, for example st[]="morty", and I want to repeat its elements for example seven times. It should be st[]="mortymo". I wrote a function which is at below. (The length function is strlen).

    void repeat(char* st,int n){
         int i,k=0,l=length(st);
         char* ptr;
         ptr=(char*)malloc((n+1)*sizeof(char));
         for (i=0;i<n;i++){
              *(ptr+i)=*(st+k);
              k++;
              if(k==l)k=0;
         }
    }

Upvotes: 0

Views: 156

Answers (4)

jxh
jxh

Reputation: 70472

Since you don't intend to modify the contents of st, go ahead and declare it as const. Since you intend to allocate a new string in your function, you should return it to the caller.

char *repeat(const char* st,int n){

k is unnecessary for your problem. Call the standard functions.

     int i,l=strlen(st);
     char* ptr;

Don't cast the result of malloc, as this can mask a fatal error in C. sizeof(char) is always 1. Check the result of the malloc call for success.

     ptr=malloc(n+1);
     if (ptr == NULL) return NULL;

     for (i=0;i<n;i++){

Access arrays idiomatically with []. Note that k increments whenever i does, but you are applying a modulo operation of k. However, C has a modulo operator, which you can use directly on i.

          ptr[i]=st[i%l];
     }

Make sure the new string is NUL terminated. Your function is declared to return a result, but your implementation fails to do so.

     ptr[n] = '\0';
     return ptr;
}

C has many functions you can call to do the copying for you rather than the byte by byte loop you have written. There is simplicity in your implementation, but below is an alternative, that also includes additional error checking that is lacking in your solution.

(Some may balk at the use of sprintf, but it is being used correctly.)

char *
repeat (const char *st, int n) {
    int l = st ? strlen(st) : 0;
    char *ret = (st && n > 0 ? malloc(n+1) : 0), *p = ret;
    while (ret && n > 0) {
        p += sprintf(p, "%.*s", (l < n ? l : n), st);
        n -= l;
    }
    return ret ? ret : "(nil)";
}

Try it online!

Upvotes: 0

sg7
sg7

Reputation: 6298

The program below repeats characters from the original string. Comments in the code:

#include<stdio.h>
#include<stdlib.h>

 char* repeat(const char* st, size_t n){
         // use `const` to note that pointer `st` will not be modified
         // for purity you may want to use type `size_t` since returning type of strlen is `size_t` 

         size_t i, k=0;
         size_t l = strlen(st);

         // do not use (char *) cast
         char* ptr = malloc((n+1)*sizeof(char)); // allocate enough room for characters + NULL

         for (i=0; i< n; i++)
         {
              ptr[i] = st[k]; // use index for readability
              k++;

            if (k == l)
                k=0;
         }

         ptr[i] = 0; // terminate the string


    return ptr;
 }

int main( )
{
    char *str = "12345";

    str = repeat(str, 15);

    printf("%s\n",str);

    free (str); // free the allocated memory inside the repeat function

    return 0;
}

OUTPUT:

123451234512345 

Upvotes: 1

Vlad from Moscow
Vlad from Moscow

Reputation: 311048

If I have understood the assignment correctly then you need a function like that one shown in the demonstrative program.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char * repeat( const char *s, size_t n )
{
    char *p = NULL;

    size_t len = strlen( s );

    if ( len == 0 ) n = 0;

    p = ( char * )malloc( n + 1 );

    if ( p )
    {
        size_t i = 0;

        for ( size_t j = 0; i < n; i++ )
        {
            p[i] = s[j];
            if ( ++j == len ) j = 0;
        }

        p[i] = '\0';
    }


    return p;
}

int main(void) 
{
    char *s = "Hi, Zusaetlich.";

    char *p = repeat( s, 2 * strlen( s ) );

    puts( p );

    free( p );

    return 0;
}

The program output is

Hi, Zusaetlich.Hi, Zusaetlich.

Pay attention to that the function is designed such a way that if the original string is empty then the resulted string is also empty because there is nothing to repeat.

As for your function then it has at least a memory leak because the memory allocated in the function is not freed.

Also as the original string is not changed then the corresponding parameter should be qualified with the const specifier. And the second parameter should have type size_t because at least the function strlen has the return type size_t.

So the function should be declared as it is shown in the demonstrative program.

Upvotes: 0

mckuok
mckuok

Reputation: 754

In your repeat function, you allocated ptr to hold the repeated string, but you didn't return or assign it to st. You can modify your repeat function as follows:

    char* repeat(char* st,int n){
         int i,k=0,l=strlen(st);
         char* ptr;
         ptr=(char*)malloc((n+1)*sizeof(char));
         for (i=0;i<n;i++){
              *(ptr+i)=*(st+k);
              k++;
              if(k==l)k=0;
         }
        *(ptr+n) = '\0';
        return ptr;
    }

    /* some code*/
    char *st = "morty";
    st = repeat(st, 7);

Such that you are storing the result of the repeated string in st after.

Upvotes: 0

Related Questions