Search code examples
cprintffgets

Issues with fgets and printf..printing a string


working on a c project and I've hit a roadblock. I'm trying to print the point coordinate style, and I've included all the code necessary to help you folks help me out!

//point.h
struct Point{
   char label;
   int x;
   int y;
};

//point.c
displayPoint(struct Point p){
   char label = p.label;
   int x = p.x;
   int y = p.y;

   // label: (x, y)
   printf("(%c: (%d, %d)", label, x, y);
 }


 //build point from standard input
 readPoint(){
    struct Point point;
    printf("Enter label (character): ");
    fgets(buff, MAX_LINE, stdin);
    point.label = buff; //I think this is the issue here
    printf("Enter x:");
    fgets(buff, MAX_LINE, stdin);
    point.x = (int) strtol(buff, NULL, MAX_LINE);
    printf("Enter y:");
    fgets(buff, MAX_LINE, stdin);
    point.y = (int) strtol(buff, NULL, MAX_LINE);

Upon compilation, I receive the following error:

points.c: In function 'displayPoint':
points.c: warning: initialization makes pointer from integer without a cast [enabled by default]
points.c: warning: format '%c' expects argument of type 'int', but argument 2 has   type 'char *' [-Wformat]
points.c: In function 'readPoint':
points.c: warning: assignment makes integer from pointer without a cast [enabled by default]

If I create a Point using the following information:

Label: A
x: 2
y: 3

and run displayPoint I get this output:

R: (2, 3)

Obviously that's wrong, I don't know where the R came from. What am I missing here? Why does C have to be so stubborn, this would be so simple to do in java, python, etc


Solution

  • You've got a couple of problems here:

    1. fgets gets a buffer, not a single character. I hope buff is declared as a character array (char buff[MAX_LINE]).

    2. Your struct declares a single character for its label, but you're assigning your buffer to the character.

    3. You're reusing the buffer. Because this is just a pointer to a chunk of memory, you're potentially clobbering old data. You might (read, probably will want to) reset your buffer between uses.

    Given this, I think what you intend is this:

    point.label = buff[0];
    

    I'm guessing you just want a single character for your label, in which case this should work and you won't be clobbering that value. (I don't know about the rest of your input.)