Click here to Skip to main content
14,574,641 members
Rate this:
Please Sign up or sign in to vote.
See more:
I want to use strcat_s() funciton to combine two string in one line. For example users enter his\her name and his\her job. the console print name-job:

Please enter your name:Rahsan
Please enter your job:Engineer

Rahsan-Engineer

But console print Rahsan
-Engineer.

How can I fix this problem?

What I have tried:

#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;
}
Posted
Updated 27-Jun-20 5:48am
Rate this:
Please Sign up or sign in to vote.

Solution 1

For starters, your output area is too small: the two arrays you are reading from the user are 20 characters each, and you add a "-" in the middle. You need to ensure that the output buffer is big enough to hold all the data you want to fit in it.

The problem you see is that the fgets function leaves the newline at the end of the string it reads - so when you print it it prints the newline from teh name, then the hyphen and the job title.

Add a function to remove it:
void Trim(char* str)
{
	char* pos;
	if ((pos = strchr(str, '\n')) != NULL)
	{
		*pos = '\0';
	}
}

Then just call it twice:
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);


If you had used the debugger, you would have seen why it happens pretty much immediately ... I'd strongly suggest you get familiar with the debugger, it's th' most useful tool you have available to you!
   
v2
Comments
goksurahsan 27-Jun-20 11:32am
   
Actually I had seen '\n' character when I used the debugger. But I am new in C and I search on the Internet but I don't understand. I don't know pointers at now. Thank you for answer
OriginalGriff 27-Jun-20 11:51am
   
You're welcome!
k5054 27-Jun-20 11:58am
   
I also initially thought that the output area was too small, but actually its not: name and job are both declared as char[20]. That means that they can each hold up to 19 chars, plus the terminating nul, so the two strings together have a max length of 38. Adding the '-' in the middle raises the maximum length to 39, which leaves one char in users for the null. Which will fit in the output area of char[40].

That being said, I suspect the OP got lucky, and didn't realize that there was a possibility for buffer overflow, which would be the case if he had separated the input strings with " - ", instead of just a single character.
Rate this:
Please Sign up or sign in to vote.

Solution 2

fgets() includes the newline at the end of the string (assuming the input has not been truncated), so you need to trim off the trailing newline. There's several ways to do that, here's two:
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';

You should be aware that fgets() does not flush the input buffer, so if the user enters "Arnold Schwarzenegger" (length 21 chars), you'l end up with
name = "Arnold Schwarzenegg";
job="er"
. To get around this you could use 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);

When using getline() the second parameter, len in the above example, is the size of the input buffer that has been allocated by getline(). You don't need to free and reset the input buffer between calls to getline(). The second parameter to getline is the size of the allocated input buffer, so if you need to read several lines you only need to call free() after your last use of the input buffer. This also means that getline() will only reallocate the buffer as it needs to.
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100