2

そのため、K&R を使用してポインター付きの C コードを書く練習をしていました。strcat関数の1 つの問題については、自分のコードの何が問題なのかを見つけることができませんでした。Visual Studio によると、strcat 関数の後に目的の文字列が変更されずに返されました。どんな提案でも大歓迎です!

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int strcat(char* s, char* t);
int main(void)
{
char *s="hello ", *t="world";
strcat(s,t);
printf("%s",s);
return 0;
}

int strcat(char* s,char* t)
{
int i;
i=strlen(s)+strlen(t);
s=(char*) malloc(i);
while(*s!='\0')
    s++;
while('\0'!=(*s++=*t++))
    ;
return 0;
}
4

6 に答える 6

1

 strcat(char* s, char* t) 

「s」は値で送信されます。呼び出し時の 's' の値がスタックにコピーされてから、strcat() が呼び出されます。strcat の戻り時に、変更されたバージョンはスタックから破棄されます。したがって、's' の呼び出し値は変更されません (メモリ リークが発生します)。

残念ながら、C では、パラメータや命令セクションであっても、すべてのメモリ セルを変更できます。一部の変更は非常に理解しにくい場合があります。

于 2013-07-09T07:39:36.300 に答える
1
  1. strcat実際の実装では a を返すと確信していますchar*(最初の文字列の元の値を保持しています)。
  2. strcat最初のパラメーターのアドレスを変更することは想定されていないため、 を呼び出すべきではありませんmalloc
  3. char *sポイント#2は、次のように宣言する必要があることを意味しますchar s[20]mainここで20、文字列全体を保持するのに十分な大きさの任意の数値)。

入力パラメーターの値を本当に変更したい場合は、値のアドレスを渡す必要があります。そのためstrcat(char **s, ...)、関数の宣言/定義に含まれ、strcat(&s, ...)inで呼び出される必要がありmainます。

于 2013-07-09T07:40:01.387 に答える
1

1) この方法で文字列を定義する

char *s="hello "

は、リテラル文字列が定義されていることを意味します。リテラル文字列は読み取り専用メモリに保存されるため、編集できません

文字列を編集できるようにするには、文字列を char 配列として定義する必要があります

char s[100] = "hello ";

2) この方法で関数を定義すると

int strcat(char* s,char* t)

sのアドレスを関数に変更することはできませんstrcat()。したがって、メモリを関数に割り当てても、関数を終了するときにアドレスmalloc()は変更されませんs

3) 関数 strcat を次のように変更します

int strcat(char** s,char* t)
{
    int i;
    char *u, *v;
    i=strlen(*s)+strlen(t);
    v = *s;
    u=(char*) malloc(i+1);
    while(*v!='\0')
        *u++ = *v++;
    while('\0'!=(*u++=*t++));
    *s = u;
    return 0;
}

そして、あなたはそれを主に次のように呼び出します:

char *s="hello ", *t="world";
strcat(&s,t);
于 2013-07-09T07:38:00.623 に答える
0

あなたは本当の strcat のようにやろうとしているので、最初のパラメータは

The string s1 must have sufficient space to hold the result.

したがって、malloc を使用する必要はありません。

char *strcat(char* s, const char* t);
int main(void)
{
  char s[15] = {0}; // 
  char *t = "world";  //const char * so you can't change it

  strcpy(s, "Hello ");
  strcat(s,t);
  printf("%s\n",s);
  return (0);
}

char *strcat(char* s, const char* t)
{
  int i = 0;

  while (s[i] != '\0')
    i++;
  while (*t != '\0')
    s[i++] = *t++;
  s[i] = '\0'; //useless because already initialized with 0
  return (s);
}
于 2013-07-09T08:15:38.657 に答える
0

親愛なるユーザー

それほど複雑にする必要はありません。ポインターを使用した の最も単純なコードstrcat:

void strcat(char *s, char *t) {
    while(*s++); /*This will point after the '\0' */
    --s; /*So we decrement the pointer to point to '\0' */
    while(*s++ = *t++); /*This will copy the '\0' from *t also */
}

ただし、これは連結の成功に関するレポートを提供しません。

main()残りの答えについては、この部分を見てください。

int main() {
    char s[60] = "Hello ";
    char *t  = "world!";

    strcat(s, t);
    printf("%s\n", s);

    return 0;
}

s[60]そのための十分なスペースがない場合、別の文字列を最後に連結することはできないため、この部分は非常に重要です。

于 2015-12-29T17:38:45.507 に答える
0
#include<stdio.h>
#include<string.h>
#define LIMIT 100
void strcatt(char*,char*);
main()
{   
int i=0;
char s[LIMIT];
char t[LIMIT];
strcpy(s,"hello");
strcpy(t,"world");
strcatt(s,t);
printf("%s",s);
getch();
}
void strcatt(char *s,char *t)
{   

while(*s!='\0')
{    
 s++;
}
*s=' ';
++s;
while(*t!='\0')
{
    *s=*t;
    s++;
    t++;
}
*s=*t;
}
于 2014-05-21T15:34:02.973 に答える