-1

I'm having some problems with dynamic allocation, because I don't want to specify the size of the array. Basically what I need in my program is to store a name of a file in an array and make sure it is not wasting space.

I was trying to do something like creating the array name[255] to make sure it had enough space and then dynamically allocate it so it had only the required space, like writing "matrix5", then store it in name[255] and then change name[255] to name[8].

char file_name[255];

printf("what is the name of the file? [.txt]\n");
scanf_s(" %s", file_name[255]); //store name eg: "matrix5"

i = 0;
char **fullpath;
while (file_name[i] != '\0' && i <=strlen(file_name))
{
    fullpath= (char**)malloc(sizeof(char*));  //In here it would then make file_name[255] into file_name[8]                             
    fullpath[i] = file_name[i];
    i++;
}

What do I need to do here?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
LuisM
  • 11
  • 1
  • 3
    Post the code you used, sample input and expected output. – chux - Reinstate Monica Jun 02 '17 at 17:58
  • 3
    As always, `scanf_s()` isn't used correctly. – EOF Jun 02 '17 at 18:15
  • 2
    `scanf_s(" %s", file_name);` is missing a length argument. – chux - Reinstate Monica Jun 02 '17 at 18:15
  • thanks for the input, will be editing to correct this mistakes – LuisM Jun 02 '17 at 18:24
  • Note that `scanf_s(" %s", file_name[255]);` is worse than before. You need 3 arguments to `scanf_s()` in this context — you should have `if (scanf_s("%s", file_name, (unsigned)sizeof(file_name)) == 1) { …process file name… }`. See [`scanf_s()`](https://msdn.microsoft.com/en-us/library/w40768et.aspx) for why the `unsigned` cast is needed. – Jonathan Leffler Jun 02 '17 at 18:41
  • Are you working on a RAM-restricted system with no virtual memory manager? If not, just stick with [255]. – ThingyWotsit Jun 02 '17 at 18:41
  • true, it is easier to do that but since this is for college I am trying to do it with memory allocation since my professor asked. Maybe it would be easier to just ask the number of characters of the file_name, then do malloc and be done with it lol – LuisM Jun 02 '17 at 18:54
  • @JonathanLeffler Hmmm, MS with `scanf_s()` wants `unsigned` yet C11 Annex K wants `rsize_t/size_t`. --> A sad state of affairs. – chux - Reinstate Monica Jun 02 '17 at 21:42
  • @chux: yes — see also [Do you use the TR 24731 'safe' functions](https://stackoverflow.com/questions/372980/do-you-use-the-tr-24731-safe-functions). – Jonathan Leffler Jun 02 '17 at 21:44

3 Answers3

3

File names and path names typically have a maximal length that the system can handle. Example MAX_PATH. Declare an array the hold user input. IMO, I would use a 2x sized array for user input.

//                                +1 for \n
#define MY_BUFFER_SIZE (MAX_PATH*2 + 1)
char my_buffer[MY_BUFFER_SIZE];

Read the file name

printf("what is the name of the file? [.txt]\n");
if (fgets(my_buffer, sizeof my_buffer, stdin) == NULL) {
  Handle_EnfOfFile_or_InputError();
  return NULL;
}

Lop off the potential trailing \n

my_buffer[strcspn(my_buffer, "\n")] = '\0';

Create a duplicate

return strdup(my_buffer);

strdup() is not a stand C library function but easy enough to code. Example.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
1

That is how you would allocate a c-string dynamically:

char* name = malloc(sizeof(char)*(length+1)); //length of the filename plus \0 
Shiro
  • 2,610
  • 2
  • 20
  • 36
  • 1
    Curious, As `sizeof(char)` is always 1, why use `sizeof(char)*(length+1)` instead of `length+1` or `sizeof *name * (length+1)`? – chux - Reinstate Monica Jun 02 '17 at 18:17
  • I like consistency, so when needing the size of an int, you can just replace 'char' with 'int. And also when copying code modifications become easier. – Shiro Jun 02 '17 at 18:24
  • 5
    I believe that was the point of the suggestion `sizeof *name` which is low-maintenance and can be a consistent coding style. – Weather Vane Jun 02 '17 at 18:27
  • Of course this is personal preference, but I think my version is more readable. – Shiro Jun 02 '17 at 18:30
  • 2
    @Shiro Consider reviewing someone else's code 1000s of lines of code which has a bug - somewhere. `data.str = malloc(sizeof *data.str * n)` versus `data.str = malloc(sizeof(some_type) * n)` with the member `str` type defined in some other `#include` file. The first is more likely coded correctly, lower maintenance, easier to review than the 2nd which obligates a lookup in that distant `.h` file.. IMO, it is not a personal preference, but a group/company coding standard preference. Still, thanks for you thoughts. – chux - Reinstate Monica Jun 02 '17 at 18:39
  • "I think my version is more readable" ... so you think `sizeof(char)*(length+1)` is "more readable" than `(sizeof *name) * (length + 1)`? Wow, that's clutching at straws... I mean, for the disputable *slight* gain in *readability* you have an indisputable *significant* loss in *maintainability*. Is the trade-off worth it? – autistic Jun 03 '17 at 01:32
0

Are you familiar with strdup?

This will return a pointer to an allocated memory (that will need to be free by you later) with a copy of the string, and makes the code much simpler.

Tip: use strndup if you are not copying constant strings.

Jonatan Goebel
  • 1,107
  • 9
  • 14