0

say I have 3 strings:

    char a[9];
    char b[20];
    char c[20];

how would I create a third string composed of the contents of the previous strings, bearing in mind that a, b and c are input by the user. when I use strcpy with a and then strcat with b and c and then print the resulting string d, I get rubbish characters. Is this to do with the NULL terminators for each strings or am I doing something else wrong? Thank you

EDIT:

    void getBasicDetails(char date_of_birth[9], char first_name[20], 
    char last_name[20])
    {
        char temp_dob[9];
        char temp_fname[20];
        char temp_lname[20];
        char file_name[50];
        int stop = 1;
        printf("Patient's Date of Birth (in format dd/mm/yy) : "); // 2 and 5
        while (stop == 1)
        {
            scanf("%s", &temp_dob);
            emptyBuffer();
            if ((temp_dob[2] == '/' && temp_dob[5] == '/'))
            {
                stop = 0;
                break;  
            }
            else
            {
            printf("Enter in format dd/mm/yy\n");
            }
        }
      date_of_birth = temp_dob;
      date_of_birth[9] = '\0';

      printf("Patient's First Name : ");
      scanf("%s", &temp_fname);
      emptyBuffer();
      first_name = temp_fname;
      first_name[20] = '\0';

      printf("Patient's Last Name : ");
      scanf("%s", &temp_lname);
      emptyBuffer();
      last_name = temp_lname;
      last_name[20] = '\0';

      strcat(file_name, first_name);
      strcat(file_name, last_name);
      strcat(file_name, date_of_birth);
      puts(file_name);
  }
  • 2
    Instead of describing the code in words, can you edit your question to show the code? Do you properly initialize these buffers before using them? – tadman Dec 13 '18 at 00:21
  • Assuming that `a`, `b`, and `c` are valid NUL-terminated strings that don't overflow their buffers, I prefer something like `sprintf(d,"%s%s%s",a,b,c);` Remember that `d` can't be a local variable inside a subroutine you are calling - if it is, it will be popped off the stack before you can use it if you try to return it from a subroutine. – JohnH Dec 13 '18 at 00:27
  • I didnt really initialize them properly, I passed them to the same function where the user inputs the values they want to give each one. I would love to post my code but its so convoluted and dumb that I doubt anyone could read it properly. – Lord Darias Dec 13 '18 at 00:27
  • 1
    As I mentioned below under Brian's answer, you should do `file_name[0] = 0;` before doing `strcat`. As it is, `file_name` starts with unitialized/random chars so the first `strcat` might scan (e.g.) hundreds of chars, going way past the end of `file_name` looking for the 0x00 [EOS] terminator char to find the end of the string, which is undefined behavior. – Craig Estey Dec 13 '18 at 01:03
  • OT: for ease of readability and understanding: 1) consistently indent the code. Indent after every opening brace '{'. Unindent before every closing brace '}'. Suggest each indent level be 4 spaces. 2) separate code blocks: `for` `if` `else` `while` `do...while` `switch` `case` `default` via a single blank line. – user3629249 Dec 14 '18 at 03:10
  • regarding the date-of-birth verification: What happens when the user inputs a early month or an early day (only a single digit) or inputs a whole 4 digit year? – user3629249 Dec 14 '18 at 03:13
  • regarding: `first_name = temp_fname; first_name[20] = '\0';` this will NOT work, amongst other things, the call to `scanf()` already NUL terminated the string in the right place AND in C, cannot assign a string, rather must use something like `strcpy()` – user3629249 Dec 14 '18 at 03:16
  • regarding: `strcat(file_name, first_name);` The function: `strcat()` scans the array `file_name[]` until it finds a NUL byte (which may be far beyond the end of the array) Such a action results in undefined behavior. Suggest that statement be replaced with: `strcpy( file_name, first_name );` Then the following calls to `strcat()` will work as expected. – user3629249 Dec 14 '18 at 03:21
  • regarding: `first_name[20] = '\0';` and similar statements: The array `first_name[]` only contains 20 elements. In C, indexing an array is in the range 0...(number of elements in array -1) So this kind of statement is accessing beyond the end of the array. The result is undefined behavior. – user3629249 Dec 15 '18 at 01:39

3 Answers3

1

regarding the following (and similar) lines in the posted code:

  scanf("%s", &temp_fname);
  ....
  first_name = temp_fname;
  1. temp_fname is an array, In C, a bare reference to an array degrades to the address of the first byte of the array. prepending an & to the parameter in the call to scanf() is not valid when setting an array.
  2. when using the input format specifiers: %s and/or %[...] always include a MAX CHARACTERS modifier that is 1 less than the length of the input buffer. This is because those two input specifiers always append a NUL byte to the input
  3. When trying to copy a string, a simple assignment will not work. All that will happen is the address of the source is copied to the destination (and probably will cause the compiler to output an error message) Instead of an assignment use: strcpy() or strncpy()

When compiling, always enable the warnings, then fix those warnings. For gcc at a minimum use: -Wall -Wextra -Wconversion -pedantic -std=gnu11 ) Note: other compilers use different options to produce the same thing

user3629249
  • 16,402
  • 1
  • 16
  • 17
-1

If you don't mind, could you post your full code? For now I'll assume a, b, and c all contain some string and d is empty.

char a[9];
char b[20];
char c[20];
char d[60];

strcpy (b);
strcpy (a);
strcpy (c);
strcpy (d);
strcat (d, a);
strcat (d, b);
strcat (d, c);
puts(d);
printf(d);

Also, you could utilize the sprintf function to do the same:

sprintf(d, "%s%s%s", a, b, c)

If I'm doing this correctly, this should return the proper results you wanted. For more on strcat() check this link: https://www.tutorialspoint.com/c_standard_library/c_function_strcat.htm

For more on sprintf() check this link: https://www.geeksforgeeks.org/sprintf-in-c/

  • 1
    You should do `d[0] = 0;` before the `strcat` calls. Also, you should _not_ do `printf(d)` because `d` _could_ have a format specifier (e.g. `%s`). Better to do `printf("%s\n",d);` – Craig Estey Dec 13 '18 at 00:58
  • 3
    strcpy takes more than 1 argument. I don't understand what you're doing. – MFisherKDX Dec 13 '18 at 03:10
-1

I'm not sure but if you want to create a third string composed of the contents of the previous strings then try this:

   char str1[100];
   char str2[100];
   char str3[100];
   printf("Enter String1: \n");
   gets(str1);
   printf("\Enter String2:\n");
   gets(str2);
   strcpy(str3,str1);
   strcat(str3,str2);
   printf("String 3: %s", str3);
Samson Wu
  • 10
  • 7
  • 1
    [why-is-the-gets-function-so-dangerous-that-it-should-not-be-used](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used) – MFisherKDX Dec 13 '18 at 05:25
  • yes, your wrong. Amongst other considerations, the function: `gets()` has been depreciated for years and in the latest versions of the C coding standard, completely removed. Your compiler should have told you this – user3629249 Dec 15 '18 at 01:43