Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie
Hi there,
There is an issue with role permissions that is being worked on at the moment.
If you are having trouble with access or permissions on regional forums please post here to get access: https://www.boards.ie/discussion/2058365403/you-do-not-have-permission-for-that#latest

Simple C help!

  • 02-11-2007 2:36pm
    #1
    Registered Users, Registered Users 2 Posts: 12,046 ✭✭✭✭


    I have a header file, which contains a struct and a function:
    struct point{
      double x, y;
    };
    typedef struct point point_t;
    
    point_t read_point(void){
      point_t p;
      printf("Please enter a point: ");
      scanf("%f%f", &p.x, &p.y);
      return p;
    }
    

    And I just have a simple program to start with to check that my function works properly:
    # include <stdio.h>
    # include <math.h>
    # include "point.h"
    
    int main(void){
      point_t p = read_point();
      printf("(%f, %f)", p.x, p.y);
      return 0;
    }
    

    It doesn't seem to work...it just spits out the same values, no matter what input I give so I think I need to use pointers to access the values properly but I'm not sure how?

    Any help would be great, thanks :)


Comments

  • Registered Users, Registered Users 2 Posts: 2,013 ✭✭✭lynchie


    point_t read_point(void){
      [COLOR="Red"]point_t p;[/COLOR]
      printf("Please enter a point: ");
      scanf("%f%f", &p.x, &p.y);
      return p;
    }
    

    the point struct is be declared at the beginning of the function. Its allocated on the stack and therefore will cease to exist once the function has returned. Your best bet is to declare the point_t in your c file and pass a pointer to it down as an argument to the read_point method.


  • Registered Users, Registered Users 2 Posts: 12,046 ✭✭✭✭L'prof


    I thought that this line in my c file would account for that?
    point_t p = read_point();
    

    But then again, if I knew what I was talking about, I wouldn't be on here!


  • Registered Users, Registered Users 2 Posts: 981 ✭✭✭fasty


    jasonorr wrote: »
    I thought that this line in my c file would account for that?
    point_t p = read_point();
    

    But then again, if I knew what I was talking about, I wouldn't be on here!

    That doesn't work for C, as lynchie say, p is on the heap and once the function returns it's out of scope and gone.

    Try:
    void read_point(point_t* p){
      printf("Please enter a point: ");
      scanf("%f%f", p->x, p->y);
    }
    

    Call the function with
    point_t p;
    read_point(&p);
    


  • Registered Users, Registered Users 2 Posts: 12,046 ✭✭✭✭L'prof


    I'll tried that just now and it doesn't seem to work, the program just freezes! but, I was told that the function doesn't actually need any arguments and, how would it be implemented then?


  • Registered Users, Registered Users 2 Posts: 413 ✭✭ianhobo


    It doesn't seem to work...it just spits out the same values
    What do you mean?
    That compiled and worked for me.
    It prints out the values that you entered.
    What do you want to happen?


  • Advertisement
  • Registered Users, Registered Users 2 Posts: 413 ✭✭ianhobo


    I copy and pasted your original code into one file,compiled it with gcc, and ran it. it works


  • Registered Users, Registered Users 2 Posts: 12,046 ✭✭✭✭L'prof


    # include <stdio.h>
    # include <math.h>
    # include "point.h"
    
    int main(void){
      point_t p = read_point();
      printf("(%f, %f)", p.x, p.y);
      return 0;
    }
    
    struct point{
      double x, y;
    };
    typedef struct point point_t;
    
    point_t read_point(void){
      point_t p;
      printf("Please enter a point: ");
      scanf("%f%f", &p.x, &p.y);
      return p;
    }
    

    So these lines of code work for you?

    When I compile it and enter 1 2 as input, I get:
    (0.000000, 196297699578146160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.00
    0000)
    

    If I enter 1 3 I get:
    (0.000000, 196297699728296500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.00
    0000)
    

    I'm using Visual Studio 2005 as a compiler! :confused:


  • Registered Users, Registered Users 2 Posts: 981 ✭✭✭fasty


    That code is the same as you posted earlier. It won't work!

    You need to pass a pointer to a point_t struct to your read_point function as a parameter.


  • Registered Users, Registered Users 2 Posts: 12,046 ✭✭✭✭L'prof


    That code is the same as you posted earlier. It won't work!

    You need to pass a pointer to a point_t struct to your read_point function as a parameter.

    I was replying to this:
    I copy and pasted your original code into one file,compiled it with gcc, and ran it. it works

    I thought he was trying to tell me that the original code without the pointers was working but, I can't get it to work with the pointers either...the program just freezes, I think when that's happened before I ran the same program on a Linux machine and I got a segmentation fault error!


  • Registered Users, Registered Users 2 Posts: 6,570 ✭✭✭daymobrew


    jasonorr wrote: »
    I thought he was trying to tell me that the original code without the pointers was working but, I can't get it to work with the pointers either...the program just freezes, I think when that's happened before I ran the same program on a Linux machine and I got a segmentation fault error!
    You have to change your function to accept and work with the pointer being sent.

    Look at your use of scanf() - you pass pointers to it and it puts the data into the variables you passed.
    Look at the declaration for scanf to see how describes the parameters it expects. Your function is currently not expecting any variables (the 'void' bit).


  • Advertisement
  • Registered Users, Registered Users 2 Posts: 1,306 ✭✭✭carveone


    Let's take a deep breath ;)

    First of all, there's nothing at all wrong with declaring variables on the stack (auto variables are not on the heap!) and returning them. A copy of them mind, not a pointer to them. Your "return p" is fine. So ignore the pointer people! Sure you can do it that way, but that is not what is wrong...
    
    struct point{
      [B]double x, y;[/B]
    };
    
    point_t read_point(void){
      point_t p;
      printf("Please enter a point: ");
      scanf([B]"%f%f"[/B], &p.x, &p.y);
      return p;
    }
    

    Look at the bolded lines. One is a double, the other is a float. They need to agree. scanf is a variadic function (one that takes a variable number of arguments). This means that scanf must trust you when you specify the arguments by means of the quoted string. The types of the arguments passed on the stack are not magically known... So in this case, you say %f for float, scanf takes you at your word and puts a float in there. Not good. Make the the string "%lf%lf" and you might have more luck.

    Oh by the way, ditto with the printf... gcc probably works because its floating point mechanism might be different. Dunno. implementation specific as they say...

    Conor.


  • Registered Users, Registered Users 2 Posts: 1,306 ✭✭✭carveone


    jasonorr wrote: »
    (0.000000, 196297699578146160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.00
    0000)
    

    Wow. That's so cool :p To me, that just screams "mismatched parameters types".

    It's easier to comprehend what's going on if you imagine passing say, a pointer to a 32 bit int and insisting that it be treated as a 16bit short.

    The integer starts life on the stack, so it is uninitialised garbage... Let's say: 0xF00FABCD. Then you take half of that 32 bits and put a number in there, say 0x01.

    Now you have 0xF00F0001. Maybe. Depends on the machine! Now you print that out...

    In the case of integers you might actually get away with this mistake because of the way the parts align. Floating point is anyone's guess!


  • Registered Users, Registered Users 2 Posts: 12,046 ✭✭✭✭L'prof


    Make the the string "%lf%lf" and you might have more luck.
    

    I love you, it works :D:cool:

    I was using %f because I think that work on the linux machine in college!


  • Registered Users, Registered Users 2 Posts: 1,306 ✭✭✭carveone


    :p You're welcome!

    C has a number of traps waiting for the unwary and that's one of them. float and double have the same relationship as short and int. That is, depending on platform, they may be the same size. Or not. The C spec only says that double can't be smaller than a float. So you get the great experience of having your program work on linux, say, and then break horribly on windows.

    Cheers,

    Conor.


  • Registered Users, Registered Users 2 Posts: 981 ✭✭✭fasty


    Well spotted! I wonder if there's a blush emoticon... Sorry for leading you down the wrong path, Jasonorr.


  • Registered Users, Registered Users 2 Posts: 12,046 ✭✭✭✭L'prof


    No worries fasty, I'm sure it wasn't intentional...thanks for your help anyway!


Advertisement