如何在 c 中使用 strcat 连接 char 指针?

How to concatenate char pointers using strcat in c?

我正在学习 C 中的指针,使用 Linux。我正在尝试使用 strcat 函数,但它不起作用,我不明白为什么。

我将用户名作为参数传递给 main,因为我需要连接并将数字 1 放在该用户名的第一个位置。例如,如果我得到作为参数 username123 我需要将其转换为 1username123

我得到了这个代码:

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

int main(int argc, char *arg[]){
    const char *userTemp;
    char *finalUser;

    userTemp = argv[1]; //I got the argument passed from terminal
    finalUser = "1";
    strcat(finalUser, userTemp); //To concatenate userTemp to finalUser
    printf("User: %s\n",finalUser);

    return 0;
}

代码编译通过了,但是我遇到了段错误,不知道为什么。你能帮我找到正确的方向吗?

您缺少有关 C 的一些基础知识。

finalUser = "1";

这是在 "read-only" 内存中创建的。你不能改变这个。 strcat 的第一个参数需要为突变分配内存,例如

char finalUser[32];
finalUser[0] = '1';

与其他语言不同,C 中没有真正的字符串类型。

你想要这个:

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

int main(int argc, char *arg[]){
    const char *userTemp;
    char finalUser[100];   // finalUser can contain at most 99 characters

    userTemp = argv[1]; //I got the argument passed from terminal
    strcpy(finalUser, "1");    // copy "1" into the finalUser buffer
    strcat(finalUser, userTemp); //To concatenate userTemp to finalUser
    printf("User: %s\n",finalUser);

    return 0;
}

或更简单:

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

int main(int argc, char *arg[]){
    char finalUser[100];   // finalUser can contain at most 99 characters
    strcpy(finalUser, "1");    // copy "1" into the finalUser buffer
    strcat(finalUser, argv[1]); //To concatenate argv[1] to finalUser
    printf("User: %s\n",finalUser);    
    return 0;
}

免责声明:为简洁起见,此代码包含一个固定大小的缓冲区,此处未检查缓冲区溢出。

你的 C 课本中处理字符串的章节应该涵盖这一点。

顺便说一句,您还应该检查程序是否使用参数调用:

int main(int argc, char *arg[]){
  if (argc != 2)
  {
     printf("you need to provide a command line argument\n");
     return 1;
  }
  ...

I'm trying to use the strcat function, but it doesn't work and I don't understand why.

首先,你真的 shouldn't use strcat()。请改用 strlcat()。此函数和其他函数的 "l" 版本采用一个额外的参数,让您告诉函数目标缓冲区有多大,这样函数就可以避免写入超过缓冲区的末尾。 strcat() 没有该参数,因此它依赖于您确保缓冲区足够大以包含两个字符串。这是 C 代码中安全问题的常见来源。 "l" 版本还确保生成的字符串以 null 结尾。

The code compiles, but I got a segmentation fault error and doesn't know why.

函数原型如下:char *strcat( char *dest, const char *src );

现在,您基本上是这样称呼它的:strcat("1", someString);。也就是说,您试图将 someString 附加到 "1",这是一个字符串常量。对于 someString 中的任何字符串,"1" 中都没有额外的空间,并且因为您使用的函数会愉快地写入目标缓冲区的末尾,所以您的代码实际上正在覆盖发生的任何事情在该字符串常量旁边的内存中。

要解决此问题,您应该:

  1. 切换到 strlcat()
  2. 使用 malloc() 或其他方法分配一个足够大的目标缓冲区来容纳两个字符串。

在 C 中尝试修改字符串文字是未定义的行为(如 "1")。通常,这些存储在不可修改的内存中以允许进行某些优化。

让我们暂时搁置整个程序可以替换为的事实:

#include <stdio.h>
int main(int argc, char *argv[]){
    printf("User: 1%s\n", (argc > 1) ? argv[1] : "");
    return 0;
}

确保有足够 space 的方法是创建一个足够大的缓冲区来容纳你想做的任何事情。例如:

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

int main(int argc, char *argv[]){
    // Check args provded.

    if (argc < 2) {
        puts("User: 1");
        return 0;
    }

    // Allocate enough memory ('1' + arg + '[=11=]') and check it worked.

    char *buff = malloc(strlen(argv[1]) + 2); 
    if (buff == NULL) {
        fprintf(stderr, "No memory\n");
        return 1;
    }

    // Place data into memory and print.

    strcpy(buff, "1");
    strcat(buff, argv[1]);
    printf("User: %s\n", buff);

    // Free memory and return.

    free(buff);
    return 0;
}

不应该做的是分配一个固定大小的缓冲区并盲目地复制用户提供的数据。绝大多数安全问题就是这样发生的,人们用意想不到的数据覆盖缓冲区。