1

I'm trying to concatenate two strings to be used as a path for fopen(). I have the following code:

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

void main() {
    char *inputchar = (char*)malloc(sizeof(char)), *absolutepath = (char*)malloc(sizeof(char));
    FILE *filepointer;

    gets(inputchar); //Name of the file that the user wants
    absolutepath = "D:\\Files\\";
    strcat(*inputchar, *absolutepath); //Error occurs here
    filepointer = fopen(*inputchar, "r"); //Do I need to use the deference operator?
    fclose(filepointer);
    free(inputchar);
    free(absolutepath);
}

Error occurs at strcat(). What happened there?

And is it correct that I have to use deference operator for inputchar at fopen()?

Richard
  • 7,037
  • 2
  • 23
  • 76

1 Answers1

2

Here are 3 things to fix:

  1. You allocate space for exactly 1 character for inputchar. Thus getting a string longer than 0 characters with gets messes up your program's memory. Why longer than 0 character? Because gets writes a terminating 0 character at the end of the string. So allocate something more, e.g.

    char *inputchar = (char*)malloc(256*sizeof(char));
    
  2. absolutepath = "D:\\Files\\"; "D:\\files\\" is a string literal whose value is determined by the compiler. So you don't need to allocate space for that string with malloc. You can just say:

    char *absolutepath = "D:\\Files\\";
    
  3. When calling strcat, you give the pointer values to it, rather than the first characters of your strings. So you should do

    strcat(inputchar, absolutepath);
    

    instead of

    strcat(*inputchar, *absolutepath);
    

I would recommend reading some beginners C resource, e.g. this http://www.learn-c.org/en/Strings could be good for you.

user694733
  • 15,208
  • 2
  • 42
  • 68
Sami Sallinen
  • 3,203
  • 12
  • 16
  • Thank you for your answer! I've read: http://www.learn-c.org/en/Pointers, http://www.learn-c.org/en/Dynamic_allocation and http://www.learn-c.org/en/Strings. I still have some questions, though. We usually use (char*)malloc(strlen(userinput)*sizeof(char)) instead of some fixed number like 256, right? Based on your answer and some reading from the links, I assume we don't use malloc on *absolutepath because a string literal tells the compiler to calculate the size of the string and allocate that much memory for the string literal, did I get it right?.......................... – Richard May 31 '18 at 03:56
  • ................... If, say, I make a variable "yourname[]", will I be able to scanf("%s", yourname)? Or do I have to explicitly state the size of the array for yourname, e.g. yourname[10], to scan user input? For your point one, I've tried using that declaration of char* with malloc allocating less than enough memory for the input of a user, but why does my program work? When will error occur when I allocate less memory to the pointer variable than needed? – Richard May 31 '18 at 04:00
  • On mallocing a fixed size vs exactly the correct size: yes, you should prefer the correct size when you can know it beforehand, but when you are reading user input, you don't know how much there is going to be. So, you should choose a maximum length a priori and maybe instead of gets() use scanf("%256s", string); which allows you to set the maximum length that scanf will return. And when you get that far, you can as well allocate the string on the stack rather than from the heap since you anyway have to decide it's size. – Sami Sallinen May 31 '18 at 04:58
  • Malloc allocates memory from the heap, and you have to free that memory manually. A string literal is made part of the program code and it is always there, so you don't need to allocate or free it manually. – Sami Sallinen May 31 '18 at 04:59
  • I see. So for the most part, you can allocate memory on stack unless the data is too large? (I've read this too: https://stackoverflow.com/questions/18217525/why-or-when-do-you-need-to-dynamically-allocate-memory-in-c.) Thank you for the comment, I forgot to mention you on my second comment, would you please take a look at it :-)? – Richard May 31 '18 at 07:31
  • When you allocate on the stack, you have to always set the size explicitly. So you can do this: char buf[256]; scanf("%255s", buf); – Sami Sallinen May 31 '18 at 07:35