Pointer version of strcat

huangapple go评论80阅读模式
英文:

Pointer version of strcat

问题

在你提供的代码中,你试图用指针来重新实现 strcat() 函数,但是当运行程序时,没有发生任何改变。a 数组没有受到任何影响。你做错了什么?

翻译结果:

在提供的代码中,您尝试使用指针重新实现 strcat() 函数,但当运行程序时,未发生任何更改。a 数组没有受到任何影响。您做错了什么?

英文:
#include <stdio.h>

void strpcat(char *s, char *t) {
    int i = 0;
    while (*s++ != '
#include <stdio.h>
void strpcat(char *s, char *t) {
int i = 0;
while (*s++ != '\0')
i++;
while ((*(s+i) = *t++) != '\0')
i++;
}
int main(void) {
char a[20] = "Hello";
char b[] = "Bye";
strpcat(a, b);
printf("%s\n", a);
return 0;
}
') i++; while ((*(s+i) = *t++) != '
#include <stdio.h>
void strpcat(char *s, char *t) {
int i = 0;
while (*s++ != '\0')
i++;
while ((*(s+i) = *t++) != '\0')
i++;
}
int main(void) {
char a[20] = "Hello";
char b[] = "Bye";
strpcat(a, b);
printf("%s\n", a);
return 0;
}
') i++; } int main(void) { char a[20] = "Hello"; char b[] = "Bye"; strpcat(a, b); printf("%s\n", a); return 0; }

I wanted to write rewrite the strcat() function with pointers, but when I run the program nothing changes.

Nothing affects to a array, what did I do wrong?

答案1

得分: 2

以下是代码部分的翻译:

The one problem is this while loop
一个问题在于这个while循环

    while (*s++ != '\0')
        i++;

If `*str` is equal to `'\0'` nevertheless the pointer `s` is incremented. So the original string will not be changed. At least the second string will be appended to the array after the source string.
如果`*str`等于`'\0'`,尽管指针`s`被递增了。因此原始字符串不会被更改。至少第二个字符串将附加到源字符串之后。

Another problem is using the variable `i` in the second while loop
另一个问题是在第二个while循环中使用变量`i`

    while ((*(s+i) = *t++) != '\0')
         i++;

because the pointer `s` was already incremented in the previous while loop. Using the incremented variable `i` and the incremented pointer `s` the pointer expression `s + i` will have an incorrect address.
因为指针`s`已经在前一个while循环中递增了。使用递增的变量`i`和递增的指针`s`,指针表达式`s + i`将具有不正确的地址。

The variable `i` is redundant.
变量`i`是多余的。

The function can be declared and defined the following way
可以如下声明和定义该函数

    char * strpcat( char *s, const char *t ) 
    {
        char *p = s;
    
        while ( *p ) ++p; 
    
        while ( ( *p++ = *t++ ) != '\0' );
    
        return s;
    }

and called like
然后像这样调用

    puts( strpcat( a, b ) );

Pay attention to that the second parameter should be declared with the qualifier `const` because the second passed string is not changed within the function. Also you could add the qualifier `restrict` as in the standard function `strcat`
请注意,第二个参数应该用限定符`const`声明,因为在函数内部不会更改第二个传递的字符串。此外,您还可以像标准函数`strcat`一样添加限定符`restrict`:

    char * strpcat( char * restrict s, const char * restrict t );
英文:

The one problem is this while loop

while (*s++ != '\0')
i++;

If *str is equal to '\0' nevertheless the pointer s is incremented. So the original string will not be changed. At least the second string will be appended to the array after the source string.

Another problem is using the variable i in the second while loop

while ((*(s+i) = *t++) != '\0')
i++;

because the pointer s was already incremented in the previous while loop. Using the incremented variable i and the incremented pointer s the pointer expression s + i will have an incorrect address.

The variable i is redundant.

The function can be declared and defined the following way

char * strpcat( char *s, const char *t ) 
{
char *p = s;
while ( *p ) ++p; 
while ( ( *p++ = *t++ ) != '\0' );
return s;
}

and called like

puts( strpcat( a, b ) );

Pay attention to that the second parameter should be declared with the qualifier const because the second passed string is not changed within the function. Also you could add the qualifier restrict as in the standard function strcat

char * strpcat( char * restrict s, const char * restrict t );

答案2

得分: 1

你把它搞得太复杂了:

void strpcat(char* s, char* t) {
  while (*s++ != '\0')
  { // 什么都不做
  }

  s--;   // 需要回退一个字符,使 s 指向 `\0`。

  while ((*s++ = *t++) != '\0')  // 删除复杂且错误的部分
  {
     // 什么都不做
  }
}
英文:

You're overcomplicating it:

void strpcat(char* s, char* t) {
while (*s++ != '\0')
{ // do nothing
}
s--;   // need to go back one char so s points to the `\0`.
while ((*s++ = *t++) != '\0')  // remove the fancy and wrong stuff
{
// do nothing
}
}

答案3

得分: 1

  • 移动到第一个字符串的末尾
  • 继续复制第二个字符串
void strpcat(char* s, char* t) {
  while (*s != '\0') { ++s; } // 移动到末尾
  while ((*s++ = *t++) != '\0') {} // 复制源字符串到目标字符串的末尾
}
英文:

2 steps approach:

  • Go to the NULL of first string
  • Continue to copy second string
void strpcat(char* s, char* t) {
  while (*s != '\0') { ++s; } // Go to the end
  while ((*s++ = *t++) != '\0') {} // Copy source to end of destination
}

答案4

得分: 0

以下是已经翻译好的部分:

如果应用KISS原则

#include <string.h>;

char* kisscat (char* restrict dst, const char* restrict src)
{
  char* end = dst + strlen(dst);
  strcpy(end, src);
  return dst;
}

现在,正如所发生的那样,这不仅更可读,而且可能比手动编写更快。因为这些库调用可能会被内联到一些非常高效的代码中。不像完全手工制作的函数。

英文:

If applying the KISS_principle:

#include &lt;string.h&gt;
char* kisscat (char* restrict dst, const char* restrict src)
{
char* end = dst + strlen(dst);
strcpy(end, src);
return dst;
}

Now as it happens this is not only more readable, but potentially also faster than rolling any of this out manually. Since these library calls might get inlined into some very efficient code. Unlike a completely hand-made function.

答案5

得分: 0

Your implementation increments s past the null pointer, then copies the string pointed to by t well past this position to s[i] and so on. The original null terminator is not overwritten, so printf("%s\n", a) still outputs Hello and the string is copied too far into the destination array, potentially beyond the end, causing undefined behavior.

If you want to use pointers, do not also use an index and increment only if not pointing to the null pointer already.

Here is a modified version:

#include <stdio.h>;

char *strpcat(char *s, const char *t) {
    while (*s != '\0')
        s++;
    while ((*s = *t++) != '\0')
        s++;
    return s;   // return a pointer to the null terminator.
}

int main(void) {
    char a[20] = "Hello";

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

    char *p = strpcat(a, " world!");

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

    strcpy(p, " Bye.");

    printf("%s\n", a);
    return 0;
}

Output:

Hello
Hello world!
Hello world! Bye.
英文:

Your implementation increments s past the null pointer, then copies the string pointed to by t well past this position to s[i] and so on. The original null terminator is not overwritten, so printf(&quot;%s\n&quot;, a) still outputs Hello and the string in copied too far into the destination array, potentially beyond the end, causing undefined behavior.

If you want to use pointers, do not also use an index and increment only if not pointing to the null pointer already.

Here is a modified version:

#include &lt;stdio.h&gt;
char *strpcat(char *s, const char *t) {
while (*s != &#39;\0&#39;)
s++;
while ((*s = *t++) != &#39;\0&#39;)
s++;
return s;   // return a pointer to the null terminator.
}
int main(void) {
char a[20] = &quot;Hello&quot;;
printf(&quot;%s\n&quot;, a);
char *p = strpcat(a, &quot; world!&quot;);
printf(&quot;%s\n&quot;, a);
strcpy(p, &quot; Bye.&quot;);
printf(&quot;%s\n&quot;, a);
return 0;
}

Output:

Hello
Hello world!
Hello world! Bye.

huangapple
  • 本文由 发表于 2023年3月31日 18:06:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/75897259.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定