使用strcat

时间:2018-12-14 10:27:47

标签: c strcat

我目前正在尝试使用strcat在服务器程序中连续连接多个“字符串”。 该代码的相关部分如下: 我成功获取了客户端发送的年,月,日和文件名,因为它打印得很好。

我的字符串初始化如下:

    char username[MAX_USERNAME_SIZE];
    char filename[MAX_FILENAME_SIZE];
    char path[MAX_FILEPATH_SIZE];
    char buff[BUFFSIZE];
    char year[4], month[2], day[2];
    ...
    if ((numbytes = recv(new_fd, &username, MAX_USERNAME_SIZE, 0)) == -1)
    {
        perror("Serveur: recv username");
        return EXIT_FAILURE;
        }
        username[numbytes] = '\0';
        printf("Serveur: username: %s\n", username); 
        /* create user's repository if it doesn't exist yet*/

        // 3) get date from client
        if ((numbytes = recv(new_fd, year, 4, 0)) == -1)
        {
            perror("Serveur: recv year");
            return EXIT_FAILURE;
        }
        year[numbytes] = '\0';
        printf("year: %s\n", year);
        if ((numbytes = recv(new_fd, month, 2, 0)) == -1)
        {
            perror("Serveur: recv month");
            return EXIT_FAILURE;
        }
        month[numbytes] = '\0';
        printf("month: %s\n", month);
        if ((numbytes = recv(new_fd, day, 2, 0)) == -1)
        {
            perror("Serveur: recv day");
            return EXIT_FAILURE;
        }
        day[numbytes] = '\0';
        printf("day: %s\n", day);
        // get filename from client
        if ((numbytes = recv(new_fd, filename, MAX_FILENAME_SIZE, 0)) == -1)
        {
            perror("Serveur: recv filename");
            return EXIT_FAILURE;
        }
        filename[numbytes] = '\0';
        printf("Serveur: filename: %s\n", filename);

但是当我尝试正确连接所有字符串时,出现了问题。

        // create user repository
        strcpy(path, argv[1]);
        printf("Serveur: Path: %s\n", path);
        strcat(path, "/");
        printf("Serveur: Path: %s\n", path);

        strcat(path, username);
        strcat(path, "/");
        printf("Serveur: Path: %s\n, username:%s\n", path, username);
        my_mkdir(path, MODE);

        strcat(path, year);
        strcat(path, "/");
        printf("Serveur: Path: %s\n, year: %s\n", path, year);
        my_mkdir(path, MODE);

        strcat(path, month);
        strcat(path, "/");
        printf("Serveur: Path: %s\n, month: %s\n", path, month);
        my_mkdir(path, MODE);

        strcat(path, day);
        strcat(path, "/");
        printf("Serveur: Path: %s\n, day: %s\n", path, day);
        my_mkdir(path, MODE);

        strcat(path, filename);
}

这样做之后,用户名,年份和月份打印得并不令人惊讶。 这是我执行代码时的输出结果(我确定文件名可以确定,因为从客户端检索到的文件以正确的名称保存):

Serveur: connection recieved from client 127.0.0.1
Serveur: username: student
year: 95
month: 5
day: 11
Serveur: filename: tux.png
Serveur: Path: ./Test0/Test1
Serveur: Path: ./Test0/Test1/
Serveur: Path: ./Test0/Test1//
, username:
Serveur: Path: ./Test0/Test1///
, year: 
Serveur: Path: ./Test0/Test1////
, month: 
Serveur: Path: ./Test0/Test1////11/
, day: 11

我真的很想清楚我错在哪里。预先感谢

2 个答案:

答案 0 :(得分:2)

问题是您没有给字符串足够的空间。您仍然没有确切显示所有声明的方式,但是有足够的示例来演示此问题,例如这样的示例。

char year[4]

以上内容只能容纳3个字符-第4个空格用于存储\0终止字符。

在这里,您告诉代码从套接字读取4个字节,它将这样做,然后numbytes等于4 ...

    if ((numbytes = recv(new_fd, year, 4, 0)) == -1)

...然后使用numbytes添加NUL终止符...

    year[numbytes] = '\0';

...但是year[4]超出了数组的范围,这会导致未定义的行为。看来year里面有一个有效的年份,但是随后的其他代码又发生了,并且发生了奇怪的事情,因为您对所有其他字符串也犯了同样的错误。

要容纳4个字符和NUL,您需要声明year,且至少要包含5个字符,像这样...

char year[5]

...但是您的计算机内存不足以至于您必须如此节俭吗?最好提供超出所需的空间,或者将其读取到具有足够空间的缓冲区中,并在空间不足的情况下分配足够的内存以创建合适大小的字符串,如本示例所示。

char *year;
char buffer[100];
if ((numbytes = recv(new_fd, buffer, 4, 0)) == -1)
{
    perror("Serveur: recv year");
    return EXIT_FAILURE;
}
buffer[numbytes] = '\0';
year=malloc(numbytes+1);
strcpy(year,buffer);

答案 1 :(得分:1)

显示代码,该代码显示用户名,年,月和日的内存分配。确保它们没有重叠或共享。

尝试

sprintf(path,"%s/%s/%s/%s/%s/",argv[1],username,year,month,day);

或者更改,

 strcpy(path, argv[1]);
 printf("Serveur: Path: %s\n", path);
 strcat(path, "/");
 printf("Serveur: Path: %s\n", path);


 if ((numbytes = recv(new_fd, &username, MAX_USERNAME_SIZE, 0)) == -1){
        perror("Serveur: recv username");
        return EXIT_FAILURE;
 }
 username[numbytes] = '\0';
 printf("Serveur: username: %s\n", username); 
 strcat(path, username);
 strcat(path, "/");
 printf("Serveur: Path: %s\n, username:%s\n", path, username);
 my_mkdir(path, MODE);    

 /* create user's repository if it doesn't exist yet*/

 // 3) get date from client
 if ((numbytes = recv(new_fd, year, 4, 0)) == -1){
     perror("Serveur: recv year");
     return EXIT_FAILURE;
 }
 year[numbytes] = '\0';
 printf("year: %s\n", year);
 strcat(path, year);
 strcat(path, "/");
 printf("Serveur: Path: %s\n, year: %s\n", path, year);
 my_mkdir(path, MODE);

 if ((numbytes = recv(new_fd, month, 2, 0)) == -1){
     perror("Serveur: recv month");
     return EXIT_FAILURE;
 }
 month[numbytes] = '\0';
 printf("month: %s\n", month);

 strcat(path, month);
 strcat(path, "/");
 printf("Serveur: Path: %s\n, month: %s\n", path, month);
 my_mkdir(path, MODE);


 if ((numbytes = recv(new_fd, day, 2, 0)) == -1){
     perror("Serveur: recv day");
     return EXIT_FAILURE;
 }
 day[numbytes] = '\0';
 printf("day: %s\n", day);

 strcat(path, day);
 strcat(path, "/");
 printf("Serveur: Path: %s\n, day: %s\n", path, day);
 my_mkdir(path, MODE);

 // get filename from client
 if ((numbytes = recv(new_fd, filename, MAX_FILENAME_SIZE, 0)) == -1){
     perror("Serveur: recv filename");
     return EXIT_FAILURE;
 }
 filename[numbytes] = '\0';
 printf("Serveur: filename: %s\n", filename);
 strcat(path, filename);