Thread: #define comparisons and feof.

  1. #1
    Registered User
    Join Date
    Nov 2011
    Posts
    69

    #define comparisons and feof.

    How do I make this work?

    Code:
    #define BOUNDARIES 10 20 30 40 50 60 70 80 90 100
    
    index = (newnode->price == BOUNDARIES) ? (newnode->price / 10) - 1 : (int)newnode->price / 10;
    Compiler says: expected ')' before numeric constant.

    Also, I do this:

    Code:
        pos = 1;
        while ((c = fgetc(f)) != EOF) {
            fseek(f, pos - 2, SEEK_CUR);
            fscanf(f, "%s %lf", temp_title, &temp_price);
            insert(titles, prices, temp_title, temp_price);
        }
    But the last title and price that are read, are read twice. Why would that be?

    It reads from a file where data is in this form:

    <TITLE><space><PRICE>
    <TITLE><space><PRICE>
    <TITLE><space><PRICE>
    ...


    (no spaces in-between title)

  2. #2
    The superhaterodyne twomers's Avatar
    Join Date
    Dec 2005
    Location
    Ireland
    Posts
    2,273
    1) Very simplistically, #define replaces code segments with what its 'label' is defined as. So your
    Code:
    index = (newnode->price == BOUNDARIES) ? (newnode->price / 10) - 1 : (int)newnode->price / 10;
    after preprocessing reads like
    Code:
    index = (newnode->price == 10 20 30 40 50 60 70 80 90 100) ? (newnode->price / 10) - 1 : (int)newnode->price / 10;
    Does that make sense? Nope. So hence an error has occurred.

    What you'll have to do is make a function to loop over the list of possible prices, we'll call it findPrice, and compare against the newnode->price value. If it is found return something. Then your index assignment should read something like:
    Code:
    index = findPrice( newnode->price ) ? newnode->price/10-1 : (int)newnode->price/10;
    where you have defined the findPrice function.

    2) We'll have to see the insert function before we can judge why it putting it in twice.
    Last edited by twomers; 01-12-2012 at 06:14 AM. Reason: Pedantry

  3. #3
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    When fscanf fails the variables from the last read stay unchanged. So, the last time fails. check the return value to verify it is valid.

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  4. #4
    Registered User
    Join Date
    Nov 2011
    Posts
    69
    @twomers
    Yes, but isn't there a more "clever" way of doing that? It would take like 10 switch cases of almost identical code and that would certainly not look good, even though it would work.

    "index" must a number from 0 to 9, corresponding to prices (0-10], (10,20] etc (where '(' means not including and '[' means including.)

    Which obviously makes my code problematic since 10 would be placed at index = 1, while it needs to be placed at index = 0. That problem would occur for 10, 20, 30, ..., 100, and at 100 in particular it would go out of boundaries.

    @stahta
    Every title and price are scanned but the last one is scanned twice. As if feof somehow fails to recognise that EOF has been reached. Why is that?

  5. #5
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    It's not clear to me exactly what you want to accomplish, but how about something along these lines?

    Code:
    int values[] = { 10, 20, 30, 40 }, i;
    for (i = 0; i < 4; i++) {
         x == values[i] ? assign; break : continue;
    }
    This loop is totally wacky looking:

    Code:
    pos = 1;
    while ((c = fgetc(f)) != EOF) {
        fseek(f, pos - 2, SEEK_CUR);
        fscanf(f, "%s %lf", temp_title, &temp_price);
        insert(titles, prices, temp_title, temp_price);
    }
    What is it you are actually trying to do here? What's the point of "c"? It looks like you are just checking to see if you can read then rewinding. Zany. Not a good method. Forget the fgetc() and just make the condition:

    Code:
    while (fscanf(f, "%s %lf", temp_title, &temp_price) == 2) {
    That may need some tweaking depending on how consistently the file is structured.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  6. #6
    Registered User
    Join Date
    Nov 2011
    Posts
    69
    @MK27

    What the loop is trying to do, is:
    - each time, check if end of file has been reached
    - if it hasn't been reached, go on and scan the next title and price, then call 'insert' function to insert a new node with these attributes in a linked list.
    - if it has been reached, break from loop.

    Concerning those values, I roughly explained what I'm trying to do in post #4. Imagine an array where each position will point to the beginning of a linked list. This array has 10 positions: position 1 corresponds to prices (0-10], position 2 corresponds to prices (10-20] and so on.
    To find at which position the insertion is to be made, I thought I could do (int)price / 10. So, if the price was 9.21, it would be calculated as 9, divided by 10 and correctly "placed" in the first position. But then I noticed, 10, 20, 30, ..., 100 would be problematic cases since 10/10 would lead to position 1 while I clearly want it to be put in position 0. Same happens with 20/10, 30/10, 40/10, ..., 100/10 (this one in particular would cause a segmentation fault).

    So what I'm looking for is a clever way of getting this done without having to create another function to check if the price is one of those mentioned above, or having to use a loop (though I will do what you suggested if I don't find a better way). Is it somewhat more clear to you?

  7. #7
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Your read loop ought to just be something like:
    Code:
    while (fscanf(f, "%s %lf", temp_title, &temp_price) != 2) {
        insert(titles, prices, temp_title, temp_price);
    }
    It's much simpler and cleaner, and ought to avoid the problem of reading the last one twice.

    As for your price category, think about implementing a remainder check as well, perhaps using fmodf.

  8. #8
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    index = (newnode->price - 1) / 10;

  9. #9
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by nonoob View Post
    index = (newnode->price - 1) / 10;
    That wont quite work. If the item costs $10.50, it should go in index 1, but your code will put it in index 0.

  10. #10
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    Sorry, the type of newnode->price was not specified. Is it int? double?

  11. #11
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Quote Originally Posted by anduril462 View Post
    Your read loop ought to just be something like:
    Code:
    while (fscanf(f, "%s %lf", temp_title, &temp_price) != 2) {
        insert(titles, prices, temp_title, temp_price);
    }
    It's much simpler and cleaner, and ought to avoid the problem of reading the last one twice.

    As for your price category, think about implementing a remainder check as well, perhaps using fmodf.
    != ???

    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  12. #12
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Doh! Yeah, that should be == 2. Oops.

  13. #13
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by nonoob View Post
    Sorry, the type of newnode->price was not specified. Is it int? double?
    It would not make sense for it to be a double because there are exact comparisons with mutiples of 10 in there, so I vote for your solution.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  14. #14
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by iMalc View Post
    It would not make sense for it to be a double because there are exact comparisons with mutiples of 10 in there, so I vote for your solution.
    The presence or lack of exact comparisons has little to do with whether it "makes sense" for it to be a double. It's far more likely that the OP simply isn't aware of floating point inaccuracy and the issues of comparing for exact equality. What's actually important in making this decision is the actual data we have to deal with. True, we have no sample data file or declaration of temp_price or the price member of whatever newnode is, but given that the OP:
    1. Used %lf to fscanf the data out of the file and
    2. Cast the price to an int in the original calculation
    it seems reasonable to assume we actually have to deal with prices as doubles.

  15. #15
    Registered User
    Join Date
    Nov 2011
    Posts
    69
    Thank you guys! Will try that loop out!

    And yeah the prices are of type double, that's what's really making this hard. :/

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Efficent string comparisons.
    By ~Kyo~ in forum C++ Programming
    Replies: 17
    Last Post: 05-20-2011, 12:48 AM
  2. if else comparisons problem
    By stuffed in forum C Programming
    Replies: 2
    Last Post: 03-26-2011, 09:30 PM
  3. float comparisons info
    By rogster001 in forum C++ Programming
    Replies: 2
    Last Post: 01-07-2011, 09:41 AM
  4. Array Comparisons
    By B.C.Lioness in forum C++ Programming
    Replies: 8
    Last Post: 03-20-2004, 07:37 PM
  5. need HELP!!!!!!!!!C++ COMPARISONS
    By awakicee in forum C++ Programming
    Replies: 7
    Last Post: 10-01-2001, 08:08 PM