-2

I've reviewed the documentation:

It says here:

Once a file has been successfully opened, you can read from it using fscanf() or write to it using fprintf(). These functions work just like scanf() and printf(), except they require an extra first parameter, a FILE * for the file to be read/written.

So, I wrote my code as such, and I made sure to include a conditional statement to make sure that the file opened:

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

void from_user(int*b){

    b = malloc(10);
    printf("please give me an integer");
    scanf("%d",&b);

}

void main(){

    FILE *fp;

    int*ch = NULL;
    from_user(ch);
    fp = fopen("bfile.txt","w");

    if (fp == NULL){
        printf("the file did not open");
    }
    else {
        printf("this is what you entered %d",*ch);
        fprintf(fp,"%d",*ch);  
        fclose(fp);
        free(ch);   
    }
}

Am I wrong or is the documentation not explaining this correctly? thanks.

OlivierLi
  • 2,798
  • 1
  • 23
  • 30
makansij
  • 9,303
  • 37
  • 105
  • 183
  • I don't understand what you expect to happen, apart from what the quoted paragraph says? – Frxstrem Jan 28 '15 at 18:39
  • 2
    You are "wrong" in your `scanf` use inside `from_user` (`&` should not be there) and in general memory management (pointer value is not returned to `main`). It has nothing to do with `printf` vs. `fprintf` matter. – AnT stands with Russia Jan 28 '15 at 18:39
  • You may want to add a newline to the file when you print. Did you try opening the file in a text editor? – Thomas Matthews Jan 28 '15 at 18:40
  • `void main()` should be `int main(void)`. If a book, tutorial, or instructor told you to use `void main()`, **find a better one**. Allocating 10 bytes for an `int*` makes no sense. You want *one* `int` object, so `malloc(sizeof (int))` would make more sense -- but the `malloc` isn't necessary at all, since you already have an `int` object whose address is passed as a parameter. Except that you don't, since you initialized `ch` to `NULL`. Try: `int ch; from_user(&ch);`. – Keith Thompson Jan 28 '15 at 18:45
  • Your `from_user` function doesn't modify `ch` -- it can't, functions can't modify their arguments (modifying a parameter only updates a local copy of the argument). – Keith Thompson Jan 28 '15 at 18:47

3 Answers3

6

from_user() is not implemented correctly.

  1. The pointer that you create in from_user() will not be passed back to the calling function. To do that, you need a double pointer, or to pass by reference.

  2. In your code, you pass a int ** to scanf(), while it is expecting a variable of int *.

Here's a working implementation:

void from_user(int **b){
    *b = malloc(sizeof(int));
    printf("please give me an integer");
    scanf("%d", *b);
}

int main() {
    int *ch;
    from_user(&ch);
}

Your File IO

That part is all fine. It's just the value of ch that is broken.

Community
  • 1
  • 1
Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
  • Even single pointer is enough right? Anyways we have the location being allocated and initialized in the function the OP's scanf() has an issue – Gopi Jan 28 '15 at 18:41
  • @Gopi: If we want to edit the value of `ch`, then we need to pass the pointer to `ch`, or pass it by reference. – Bill Lynch Jan 28 '15 at 18:43
  • I meant why not do everything inside the func() and return the pointer like `int *from_user()` – Gopi Jan 28 '15 at 18:45
  • @Gopi: That would be fine, as would pm100's variant. I felt that this kept to the spirit of how the original code was intended to work. – Bill Lynch Jan 28 '15 at 18:46
3

a much simpler from_user implementation

int from_user(){
    int i;
    printf("please give me an integer");
    scanf("%d", &i);
    return i;
}

and in main

int ch = from_user();
...
      printf("this is what you entered %d",ch);
        fprintf(fp,"%d",ch);  
pm100
  • 48,078
  • 23
  • 82
  • 145
0

Simplest fix to your own code, you don't need to use double pointers, just allocate the memory in main and pass the pointer to your function, like this:

  1. Remove b = malloc(10);
  2. Remove the & before b in scanf
  3. Change int*ch = NULL; to int *ch = malloc(sizeof(int));

Done. Why does it matter where we allocate the memory? See my more detailed answer here: pointer of a pointer in linked list append

Oh and you should move free(ch) out from the else statement.

Community
  • 1
  • 1
Jite
  • 4,250
  • 1
  • 17
  • 18