0

I am not able to print the strings. Need some help on what am I doing wrong and some insight on the best approach in these cases.

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

void getName(char *name);

int main()
{
    char name[256];
    getName(name);
    printf("Name = %s\n", name);
    return 0;
}

void getName(char *name)
{
    char line[256];
    printf("Please enter your name! \n");
    gets(line);
    name = (char *) malloc(strlen(line));
    strcpy(name, line);
}
Stefano Sanfilippo
  • 32,265
  • 7
  • 79
  • 80
anansharm
  • 183
  • 2
  • 4
  • 13
  • 1
    You are overriding what you pass a pointer to by what malloc returns and therefore copying to nirvana.... in your case just copy directly to name without malloc – A4L Jan 21 '14 at 22:21
  • 2
    And please, for the love of unicorns, [don't cast the return value of `malloc()` so badly!](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc/605858#605858) –  Jan 21 '14 at 22:21

4 Answers4

3

You don't need to do this, comment it out:

name = (char *) malloc(strlen(line));

You already passed in a buffer for name. You don't need to allocate a second buffer.

Also, you didn't add 1 to the allocation to account for the null terminator, but that's not relevant anyway since the allocation is unnecessary either way.

You could gets directly into name and cut out the line middleman, in fact.

StilesCrisis
  • 15,972
  • 4
  • 39
  • 62
3

You have over-complicated getname() - it just needs to be:

void getName(char *name)
{
    printf("Please enter your name! \n");
    gets(name);
}

Note that gets is widely considered to be an unsafe function to use, and you should try to get into the habit of using fgets instead.

Community
  • 1
  • 1
Paul R
  • 208,748
  • 37
  • 389
  • 560
  • No, it needs to be `fgets(name, size, stdin);` (where `size` is the size of the buffer). The `gets()` function is dangerous and deprecated. –  Jan 21 '14 at 22:22
  • never use gets(). user fgets() instead. It very insecure. See man gets. – Michał Šrajer Jan 21 '14 at 22:22
  • 1
    PaulR Your baby just stepped on a mine field. –  Jan 21 '14 at 22:23
  • If you want your baby to learn you have to let her make mistakes. – Paul R Jan 21 '14 at 22:25
  • What if I want to dynamically allocate the memory, What should I be doing in that case? – anansharm Jan 21 '14 at 22:28
  • 1
    @anansharm then `char *line = malloc(SOME_SIZE); fgets(line, SOME_SIZE, stdin);`. But in this case, you don't really need dynamic memory allocation. –  Jan 21 '14 at 22:29
  • 1
    Normally you would dynamically allocate in main() and pass the pointer into getname. It would then be up to main to eventually free the pointer when it is no longer needed. – Paul R Jan 21 '14 at 22:29
  • @H2CO3 I see what you are saying. – anansharm Jan 21 '14 at 22:39
3

what am I doing wrong

Others have already pointed out some of the errors, but nobody has shown the right solution yet.

Your code is inherently vulnerable to buffer overflows. The gets() function doesn't let you specify the buffer size, so if you enter more than 256 characters, this will write out of the bounds of your array. That's bad.

What you should do instead is

  1. not use a separate function for this (because it has no benefits in this particular case), and
  2. call fgets() on your array:

#include <stdio.h>

int main()
{
    char name[256];
    fgets(name, sizeof name, stdin);
    printf("Name = %s\n", name);
    return 0;
}

Also, if you ever consider dynamic memory allocation:

  1. Do not cast. It's a deadly sin.

  2. Check the return value of malloc().

  3. You will still want to keep track of the buffer size; how about a function like this?


#define NAME_LENGTH 256

char *getName(void)
{
    char *buf = malloc(NAME_LENGTH);
    if (buf == NULL) {
        return NULL;
    }

    fgets(buf, NAME_LENGTH, stdin);
    return buf;
}

But, as I mentioned in the comments, in this case you don't need dynamic memory allocation at all.

Community
  • 1
  • 1
  • 1
    When recommending a switch from `gets()` to `fgets()`, it's always a good idea to point out that when `fgets()` reads the entire input line, it doesn't discard the '\n' at the end. Handling the '\n' is trivial, yes, but you have to know it's there first. And you can't expect someone who's still using `gets()` to be aware of the difference without warning them. – This isn't my real name Jan 23 '14 at 02:59
0

I know that pointers can be complicated for beginners. So, forget about pointers. How do you expect the following code should run?

void change(int a)
{
   a = 10;
}

int main()
{
    int a = 20;
    change (a);
    printf("%d", a);  // It prints 20
}

(If you did understand the above code, read on. Otherwise, read about functions and scope of a variable.)

Your code has essentially the same structure, only that instead of an int a, you have a char *name. Observe that you have two different name identifiers here. One is getName's argument, and the other one is a constant pointer (an array identifier) defined in main. Changing the argument's value of a function doesn't change the value of the callers' parameter.

Ali Alavi
  • 2,367
  • 2
  • 18
  • 22
  • However, this is not OP's problem. The problem is that the pointer **is** changed within the function, so `gets()` won't write to the original array but somewhere else. –  Jan 21 '14 at 22:46
  • Yes it is OP's problem. And the value of a also is changed within the function :) – Ali Alavi Jan 21 '14 at 23:01
  • It's still not the problem. And I know how functions work, don't teach me C. Read the question instead. –  Jan 21 '14 at 23:05
  • Oh, the sarcasm. As if I didn't know what's happening and what should be changed to make the program work. –  Jan 21 '14 at 23:15
  • 1- Understand that I am answering based on your comment, not your knowledge. 2- I am pointing to the important mistakes that OP has made in the provided code using a simple example as an analogy. The example explains why the pointer 'name', allocated dynamically inside getName, cannot be accessed by printf function called in main. It also explains why the array address is not changed to the dynamically allocated memory. These are the main problems in OP's code, I believe. Now you you have 2 options:1-Arguing why they are not OP's problems. 2-Down-vote my answer. Bragging is not one of them. – Ali Alavi Jan 21 '14 at 23:40