Thread: How do I fix this piece of code?

  1. #1
    Registered User
    Join Date
    Dec 2013
    Posts
    18

    How do I fix this piece of code?

    The output I get for each year range is inf. I'm trying to read into the file and calculating the frequency per hundred thousand, for a name in a specific year range. How can I fix this? Output:

    Name?
    julie
    1921 - 1925: inf
    1926 - 1930: inf
    1931 - 1935: inf
    1936 - 1940: inf
    1941 - 1945: inf
    1946 - 1950: inf
    1951 - 1955: inf
    1956 - 1960: inf
    1961 - 1965: inf
    1966 - 1970: inf
    1971 - 1975: inf
    1976 - 1980: inf
    1981 - 1985: inf
    1986 - 1990: inf
    1991 - 1995: inf
    1996 - 2000: inf
    2001 - 2005: inf

    Code:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    struct NameRecord {
            char name[31];
            int year;
            int frequency;
    };
    
    
    int getRawData(FILE *fp, struct NameRecord records[], int currSize);
    
    
    int main() {
    
    
    struct  NameRecord records[150000];
    
    
    FILE    *fp = NULL;
    
    
    int     size = 0, currSize = 0, yearRangeTotal[17], nameTotal[17], year = 0;
    char    name[31];
    double  perHundredThousand[17], frequency = 0;
    
    
            fp = fopen("femalebabynames.csv", "r");
            size = getRawData(fp, records, currSize);
    
    
            printf("Name?\n");
            scanf("%s", name);
    
    
            int i, x;
    
    
                    memset(yearRangeTotal, 0, sizeof(yearRangeTotal));
                    for(i = 0; i < size; i++) {
                            x = ((records[i].year - 1) / 5 - 384);
                            yearRangeTotal[x] =+ yearRangeTotal[x] + records[i].frequency;
                    }
    
    
                    memset(nameTotal, 0, sizeof(nameTotal));
                    for(i = 0; i < size; i++) {
                            x = ((records[i].year - 1) / 5 - 384);
                            if(strncmp(name, records[i].name, 30) == 0) {
                                    nameTotal[x] =+ nameTotal[x] + records[i].frequency;
                            }
                    }
    
    
                    memset(perHundredThousand, 0, sizeof(perHundredThousand));
                    for(i = 0; i < 17; i++) {
                            perHundredThousand[i] = 100000.00 / nameTotal[i] * yearRangeTotal[i];
                    }
    
    
                    for(i = 0; i < 17; i++) {
                            printf("%.4d - %.4d: %.2f\n", (i+384)*5+1, (i+385)*5, perHundredThousand[i]);
                    }
    
    
                    printf("\n");
    
    
            return 0;
    
    
    }
    
    
    int getRawData(FILE* fp, struct NameRecord records[], int currSize) {
            while(EOF != fscanf(fp,"%d,%[^,],%d", &records[currSize].year, records[currSize].name, &records[currSize].frequency)) {
                    currSize++;
            }
            return currSize;
    
    
    }

  2. #2
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    It's not =+ but +=.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  3. #3
    Registered User
    Join Date
    Dec 2013
    Posts
    18
    I tried that but now the output is:
    1921 - 1925: inf
    1926 - 1930: -inf
    1931 - 1935: -inf
    1936 - 1940: -inf
    1941 - 1945: inf
    1946 - 1950: -inf
    1951 - 1955: -inf
    1956 - 1960: inf
    1961 - 1965: -inf
    1966 - 1970: inf
    1971 - 1975: inf
    1976 - 1980: inf
    1981 - 1985: -inf
    1986 - 1990: inf
    1991 - 1995: inf
    1996 - 2000: -inf
    2001 - 2005: -inf

  4. #4
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,907
    The smallest possible sample input file that demonstrates this problem would be immensely helpful.

    Some notes in the mean time:

    1. Don't use magic numbers. #define some constants. Why 31, 17, 384, 5, 385? Consider defining some constants in terms of others
    Code:
    #define YEAR_GROUP_SIZE 5
    #define MAX_YEARS 85
    #define NUM_YEAR_GROUPS (MAX_YEARS / YEAR_GROUP_SIZE + 1)  // +1 in case they don't divide evenly, and you need to deal with a partial year group
    2. Does records really need to hold 150k entries?

    3. Check the value of your file functions like fopen. If you can't open the file, print an error (look into the perror() function) and quit. You can't do anything else useful.

    4. =+ and += are not the same thing
    Code:
    x =+ y;  // x = +y;  x is assigned the value of y
    x += y;  // x = x + y;  x is assigned the value of x+y
    5. Read the documentation for fscanf. You should check the return value to make sure you scanned all expected values. If not, you have a corrupted line in your file and all further parsing is suspect.

    6. inf can come from a few things: divide by zero (or almost 0), random, uninitialized data, etc. Make sure you initialize everything properly.

    7. On that note, your memset() calls will set the memory to all-bits zero. That may not correspond to an actual value of 0 in a floating point variable (like your array of doubles 'perHundredThousand'). Explicitly set each element to 0.0 with a loop. Since you do this several times, writing a function would be a good idea.

    8. There is no point in passing in currSize to the getRawData function. Just make it a local, initialized to 0, and return it when done.

    That should give you something to work on for a while.

  5. #5
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    On a second look, changing to += is still wrong.
    You have
    Code:
            yearRangeTotal[x] += yearRangeTotal[x] + records[i].frequency;
    You want
    Code:
            yearRangeTotal[x] += records[i].frequency;
    Ditto for nameTotal.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  6. #6
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,907
    Quote Originally Posted by oogabooga View Post
    On a second look, changing to += is still wrong.
    You have
    Code:
            yearRangeTotal[x] += yearRangeTotal[x] + records[i].frequency;
    You want
    Code:
            yearRangeTotal[x] += records[i].frequency;
    Ditto for nameTotal.
    Haha! On third look, if that was the case, then the original should have worked since it was adding the current value of yearRangeTotal with records.frequency and storing it back into yearRangeTotal.

  7. #7
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,742
    Did you really mean to use strncmp()?

    Edit: I guess you might have if you're reading a csv file without tokenising the columns, but then shouldn't the number of characters to compare be the length of "julie" and not 30? I imagine it's probably terminating at the ',' with a non-zero return (strings not equal); so no matches would be found. Also, it might be better to either convert everything to uppercase or compare using a case-insensitive comparison.
    Last edited by Hodor; 12-03-2013 at 10:29 PM.

  8. #8
    Registered User
    Join Date
    Dec 2013
    Posts
    18
    Here's a sample of what's in the data:
    Beginning
    2005 aaliya 7
    2006 aaliya 5
    2007 aaliya 5
    2008 aaliya 7
    2009 aaliya 5

    End
    2010 ZUNAIRA 5
    2008 ZUNAIRAH 6
    2010 ZUNAIRAH 7

    Give me a moment while I try to make sense of everything... sorry I'm still fairly new at programming. I have a sense of what I'm trying to do but I don't think I'm using the right functions and format

  9. #9
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,742
    Oh, it's tab or space delimited? Either way I think that strncmp() is a problem... (edit, no, I am just confused. Ignore this comment)
    Last edited by Hodor; 12-03-2013 at 10:32 PM.

  10. #10
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Quote Originally Posted by Hodor View Post
    Did you really mean to use strncmp()?

    Edit: I guess you might have if you're reading a csv file without tokenising the columns, but then shouldn't the number of characters to compare be the length of "julie" and not 30? I imagine it's probably terminating at the ',' with a non-zero return (strings not equal); so no matches would be found. Also, it might be better to either convert everything to uppercase or compare using a case-insensitive comparison.
    I see nothing wrong with the way he's using strncmp.
    7.21.4.4 The strncmp function

    Synopsis

    1

    #include <string.h>
    int strncmp(const char *s1, const char *s2, size_t n);
    Description

    2 The strncmp function compares not more than n characters (characters that follow a null character are not compared) from the array pointed to by s1 to the array pointed to by s2.

    Returns

    3 The strncmp function returns an integer greater than, equal to, or less than zero, accordingly as the possibly null-terminated array pointed to by s1 is greater than, equal to, or less than the possibly null-terminated array pointed to by s2.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  11. #11
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,742
    Quote Originally Posted by oogabooga View Post
    I see nothing wrong with the way he's using strncmp.
    Yeah, I must have been editing my comment when you were posting this

  12. #12
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Wait a second! If the data is not comma-delimited (as implied by the file ending .csv) then you shouldn't be scanning it with this format: "%d,%[^,],%d"
    Try this instead: "%d %s %d"
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  13. #13
    Registered User
    Join Date
    Dec 2013
    Posts
    18
    The file does read with my code because I tested it with:

    Code:
    int getRawData(FILE* fp, struct NameRecord records[], int currSize) {
            while(EOF != fscanf(fp,"%d, %[^,], %d", &records[currSize].year, records[currSize].name, &records[currSize].frequency)) {
                   printf("%d  ---  %d --- %s --- %d\n", currSize, records[currSize].year, records[currSize].name, records[currSize].frequency);
                   currSize++;
            }
            return currSize;
    
    
    }

  14. #14
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    So the example records you posted are incorrect since they have no commas in them, right?

    Also, post your current code.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  15. #15
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,907
    Quote Originally Posted by deepee View Post
    The file does read with my code because I tested it with:

    Code:
    int getRawData(FILE* fp, struct NameRecord records[], int currSize) {
            while(EOF != fscanf(fp,"%d, %[^,], %d", &records[currSize].year, records[currSize].name, &records[currSize].frequency)) {
                   printf("%d  ---  %d --- %s --- %d\n", currSize, records[currSize].year, records[currSize].name, records[currSize].frequency);
                   currSize++;
            }
            return currSize;
    
    
    }
    If that's the case, then the input file you posted does not match the input file on your system. fscanf will try to match those commas, and fail if it can't. Also, it's worth pointing out that the code above does not match the code in your first post, since you have spaces after the commas in your format string. We need to know exactly what you're working with, if we are to help you.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Trying to understand a piece of code.
    By Brian29 in forum C++ Programming
    Replies: 10
    Last Post: 12-06-2012, 03:23 AM
  2. Can someone help me with this small piece of code
    By Avanish Giri in forum C Programming
    Replies: 6
    Last Post: 04-09-2012, 07:11 PM
  3. what's wrong with this piece of code?
    By shaxquan in forum C Programming
    Replies: 3
    Last Post: 06-14-2010, 04:46 AM
  4. Help with a piece of code
    By Victor4015 in forum C++ Programming
    Replies: 1
    Last Post: 11-16-2005, 05:38 PM
  5. Help with a little piece of code
    By cdonlan in forum C Programming
    Replies: 5
    Last Post: 11-15-2004, 12:38 PM