2017-12-18 17 views
0

たとえば、st[]="morty"のように連続して文字列要素を追加したい場合、その要素をたとえば7回繰り返します。 st[]="mortymo"である必要があります。私は以下の関数を書いた。 (長さ関数はstrlenです)。あなたのrepeat機能でCで文字列要素を連続して追加する方法は?

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; 
     } 
    } 
+2

あなたはメモリを割り当て、ptr' 'でそのアドレスを格納しますが、あなたは' PTRを破棄します'関数の最後に。これはメモリをリークするだけでなく、操作の結果を破棄します。あなたは 'ptr'を返すべきではありませんか? – cdhowie

+1

また、割り当てられた文字列もNULL終了する必要があります。 –

+1

それは何をすべきか対何をすべきか? –

答えて

0

、あなたは繰り返される文字列を保持するためにptrを割り当てられていますが、stに戻すか、割り当てられませんでした。

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); 

あなたは後にstで繰り返される文字列の結果を格納しているというようなを次のようにあなたのrepeat機能を変更することができます。

+1

末尾のnullを追加したことはありません。 – Barmar

+0

@Barmarあなたは正しいです!今すぐ修正しました – mckuok

0

私は割り当てを正しく理解していれば、デモプログラムに示されているような関数が必要です。

#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; 
} 

プログラムの出力は、関数は元の文字列が空の場合は繰り返すものがないので、その後、結果の文字列も空であるように設計されていることに

Hi, Zusaetlich.Hi, Zusaetlich. 

ご注意です。

関数では、関数に割り当てられたメモリが解放されないため、少なくともメモリリークが発生します。

また、元の文字列は変更されていないため、対応するパラメータはconst指定子で修飾する必要があります。 2番目のパラメータの型はsize_tである必要があります。少なくとも、関数strlenの戻り型はsize_tです。

したがって、関数はデモプログラムで示されているように宣言する必要があります。

+0

コードを投稿して、彼のバージョンに間違っていた点や修正方法を説明しないでください。 – Barmar

1

以下のプログラムは、元の文字列の文字を繰り返します。コード内 コメント:

#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 
0

あなたはstの内容を変更するつもりはありませんので、先に行くとconstとしてそれを宣言する。あなたの関数に新しい文字列を割り当てるつもりなので、それを呼び出し側に返すべきです。

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

kは問題ではありません。標準関数を呼び出します。これはC. sizeof(char)で致命的なエラーが成功のためのmalloc呼び出しの結果を確認し、常に1です。隠すことができるよう

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

は、mallocの結果をキャストしないでください。

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

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

アイドルには[]でアクセスします。iの場合はkが増分しますが、モジュロ演算を適用する場合はkとなります。ただし、Cにはモジュロ演算子があります。これはiで直接使用できます。

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

新しい文字列がNULであることを確認してください。あなたの関数は結果を返すと宣言されていますが、あなたの実装では結果が返されません。

Cには、作成したバイトごとのループではなく、あなたのために呼び出すことができる多くの機能があります。実装にはシンプルさがありますが、以下では、ソリューションに欠けている追加のエラーチェックも含まれています。

(一部はsprintfの使用に尻込みかもしれないが、それは正しく使用されている。)

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!

+1

OPリクエストのPOVからの答えに何が間違っているのかは不明ですが、エラーチェックを強化しました。 – jxh

関連する問題