goksurahsan Ответов: 2

Как я могу использовать strcat_s с двумя строками для печати в одной строке?


Я хочу использовать функцию strcat_s() для объединения двух строк в одну строку. Например, пользователи вводят свое имя и должность. имя печати консоли-задание:

Пожалуйста, введите свое имя:Рахсан
Пожалуйста, введите свою должность:Инженер

Рахсан-Инженер

Но консольная печать Рахсан
-Инженер.

Как я могу решить эту проблему?

Что я уже пробовал:

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

int main()
{
	setlocale(LC_ALL, "Turkish");
	char name[20];
	char job[20];
	char users[40]="";

	printf("Please enter your name:\n");
	fgets(name, sizeof(name), stdin);
	printf("\n");
	printf("Please enter your job:\n");
	fgets(job, sizeof(job), stdin);
	printf("\n");

	strcat_s(users,40,name);
	strcat_s(users,40,"-");
	strcat_s(users,40,job);
	puts(users);
	
	return 0;
}

2 Ответов

Рейтинг:
18

OriginalGriff

Во-первых, ваша область вывода слишком мала: два массива, которые Вы читаете от пользователя, состоят из 20 символов каждый, и вы добавляете " - " в середине. Вам нужно убедиться, что выходной буфер достаточно велик, чтобы вместить все данные, которые вы хотите поместить в него.

Проблема, которую вы видите, заключается в том, что функция fgets оставляет новую строку в конце строки, которую она читает, поэтому при печати она печатает новую строку из имени, затем дефис и название задания.

Добавьте функцию для его удаления:

void Trim(char* str)
{
	char* pos;
	if ((pos = strchr(str, '\n')) != NULL)
	{
		*pos = '\0';
	}
}

Тогда просто позвоните ему дважды:
printf("Please enter your name:\n");
fgets(name, sizeof(name), stdin);
printf("\n");
Trim(name);
printf("Please enter your job:\n");
fgets(job, sizeof(job), stdin);
printf("\n");
Trim(job);


Если бы вы использовали отладчик, вы бы сразу поняли, почему это происходит ... Я настоятельно рекомендую вам ознакомиться с отладчиком, это самый полезный инструмент, который у вас есть!


goksurahsan

На самом деле я видел символ '\n', когда использовал отладчик. Но я новичок в Си, и я ищу в интернете, но я не понимаю. Сейчас я не знаю указателей. Спасибо за ответ

OriginalGriff

Всегда пожалуйста!

k5054

Я также изначально думал, что область вывода слишком мала, но на самом деле это не так: имя и работа объявляются как char[20] Это означает, что каждая из них может содержать до 19 символов плюс завершающий nul, так что две строки вместе имеют максимальную длину 38. Добавление '-' в середине увеличивает максимальную длину до 39, что оставляет один символ в пользователях для null. Который поместится в выходной области char[40].

Тем не менее, я подозреваю, что оператору повезло, и он не понимал, что существует возможность переполнения буфера, что было бы в том случае, если бы он разделил входные строки с помощью" -", а не просто одного символа.

Рейтинг:
1

k5054

fgets() включает новую строку в конце строки (при условии, что входные данные не были усечены), поэтому вам нужно обрезать конечную новую строку. Есть несколько способов сделать это, вот два:

fgets(name, sizeof(name), stdin);

/* Method one, using strlen() */
size_t len = strlen(name);
if(name[len] == '\n')
   name[len] = '\0';

/* method two, use strchr */
char *ptr = strchr(name, '\n');
if(ptr != NULL)
    *ptr = '\0';

Вы должны знать, что fgets() не смывает входной буфер, поэтому, если пользователь введет "Арнольд Шварценеггер" (длина 21 символ), вы получите
name = "Arnold Schwarzenegg";
job="er"
Чтобы обойти это, вы могли бы использовать getline()
size_t len = 0;
char *input = NULL;
ssize_t rlen;

rlen = getline(&input, &len, stdin);
/* rlen is the number of chars read in, so we can trim the newline without calling
   another function */
if(rlen > sizeof(name) { /* read in too many chars */
    input[sizeof(name)-1] = '\0'; /* effectively make input only 19 chars long */ 
else if(rlen > 0)  { /* trim off trailing newline */
    input[rlen-1] = '\0';
else {
    /* do error handling */
}
strcpy(name, input); /* safe, since we already trimmed input if over-length */

/* ... */
free(buff);

При использовании getline() второй аргумент, len в приведенном выше примере это размер входного буфера, который был выделен getline() Вам не нужно освобождать и сбрасывать входной буфер между вызовами на getline() Второй параметр getline-это размер выделенного входного буфера, поэтому если вам нужно прочитать несколько строк, вам нужно только позвонить free() после вашего последнего использования входного буфера. Это также означает, что getline() будет только перераспределять буфер по мере необходимости.