1

I have a function that read string from stdin which based on answer from here,

    char* ReadString (FILE* f) {
    int chr;
    int n=0;
    size_t size=4;
    char *st=(char*)malloc(size*sizeof(char));
    while (((chr=fgetc(f))!='\n') && (chr != EOF) ) {
        st[n]=chr;
        if (n+1==size)
            st=(char*)realloc(st,(size+=8)*sizeof(char));
        n++;
    }
    st[n]='\0';
return (char*)realloc(st,sizeof(char)*n);
}

Well function works ok, but I found a problem.

int k;
printf("number\n");
scanf("%d",&k);
while (!loop) { //infinite loof for tests
        printf("Name of the file and distination\n");
        fname= ReadString(stdin);
        printf("\"%s\"\n",fname); 
}

Now I will get a segmentation fault. Well the problem, as I understood, is that after scanf, in stdin "\n" is left. If I put

while ( getchar() != '\n' ); // clean stdin 
        fname= ReadString(stdin);

Than I will not get segmentation fault, first string will read perfectly but the next string will not read correctly I will need to enter twice. Why (((chr=fgetc(f))!='\n') && (chr != EOF) ) is not working? -------------Answer--------------

Based on answer below here is the code for future.

char* ReadString (FILE* f) {
    int chr;
    int n=0;
    size_t size=4;
    char *st=(char*)malloc(size);
    bool loop=false;
    while (!loop) {
        while (((chr=fgetc(f))!='\n') && (chr != EOF) ) {
            st[n]=chr;
            if (n+1==size)
                st=(char*)realloc(st,(size+=8)*sizeof(char));
            n++;
        }
        loop=true;
        if (n==0)
            loop=false;
    }
    if (n!=0 )
        st = (char*)realloc(st,sizeof(char)*n);
    st[n]='\0';
return st;
}
2
  • Don't cast malloc(). Commented Jan 22, 2017 at 16:08
  • Multiplying by sizeof (char) is redundant: sizeof (char) is 1 by definition. Commented Jan 22, 2017 at 16:09

1 Answer 1

1

You have an off-by-one error in your last realloc. Your string stores n+1 bytes but you shorten the allocation to n bytes.

If the first character read is a newline, your loop never runs. Your st string consists of 0 characters, followed by a '\0' terminator, i.e. it uses 1 byte of storage.

But n is 0, so realloc(st,sizeof(char)*n) reallocates it down to 0 bytes, which probably frees the string (or returns a pointer to 0 bytes of memory, which must not be dereferenced).

The easiest solution is to just return st without reallocating it. Otherwise it should be something like return realloc(st, n+1); (but you should really check all of your realloc calls for errors).

Sign up to request clarification or add additional context in comments.

2 Comments

well you right, Now it read everything. But one more moment now since stdin has "\n", it read first empty string... Is it possible to ignore it?
@alex_mike The solution to that is to never use scanf. Do all user input by reading whole lines (using fgets or your ReadString). Once you have a line, you can convert it to a number by using e.g. atoi or sscanf.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.