-1

im trying to make a program which reads what we wrote without concerning the memory, and print out what we wrote! but it goes to segmentation fault (core dump)

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

int isdigit(char c); 
int main()
{
    char *input
    int length;

    printf("Number or Letter\n");
    gets(input);
    input = (char*)malloc(sizeof(char)*strlen(input));
    printf(input[0]);
    return 0;
}
  • 6
    `strlen(input)`. How can you get the length of a string when there is no string there yet? `input` is uninitialised and thus points to some random (likely invalid memory) location. Trying to use it makes no sense and results in Undefined Behaviour. – kaylum Oct 15 '16 at 05:23
  • 1
    Don't use `gets()`; see [Why `gets()` is too dangerous to be used, ever!](http://stackoverflow.com/questions/1694036/why-is-the-gets-function-dangerous-why-should-it-not-be-used). And don't use `printf(input[0])`; you're supposed to pass a `char *` and not a `char` as the first argument to `printf()`, and don't pass what the user entered as the format string. – Jonathan Leffler Oct 15 '16 at 05:26
  • `printf(input[0]);` also makes no sense. At least read the [printf man page](https://linux.die.net/man/3/printf) to see what parameters it requires and if that isn't clear do a search as there are millions of examples of correct `printf` usage. – kaylum Oct 15 '16 at 05:27
  • 1
    Now you have changed it to fix one problem but have made it equally bad. `gets(input);` How can you expect to write into `input` when it is uninitalised and does not point to a valid memory buffer? Does it make sense to you that you write to it and then malloc for it *after*? – kaylum Oct 15 '16 at 05:29
  • @JonathanLeffler i used gets()function because what i wanted to make doesnt need to concerning the memory problem. – qfqwerqgfzsdfew Oct 15 '16 at 05:33
  • You've demonstrated that you can't use it safely — your code won't work. Please do not use `gets()` ever — at least, not in questions you ask on SO, or in answers you submit on SO. And don't use it in any production code, or any good quality test code. And remember that prototype code tends to live forever too, so it isn't safe to use it in prototype code —— actually, it simply isn't safe to use `gets()` anywhere, any time, which is about where we started. – Jonathan Leffler Oct 15 '16 at 05:34
  • The common thing to do is to define a MAX_LEN value and use that for your `malloc`. Something like: `#define MAX_LEN 256` then `char *input = malloc(MAX_LEN); fgets(input, MAX_LEN, stdin);` – kaylum Oct 15 '16 at 05:41
  • @kaylum it doesnt make a sense to me. Because, if i #define LENGTH 256, then it starts with deciding the size of an string. What should i do if i want to use&decide exact memory of what i wrote ?? – qfqwerqgfzsdfew Oct 15 '16 at 05:49
  • 1
    You cannot know the length of the string until you read it. And to read it you need to allocate memory. So you cannot do the two things at the same time. The allocation must come first then the read. One possible way is to get the user to enter the string length first and then enter the string. – kaylum Oct 15 '16 at 05:55
  • 1
    If you really want to deal with arbitrarily long input lines and you think that `char input[4096];` is problematic (why?), then consider using POSIX [`getline()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getline.html). It will grow the space used until it is long enough for the current line (or there's no memory left). Unless you're working in an unusual (e.g. embedded) environment with minimal space. Often, 4 KiB will be long enough. If it's not, `getline()` works. If you don't have `getline()`, you can iterate with `fgets()` and `realloc()`. – Jonathan Leffler Oct 15 '16 at 06:09
  • @JonathanLeffler Thank you!! appreciate it!! – qfqwerqgfzsdfew Oct 15 '16 at 06:18
  • In addition to everything above, you are missing `#include `. Because you are casting the return value of `malloc`, your compiler isn't catching this since without `stdlib.h` it assumes `malloc` returns `int`, and you are casting that `int` to a pointer which will cause issues. You do not need to cast `malloc` return values in C. – PhantomWhiskers Oct 15 '16 at 06:36

1 Answers1

0

To read in an arbitrary long input string, you must use some kind of memory re-allocation when the input string grows beyond the already allocated memory. For instance you could use realloc like this:

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

#define INCREASE 32

int main(void) {
    int c;
    int allocated = INCREASE;
    int used = 1;
    char* in = malloc(allocated*sizeof(char));
    if (!in) exit(1);
    *in = '\0';

    while((c = fgetc(stdin)) != EOF && c != '\n')
    {
        if (used > (allocated-1))
        {
            // printf("Realloc\n");
            allocated += INCREASE;
            char* t = realloc(in, allocated);
            if (t)
            {
                in = t;
            }
            else
            {
                free(in);
                exit(1);
            }
        }

        in[used-1] = c;
        in[used] = '\0';
        ++used;
    }
    printf("%s\n", in);
    free(in);
    return 0;
}
Support Ukraine
  • 42,271
  • 4
  • 38
  • 63