简体   繁体   English

字符串连接在C中没有strcat

[英]String concatenation without strcat in C

I am having trouble concatenating strings in C, without strcat library function. 我在C语言中连接字符串时遇到问题,没有strcat库函数。 Here is my code 这是我的代码

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

int main()
{
  char *a1=(char*)malloc(100);
  strcpy(a1,"Vivek");
  char *b1=(char*)malloc(100);
  strcpy(b1,"Ratnavel");
  int i;
  int len=strlen(a1);

  for(i=0;i<strlen(b1);i++)
  {
     a1[i+len]=b1[i];
  }

  a1[i+len]='\0';                
  printf("\n\n A: %s",a1);

  return 0;
}

I made corrections to the code. 我对代码进行了更正。 This is working. 这很有效。 Now can I do it without strcpy? 我现在可以不用strcpy吗?

 char a1[] = "Vivek";

Will create a char array a1 of size 6 . 将创建一个大小为6的char数组a1 You are trying to stuff it with more characters than it can hold. 你试图用更多的字符来填充它。

If you want to be able to accommodate concatenation "Vivek" and "Ratnavel" you need to have a char array of size atleast 14 (5 + 8 + 1) . 如果你想能够容纳连接"Vivek""Ratnavel"你需要一个大小至少为14 (5 + 8 + 1)的字符数组。

In your modified program you are doing: 在您修改的程序中,您正在执行:

char *a1=(char*)malloc(100);  // 1
a1 = "Vivek";                 // 2

1: Will allocate a memory chunk of size 100 bytes, makes a1 point to it. 1:将分配一个大小为100字节的内存块,使其指向a1
2: Will make a1 point to the string literal "Vivek" . 2:将a1指向字符串文字"Vivek" This string literal cannot be modified. 无法修改此字符串文字。

To fix this use strcpy to copy the string into the allocated memory: 要修复此问题,请使用strcpy将字符串复制到已分配的内存中:

char *a1=(char*)malloc(100);  
strcpy(a1,"Vivek");

Also the for loop condition i<strlen(b1)-1 will not copy last character from the string, change it to i<strlen(b1) for循环条件i<strlen(b1)-1也不会复制字符串中的最后一个字符,将其更改为i<strlen(b1)

And

a1[i]='\0';

should be 应该

a1[i + len]='\0';

as the new length of a1 is i+len and you need to have the NUL character at that index. 因为a1的新长度是i+len ,你需要在该索引处有NUL字符。

And don't forget to free your dynamically allocated memory once you are done using it. 完成使用后,不要忘记free动态分配的内存。

Old answer below 下面的老答案


You can initialize a string with strcpy , like in your code, or directly when declaring the char array. 您可以使用strcpy初始化字符串,就像在代码中一样,或者直接在声明char数组时。

char a1[100] = "Vivek";

Other than that, you can do it char-by-char 除此之外,你可以做char-by-char

a1[0] = 'V';
a1[1] = 'i';
// ...
a1[4] = 'k';
a1[5] = '\0';

Or you can write a few lines of code that replace strcpy and make them a function or use directly in your main function. 或者您可以编写几行代码替换strcpy并使其成为函数或直接在main函数中使用。


Old answer 老答案

You have 你有

0 1 2 3 4 5 6 7 8 9 ...
    a1 [V|i|v|e|k|0|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_]
    b1 [R|a|t|n|a|v|e|l|0|_|_|_|_|_|_|_|_|_|_|_|_|_]

and you want 而你想要的

0 1 2 3 4 5 6 7 8 9 ...
    a1 [V|i|v|e|k|R|a|t|n|a|v|e|l|0|_|_|_|_|_|_|_|_]

so ... 所以......

a1[5] = 'R';
a1[6] = 'a';
// ...
a1[12] = 'l';
a1[13] = '\0';

but with loops and stuff, right? 但是有循环和东西,对吗? :D :d

Try this (remember to add missing bits) 试试这个(记得添加缺失的位)

for (aindex = 5; aindex < 14; aindex++) {
    a1[aindex] = b1[aindex - 5];
}

Now think about the 5 and 14 in the loop above. 现在想想上面循环中的514

What can you replace them with? 你有什么可以替代他们的? When you answer this, you have solved the programming problem you have :) 当你回答这个问题时,你已经解决了你的编程问题:)

You cannot safely write into those arrays, since you have not made sure that enough space is available. 您无法安全地写入这些数组,因为您还没有确保有足够的空间可用。 If you use malloc() to allocate space, you can't then overwrite the pointer by assigning to string literal. 如果使用malloc()来分配空间,则不能通过分配字符串文字来覆盖指针。 You need to use strcpy() to copy a string into the newly allocated buffers, in that case. 在这种情况下,您需要使用strcpy()将字符串复制到新分配的缓冲区中。

Also, the length of a string in C is computed by the strlen() function, not length() that you're using. 此外,C中字符串的长度由strlen()函数计算,而不是您正在使用的length()

When concatenating, you need to terminate at the proper location, which your code doesn't seem to be doing. 连接时,您需要在适当的位置终止,您的代码似乎没有这样做。

Here's how I would re-implement strcat() , if needed for some reason: 这是我如何重新实现strcat() ,如果出于某种原因需要:

char * my_strcat(char *out, const char *in)
{
  char *anchor = out;
  size_t olen;

  if(out == NULL || in == NULL)
    return NULL;

  olen = strlen(out);
  out += olen;
  while(*out++ = *in++)
    ;
  return anchor;
}

Note that this is just as bad as strcat() when it comes to buffer overruns, since it doesn't support limiting the space used in the output, it just assumes that there is enough space available. 请注意,当涉及缓冲区溢出时,这与strcat()一样糟糕,因为它不支持限制输出中使用的空间,它只是假设有足够的可用空间。

Problems: 问题:

  1. length isn't a function. length不是一个功能。 strlen is, but you probably shouldn't call it in a loop - b1 's length won't change on us, will it? strlen是,但你可能不应该在循环中调用它 - b1的长度不会改变我们,是吗? Also, it returns a size_t , which may be the same size as int on your platform but will be unsigned. 此外,它返回一个size_t ,它可能与您平台上的int大小相同,但是将是无符号的。 This can (but usually won't) cause errors, but you should do it right anyway. 这可能(但通常不会)导致错误,但无论如何都应该正确。
  2. a1 only has enough space for the first string, because the compiler doesn't know to allocate extra stack space for the rest of the string since. a1只有足够的空间容纳第一个字符串,因为编译器不知道为字符串的其余部分分配额外的堆栈空间。 If you provide an explicit size, like [100] , that should be enough for your purposes. 如果您提供明确的大小,例如[100] ,那么这应该足以满足您的需要。 If you need robust code that doesn't make assumptions about what is "enough", you should look into malloc and friends, though that may be a lesson for another day. 如果您需要健壮的代码,而不是对“足够”的内容进行假设,那么您应该考虑malloc和朋友,尽管这可能是另一天的教训。
  3. Your loop stops too early. 你的循环太早停止了。 i < b1_len (assuming you have a variable, b1_len , that was set to the length of b1 before the loop began) would be sufficient - strlen doesn't count the '\\0' at the end. i < b1_len (假设你有一个变量, b1_len ,在循环开始之前设置为b1的长度)就足够了 - strlen不计算结尾的'\\0'
  4. But speaking of counting the '\\0' at the end, a slightly more efficient implementation could use sizeof a1 - 1 instead of strlen(a1) in this case, since a1 (and b1 ) are declared as arrays, not pointers. 但是说到最后计算'\\0' ,在这种情况下,稍微更高效的实现可以使用sizeof a1 - 1而不是strlen(a1) ,因为a1 (和b1 )被声明为数组,而不是指针。 It's your choice, but remember that sizeof won't work for pointers, so don't get them mixed up. 这是你的选择,但请记住, sizeof不适用于指针,所以不要混淆它们。
    EDIT: New problems: 编辑:新问题:
  5. char *p = malloc(/*some*/); p = /* something */ char *p = malloc(/*some*/); p = /* something */ is a problem. char *p = malloc(/*some*/); p = /* something */是一个问题。 = with pointers doesn't copy contents, it copies the value, so you're throwing away the old pointer value you got from malloc . =使用指针不复制内容,它会复制该值,因此您将丢弃从malloc获得的旧指针值。 To copy the contents of a string into a char * (or a char [] for that matter) you'd need to use strcpy , strncpy , or (my preference) memcpy . 要将字符串的内容复制到char * (或char [] ),您需要使用strcpystrncpy或(我的首选项) memcpy (Or just a loop, but that's rather silly. Then again, it may be good practice if you're writing your own strcat .) (或者只是一个循环,但这是相当愚蠢的。再说一次,如果你正在编写自己的strcat ,这可能是一个好习惯。)
  6. Unless you're using C++, I wouldn't cast the return value of malloc , but that's a religious war and we don't need one of those. 除非你使用C ++,否则我不会转换malloc的返回值,但这是一场宗教战争,我们不需要其中一种。
  7. If you have strdup , use it. 如果你有strdup ,请使用它。 If you don't, here is a working implementation: 如果你不这样做,这是一个有效的实现:

     char *strdup(const char *c) { size_t l = strlen(c); char *d = malloc(l + 1); if(d) memcpy(d, c, l + 1); return d; } 

    It is one of the most useful functions not in the C standard library. 它是C标准库中最有用的功能之一。

You can do it using strcpy() too ;) 你也可以使用strcpy()来做;)

char *a = (char *) malloc(100);
char *b = (char *) malloc(100);

strcpy(a, "abc");               // initializes a
strcpy(b, "def");               // and b

strcpy((a + strlen(a)), b);     // copy b at end of a

printf("%s\n",a);               // will produce: "abcdef"

i think this is an easy one. 我觉得这很简单。

#include<stdio.h>
int xstrlen(char *);
void xstrcat(char *,char *,int);
void main()
{
    char source[]="Sarker";
    char target[30]="Maruf";
    int j=xstrlen(target);
    xstrcat(target,source,j);
    printf("Source String: %s\nTarget String: %s",source,target);
}
int xstrlen(char *s)
{
    int len=0;
    while(*s!='\0')
    {
        len++;
        s++;
    }
    return len;
}
void xstrcat(char *t,char *s,int j)
{
    while(*t!='\0')
    {
        *t=*t;
        t++;
    }
    while(*s!='\0')
    {
        *t=*s;
        s++;
        t++;
    }
}

It is better to factor out your strcat logic to a separate function. 最好将strcat逻辑分解为单独的函数。 If you make use of pointer arithmetic, you don't need the strlen function: 如果使用指针运算,则不需要strlen函数:

#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* To completely get rid of this, 
                       implement your our strcpy as well */

static void 
my_strcat (char* dest, char* src)
{
  while (*dest) ++dest;
  while (*src) *(dest++) = *(src++);
  *dest = 0;
}

int 
main()
{
  char* a1 = malloc(100);
  char* b1 = malloc(100);

  strcpy (a1, "Vivek");  
  strcpy (b1, " Ratnavel");

  my_strcat (a1, b1);
  printf ("%s\n", a1); /* => Vivek Ratnavel */

  free (a1);
  free (b1);
  return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM