0

I have the following typedef in my code:

typedef char * string;

And I need to have the user input a string so that I can then parse it and use the contents later. If I am just declaring a string with this definition it works, like this:

string bob = "My name is bob!;
printf("%s\n", bob);

What should I use to get user input when using this, scanf() and fgets() both give me Segmentation fault (core dumped) errors when I try to use them.

This is for school, which is why I need to use the typedef this way.

Bob Bob
  • 1
  • 1
  • 2
    The problem is not your typedef; you can use it as if you wrote `char *`. The problem is the target: When initializing `bob` with a string literal, it usually resides in non-writeable memory, hence the segfault (technically, it's UB). Try to initialize it with `malloc()` – Ctx Nov 16 '17 at 19:36
  • string literals are in read only memory. You can't change them. So can't use in scanf either. Use `char str[MAXSIZE]` or `char *str =malloc(sizeof (char) *MAXSIZE)`. Trying to modify a readonly memory is undefined behavior. Also with the `malloc` when you allocate..check for the return value and also dont forget to `free` them. In this case, as you have said `typedef has problem`...no it has not. `typedef` should be used in case of complicated types that you want to use...here it loses readability because of `typedef`-ing `char*`. Segfaults-caused by program trying to read/write illegal memory – user2736738 Nov 16 '17 at 19:37
  • 2
    It is not a good idea in C to [`typedef` a pointer](https://stackoverflow.com/questions/750178/is-it-a-good-idea-to-typedef-pointers). – Weather Vane Nov 16 '17 at 19:39
  • @coderredoc Detail: "string literals are in read only memory" is almost right and a useful axiom for a learner. Yet there is no read-only memory requirement in C. Writing to a _string literal_ might "work", it might not. After all it is is UB. – chux - Reinstate Monica Nov 16 '17 at 19:56
  • Thanks so much for your answers everybody, they helped a lot! – Bob Bob Nov 16 '17 at 20:04
  • @WeatherVane In [select cases](https://stackoverflow.com/a/750341/2410359) of [information hiding](https://en.wikipedia.org/wiki/Information_hiding), `typedef` a pointer is good. Even though I do not favor `typedef char * string;`, for learners, it is (unfortunately) common. – chux - Reinstate Monica Nov 16 '17 at 20:22
  • @chux once, I too used to `typedef` pointers because they made the code easier to write ~ actually compile! They made the syntax easier. But later I understood that, when familiar with the syntax, it makes the code *harder* to understand. This comment is really to OP. – Weather Vane Nov 16 '17 at 20:31

3 Answers3

0

you can typedef a pointer variable but must be taken care while using or accessing that typedefed pointer variable because normally you won't see * symbol in declaration and definition may be somewhere else and you may treat as a normal variable.

If you want to take input for pointer variable from runtime or from file first you should allocate the memory.

int main()
    {
            typedef char * string;// now string also a char pointer
            string bob;// bob is pointer variable
            printf("enter the string\n");
            scanf("%s",bob);//bob is uninitialized pointer .. u can't put any data
            printf("%s\n", bob);
          //once job is done free dynamically allocated memory using free function 
    }

Above code will cause segmentation fault,So allocate the memory dynamically first.

        string bob;
        bob = malloc(SIZE);//how much memory you want , mention in SIZE variable.
        printf("enter the string\n");
        scanf("%s",bob);
        printf("%s\n", bob);
Achal
  • 11,821
  • 2
  • 15
  • 37
0

That's because you have to set your starting value.
Assume you have char * a;
a has an undefined value, maybe pointing to an unauthorized area. You can not write in there.

What should you do? If you must use typedef char * string; , you have to write it on:
1) Dynamic heap, 2) on a buffer at the stack.

1) Use malloc - a function which has to be included from stdlib.h, and allocates memory at the Dynamic heap. The function returns a pointer to the start of the memory allocated.
Don't forget after using it to free the allocated memory to avoid leak, by free() function.

2) Declaring a foretold array size of chars, and give it's address to your variable.

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

#define MY_SIZE 50
typedef char * string;

int main() {
    string s;

    // 1)
    s = malloc(MY_SIZE);
    // some code
    free(s);

    // 2)
    char buf[MY_SIZE];
    s = buf;

    return 0;
}

You have to practice both ways.
Hope that I've helped!

Yinon
  • 945
  • 1
  • 8
  • 21
0

How to get string from user when using typedef? (typedef char * string;)

string bob needs to be assigned a value, a memory location is which to store the data read.

#define N 80 

// local array
char buf[N];
string bob = buf;
fgets(bob, N, stdin); 

// or malloc
string bob = malloc(N);
if (bob == NULL) Handle_OutOfMemory(); 
fgets(bob, N, stdin); 

Now trim the potential '\n'

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

Print result

printf("<%s>\n", bob);

... and use the contents later.

This implies code should use a right-sized memory allocation for use well passed this input code. strdup() is not in the standard C library, but very common. Sample code.

 // local array approach
 bob = strdup(bob);
 // Now bob points to allocated memory

 // malloc approach
 // re-size to be efficient
 void *t = realloc(bob, strlen(bob) + 1);
 if (t) {
   bob = t;
 }
 // Detail: A realloc to a smaller amount of memory rarely ever fails.
 // If it did fail, just continue with old pointer.

If bob points to allocated memory, clean up when done with bob.

free(bob);

Only use scanf() if required and you can't drop the class or get employment elsewhere.

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