title: Combine directory and file path - C
body: <p>As part of learning C, I wrote the following code to combine directory name with file name. Eg: <code>combine("/home/user", "filename")</code>  will result in <code>/home/user/filename</code>. This function is expected work across platforms (atleast on all popular linux distributions and windows 32 and 64bit).</p>
  
  <p>Here is the code.</p>
  
  <pre><code>const char* combine(const char* path1, const char* path2)
  {
      if(path1 == NULL &amp;&amp; path2 == NULL) {
          return NULL;
      }
  
      if(path2 == NULL || strlen(path2) == 0) return path1;
      if(path1 == NULL || strlen(path1) == 0) return path2;
  
      char* directory_separator = "";
  #ifdef WIN32
      directory_separator = "\\";
  #else 
      directory_separator = "/";
  #endif
  
      char p1[strlen(path1)];                    // (1)
      strcpy(p1, path1);                         // (2) 
      char *last_char = &amp;p1[strlen(path1) - 1];  // (3)
  
      char *combined = malloc(strlen(path1) + 1 + strlen(path2));
      int append_directory_separator = 0;
      if(strcmp(last_char, directory_separator) != 0) {
          append_directory_separator = 1;
      }
      strcpy(combined, path1);
      if(append_directory_separator)
          strcat(combined, directory_separator);
      strcat(combined, path2);
      return combined;
  }
  </code></pre>
  
  <p>I have the following questions regarding the above code.</p>
  
  <ol>
  <li>Consider the lines numbered 1,2,3. All those 3 lines are for getting the last element from the string. It looks like I am writing more code for such a small thing. What is the correct method to get the last element from the <code>char*</code> string.</li>
  <li>To return the result, I am allocating a new string using <code>malloc</code>. I am not sure this is the right way to do this. Is caller expected to free the result? How can I indicate the caller that he has to free the result? Is there a less error prone method available?</li>
  <li>How do you rate the code (Poor, Average, Good)? What are the areas that can be imrpoved?</li>
  </ol>
  
  <p>Any help would be great.</p>
  
  <p>Edit</p>
  
  <p>Fixed all the issues discussed and implemented the changes suggested. Here is the updated code.</p>
  
  <pre><code>void combine(char* destination, const char* path1, const char* path2)
  {
      if(path1 == NULL &amp;&amp; path2 == NULL) {
          strcpy(destination, "");;
      }
      else if(path2 == NULL || strlen(path2) == 0) {
          strcpy(destination, path1);
      }
      else if(path1 == NULL || strlen(path1) == 0) {
          strcpy(destination, path2);
      } 
      else {
          char directory_separator[] = "/";
  #ifdef WIN32
          directory_separator[0] = '\\';
  #endif
          const char *last_char = path1;
          while(*last_char != '\0')
              last_char++;        
          int append_directory_separator = 0;
          if(strcmp(last_char, directory_separator) != 0) {
              append_directory_separator = 1;
          }
          strcpy(destination, path1);
          if(append_directory_separator)
              strcat(destination, directory_separator);
          strcat(destination, path2);
      }
  }
  </code></pre>
  
  <p>In the new version, caller has to allocate enough buffer and send to <code>combine</code> method. This avoids the use of <code>malloc</code> and <code>free</code> issue. Here is the usage</p>
  
  <pre><code>int main(int argc, char **argv)
  {
      const char *d = "/usr/bin";
      const char* f = "filename.txt";
      char result[strlen(d) + strlen(f) + 2];
      combine(result, d, f);
      printf("%s\n", result);
      return 0;
  }
  </code></pre>
  
  <p>Any suggestions for more improvements?</p>