Need help with pointers

Discussion in 'C' started by brian96853@yahoo.com, Nov 17, 2010.

  1. brian96853@yahoo.com

    brian96853@yahoo.com New Member

    Joined:
    Nov 17, 2010
    Messages:
    2
    Likes Received:
    0
    Trophy Points:
    0
    I am having trouble with pointers. Not really understanding what is going wrong with my code, but I am trying to print a running cost for an array and it is not working. It is giving me a 0 cost for all my types and put in the same location. Someone please help. I am struggling with this. I listed code to see if anyone would even want to take a shot a deciphering this. Some unecessary code is left out.

     
    Code:
    char *strings[] = {"Camping" , "Tennis " , "Golf " , "Snow Sports" , "Water Sports" , NULL}; //string array/pointer
    int type[5] = {0}; type array
    int main()
    {
     
    int choice, more = TRUE;
     
     
    do
    {
    choice = menu(); //main menu screen alwas choose add.
    switch (choice)
    {
    case 1: add(); break;
    case 2: //report(); break;
    case 3:
    case 4:
    case 5: return 0; break; //exit program from main menu
    default: printf("Error in selection\n"
    "Please try again");
    }
    }
    while(more);
    return 0;
    }
    int menu()
    {
    int fake;
    printf("Sierra \n");
    printf("1 Add \n");
    printf("2 Report \n");
    printf("3 Delete Record \n");
    printf("4 Change Record \n");
    printf("5 Quit \n");
    fake = valid1(1, 5, "Enter your selection");
     
    return(fake);
    }
     
     
    void add() /add function takes in all other functions to add every.
    {
     
    int invn, types, quant, MINI, MAXI, MINT, MAXT, MINQ, MAXQ, point, *ptr2;
    double cost, price, MINC, MAXC, MINP, MAXP;
    char c, desc, description[40], *labptr; 
    char line[15];
    FILE *fp;
     
     
    labptr = description;
     
    ptr2 = type; //pointer to array type
    fp = fopen("Limits.txt", "rt"); //opens limits.txt and reads text file.
    if (fp == NULL) //check for non existing file.
    {
    printf("File does not exist. ");
    exit(1);
    }
    while (fscanf(fp, "%d %d %d %d %d %d %lf %lf %lf %lf" ,&MINI, &MAXI, &MINT, &MAXT, 
    &MINQ, &MAXQ, &MINC, &MAXC, &MINP, &MAXP ) != EOF)
    fclose(fp);
     
    init_costs(type, 5);
    do
    {
     
    invn = getint("Product Number", MINI, MAXI); //getint functions to
    types = getint("Product Type", MINT, MAXT); //return values of 
     
    quant = getint("Quantity", MINQ, MAXQ); //quant. type, etc.
    cost = getreal("Cost", MINC, MAXC); //getreal returns
    price = getreal("Price", MINP, MAXP); //cost and price
     
    type[types - 1] += cost; //this is part of the trouble
     
    show(invn, description, quant, cost, price);
     
     
    c = getyn("Would you like to continue?\n");
    }
    while(c != 'N');
    show_costs(strings, *ptr2, 5); //trouble with pointer
    return;
    }
    int getint(char item[], int min, int max)
    {
    int err, inn;
    do
    {
    printf("Enter %s between %04d and %04d: ", item, min, max); //printing and scanning, and initializing ints and doubles 
    scanf_s("%d%*c", &inn); //to create menu.
    err = (inn < min) || (inn > max);
    if(err) error(min, max);
    }
    while(err);
    return(inn);
    }
    void error(int min, int max)
    {
    printf("\nOut of bounds" , min, max);
    return;
    }
    double getreal(char item2[], double min2, double max2)
    {
    double err2, dbl;
    do
    {
    printf("Enter %s between %06.2lf and %06.2lf: ", item2, min2, max2); //printing and scanning, and initializing ints and doubles 
    scanf_s("%lf%*c", &dbl); //to create menu.
    err2 = (dbl < min2) || (dbl > max2);
    if(err2) error2(min2, max2);
    }
    while(err2);
    return(dbl);
    }
    void error2(double min2, double max2)
    {
    printf("\nOut of bounds\n" , min2, max2);
    return;
    }
    double totalc(double j, int k) //do i need to put this somewhere?
    {
    double n;
    n = j*k;
    return n;
    }
    
    void show(int invn, char description[], int quant, double cost, double price)
    {
    double calc1;
     
    printf("\nProduct number : %04d" , invn);
    printf("\nProduct type is : %s", description);
    printf("\nQuantity : %03d" , quant);
    printf("\nCost : $%06.2lf" , cost);
    printf("\nPrice : $%06.2lf" , price);
    calc1 = totalc(cost, quant);
    printf("\nTotal Cost : $%06.2lf " , calc1);
    calc1 = totalc(price, quant);
    printf("\nTotla Price : $%06.2lf" , calc1);
    printf("\n\n");
     
    printf("\n\n");
    printf("Press anything to continue ");
    getchar();
     
    }
    void message(char msg[])
    {
    printf("%s, press \"Enter\" to continue\n", msg);
    getchar();
    }
    int valid1(int min3, int max3, char item[])
    {
    int n;
    printf("Enter the %s %d to %d: ", item, min3, max3);
    scanf("%d%*c", &n);
    while(n < min3 || n > max3)
    {
    printf("\nRange error, \a");
    printf("Enter the %s %d to %d: ", item, min3, max3);
    scanf("%d%*c", &n);
    }
    return(n);
    }
    void init_costs(int *ptr1, int max)
    {
    ptr1 = 0;
     
    }
    void show_costs(char *strings[], int ptr2, int max) //pointer trouble
    {
    int i, total = 0;
     
     
    printf("Type Dept Cost\n");
     
    for(i = 0; i < max; i++, ptr2++)
    {
    total += ptr2;
    printf("\n %d %s $%7.2lf, %p(locations) \n" , i + 1, strings[i], ptr2, (void *)&ptr2);
    }
     
    printf("\n\n");
    printf("Press anything to continue ");
    getchar();
    }
    }
    
    This is what gets brought up and I need my cost to actually contain a value.

    Type Dept Cost
    1 Camping $ 0.00, 0033FA64(locations)
    2 Tennis $ 0.00, 0033FA64(locations)
    3 Golf $ 0.00, 0033FA64(locations)
    4 Snow Sports $ 0.00, 0033FA64(locations)
    5 Water Sports $ 0.00, 0033FA64(locations)
     
    Last edited by a moderator: Nov 17, 2010
  2. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    First of all when posting code, USE CODE BLOCKS. Not doing so shows you haven't read the posting guidelines. This is bordering on rude, but you can redeem yourself by READING THEM NOW.

    Using code blocks preserves the formatting and saves me the few minutes it's now going to take me to reformat the code so that it is readable...
     
  3. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    What does limits.txt contain? (NB: please only post the MINIMAL amount of data needed for the problem.)

    Also what input do you give the program?

    While reading the code I found a couple of other things:
    Code:
    type[types - 1] += cost; //this is part of the trouble
    
    1. OK, this throws a warning: conversion from double to int, possible loss of precision. type[] is an array of int, why do you want to add a double to its members? If it stores a double value, why isn't it an array of double?

    2. Replaced all scanfs with fgets. The scanf family is fine for reading formatted data from files, but for getting user input it's just not up to the job. For example:
    Code:
    	char buf[32];
    	fgets(buf,30,stdin);
    	n=atoi(buf);
    	//scanf("%d%*c", &n);
    
    OK I guess this is the line you're struggling with:
    Code:
    printf("\n %d %s $%7.2lf, %p(locations) \n" , i + 1, strings[i], ptr2, (void *)&ptr2);
    
    First clue you're having problems is the cast. NEVER USE CASTS UNLESS YOU KNOW EXACTLY WHAT YOU ARE DOING!!!!! You almost *never* need to use a cast. Don't EVER interpret a compiler error to mean "you need a cast, mate". So, let's see what error it's hiding...remove cast, compile...oh, there isn't one. Hmm.

    So the problem here is that it displays a pointer. Well, that's what you're telling it to do. According to the Visual Studio 2008 documentation %p means "Prints the argument as an address in hexadecimal digits." And you're passing in the address of ptr2, so it's doing what you told it to.

    Code:
    void show_costs(char *strings[], int ptr2, int max) //pointer trouble
                                     ^^^^^^^^
    
    OK, so maybe you're having "pointer trouble" because ptr2 isn't a pointer. It's an int. And you get 0033FA64 because that's the value of &ptr2, i.e. the address in memory of ptr2, and it's the same on all rows because this doesn't change.

    Another problem is presumably that the dollar value printed is zero. The parameter corresponding to $%7.2lf is.....ptr2! The integer from previously. So that won't work. What variable should it display? Not type[N] of course, cos this is an array of int. And definitely not ptr2.


    Contrary to popular opinion, pointers are really easy. A pointer is a variable that holds the address in memory of another variable. So suppose we have a variable x
    Code:
    int x;
    
    that the compiler decides to put at location 0x1000 in memory. Let's have a pointer now:
    Code:
    int *ptr_to_x = &x;
    
    Defining it as int* instead of int tells the compiler it's a pointer. The & in this context tells the compiler we want the address of x. So now ptr_to_x contains the value 0x1000. So lets write directly to the variable, and display the value from the pointer:
    Code:
    x=5;
    printf("x contains %d\n",*ptr_to_x);
    
    The * in this context tells the compiler to DEREFERENCE the pointer ptr_to_x. Which means it looks at the value in ptr_to_x (0x1000) and takes this as a memory location, then looks in that memory location for the value (5).

    In many respects ptr_to_x is a normal variable. It also has a location in memory. We can do the same with ptr_to_x as we did to x:
    Code:
    int **ptr_to_ptr_to_x;
    ptr_to_ptr_to_x = &ptr_to_x;
    printf("x contains %d\n",**ptr_to_ptr_to_x);
    
    Don't let that confuse you. int** means it's a pointer to a pointer to something. Real world example: Where does the Queen live? The answer is in that box. That box contains a piece of paper that states "Buckingham Palace". The piece of paper is the pointer to (address of) the Queen. "In that box" is a pointer to the pointer to the Queen.

    What you cannot do here is initialise ptr_to_ptr_to_x directly from x.
    Code:
    int **ptr_to_ptr_to_x = &&amp;x; // NOT VALID
    
    Address-of (&) can only be done once.

    In C(++) pointers are useful (among other things) for modifying variables within a function.
    Code:
    int x=5;
    myfunc(x, &x);
    
    ...
    void myfunc(int z, int *ptr)
    {
      z=7; // modifies the local variable z, not x.
      ptr=0x1000; // store a new address in ptr
      *ptr=8; // without the previous line that modifies ptr, this would store 8 into x.
    }
    
    This is because C doesn't support pass-by-reference, only pass-by-value, so you have to take the address of a variable and pass its address in if you want to modify it.
     
    brian96853@yahoo.com likes this.
  4. brian96853@yahoo.com

    brian96853@yahoo.com New Member

    Joined:
    Nov 17, 2010
    Messages:
    2
    Likes Received:
    0
    Trophy Points:
    0
    Thank you very Much! And sorry for not reading the guidlines...I have been struggling with this for a while and my teacher has not helped me with anything and have been struggling ever since he introduced pointers. Thanks Again!
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice