Объединить несколько символов char * подряд с помощью strcat - PullRequest
0 голосов
/ 14 декабря 2018

В настоящее время я пытаюсь объединить несколько «строк» ​​подряд в моей серверной программе, используя 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 голосов
/ 16 декабря 2018

Проблема в том, что вы недостаточно места для своих строк.Вы до сих пор точно не показываете, как все они объявлены, но есть достаточно примеров, чтобы продемонстрировать проблему, как этот.

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);
0 голосов
/ 14 декабря 2018

показывает код, который показывает распределение памяти для имени пользователя, года, месяца и дня.Убедитесь, что они не перекрываются и не используются совместно.

попробуй

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);
...