A C program to determine the most common birthday

Click For Summary

Discussion Overview

The discussion revolves around a C programming assignment that requires participants to write a program to determine the most common birthday from a file containing a list of birthdays in the format mm/dd/yyyy. The participants explore various approaches to counting occurrences of birthdays and months, while addressing issues related to the implementation of the code.

Discussion Character

  • Homework-related
  • Technical explanation
  • Debate/contested

Main Points Raised

  • One participant suggests using a 2D array to count occurrences of birthdays and months, but acknowledges potential flaws in this logic.
  • Another participant questions the necessity of certain arrays, pointing out that some arrays are initialized with values that do not contribute to the counting process.
  • Concerns are raised about the bounds checking of the input values for months and days, with suggestions to simplify the incrementing of counts based on valid ranges.
  • Participants discuss the segmentation fault occurring during runtime, attributing it to writing to non-existent array elements and the initialization of arrays that may not be needed.
  • There is a suggestion to read the filename from command-line arguments rather than standard input, along with recommendations for error handling in file operations.
  • A participant challenges the logic in the code related to finding the largest month count, questioning the value of the index variable at the end of the loop.

Areas of Agreement / Disagreement

Participants express differing opinions on the necessity and implementation of certain arrays, as well as the approach to input validation and error handling. The discussion remains unresolved regarding the best method to implement the solution and address the segmentation fault.

Contextual Notes

Participants highlight limitations in the current code, including potential issues with array bounds, unnecessary initializations, and the need for clearer logic in determining the most common birthday and month. There are also unresolved questions about the handling of command-line arguments and file reading.

toforfiltum
Messages
341
Reaction score
4

Homework Statement


Write a program that opens a file of the users choice that contains a list of birthdays. Extract from this file two things: (1) the date with the most common birthday (all of them) and (2) the month with the most people born. We will not test for a tie in either of these statistics. The file tested will always be in the format:
mm/dd/yyyy

Homework Equations


bday1.txt file is uploaded, second one is too large but of same format.

The Attempt at a Solution


Ok, at first I tried to come up separate array of counters for the month and day, thinking that the highest for both would give me the most common birthday. But that logic is flawed. I may have lesser months or days but a higher occurrence of the particular same month and day.

So, I realize I must create a 2D array counter for birthdays and months, and another array for months.
I hope my logic here is right so far.

Therefore, this is my code:
C:
#include <stdio.h>

int main ( void )
{
    int month [12] = {0}, m_d [12][31] = {0},i = 0, flag, store_m = 0, store_d = 0, count_month [12] = {0}, count_m_d [12][31] = {0}, trash;
    int largest_m, largest_bd, a, j;
   
    for ( i = 0; i < 12; i++ )
    {
        month [i] = i+1;
    }
   
    for ( i = 0; i < 31; i++ )
    {
        for ( int j = 0; j < 31; j++ )
        {
            m_d [i][j] = j+1;
        }
    }
   
    flag = scanf("%d/%d", &store_m, &store_d );
   
    while ( flag != EOF )
    {
        for ( i = 0; i < 12; i++ )
        {
            if ( store_m == month [i] )
            {
                count_month [i]++;
                for ( int j = 0; j < 31; j++ )
                {
                    if ( store_d  == m_d [i][j] )
                    {
                        count_m_d [i][j]++;
                    }
                }
            }
        }
   
       
       
    scanf("/%d", &trash );
    flag = scanf("%d/%d", &store_m, &store_d );
   
    }
   
    largest_m = count_month [0];
   
    for ( int i = 0; i < 12; i++ )
    {
        if ( largest_m < count_month [i] )
        {
            largest_m = count_month [i];
           
        }
    }
    largest_m = month [i];
   
    largest_bd = count_m_d [0][0];
   
    for ( a = 0; a < 12; a++ )
    {
        for ( j = 0; j < 31; j++ )
        {
            if ( largest_bd < count_m_d [a][j] )
            {
                largest_bd = count_m_d [a][j];
       
            }
        }
    }
    largest_bd = m_d [a][j];
    a = month [a];
   
    printf("Most common birthday: \n");
    printf("%2d/%2d\n", a, largest_bd );
   
    printf("Most common birthday month: \n");
    printf("%d", largest_m );
   
    return 0;
}

The code could compile but during runtime, it has segmentation fault. Using UNIX to run this file, I could redirect input from stdin to the file using '<'. I'm suspecting the fault lies in a = month [a]? Because that's the value that I want, not the total count, but I need the count to determine the month. Am I doing this right?
 

Attachments

Physics news on Phys.org
Code:
for ( i = 0; i < 31; i++ )
    {
        for ( int j = 0; j < 31; j++ )
        {
            m_d [i][j] = j+1;
        }
    }
You access m_d with a first index beyond 11.

I don't understand what you want to do in this step. Where is the point of m_d if you just want m_d[i][j] to be j+1?

count_m_d is all you need. count_m is optional. Everything else is unnecessary.
 
1) As mfb said, your month[j] is always equal to j, and your m_d[ i][j] is always j, so why use those arrays.
2) You have bounds checked store_m and store_d by comparing each to every valid value. But why not simply make sure that each is greated than or equal to 1 and less than or equal to 12 or 31?
3) Once you have bound check store_m and store_d, you can increment count_month[store_m-1] and count_m_d[store_m-1][store_d-1]. Or, if you don't like subtracting the 1's, dimension your arrays by 13 and 32.
 
Last edited by a moderator:
toforfiltum said:
The code could compile but during runtime, it has segmentation fault.

Well just at a glance: 1) you're writing to array elements that don't exist, and 2) you create two arrays that are presumably meant to count how many times each month and each day/month pair appear in the file, but then you have two loops at the start of your program in which you do month [i] = i+1; and m_d [i][j] = j+1; -- why? If you want to count them then surely you want the counters to start at zero, no? Then at the end just scan both arrays to find which month and which day/month pair have the highest counts.
Using UNIX to run this file, I could redirect input from stdin to the file using '<'.

You're probably meant to open and read from the file from C, which you can do with standard library functions.

This means you need to read the filename from somewhere. The normal way to do this would be to read the filename as a command-line argument, so you would run your program from the terminal like this:
Code:
$ ./my_program my_file.txt
and the program would try to open "my_file.txt" (if it exists). C provides an easy and standard way to access the command-line arguments your program was called with (if any); googling for "C command line arguments" or "argc argv" should turn up explanations.

Just make sure to check for errors if you do this (i.e., if the program was run without a command line argument or there's an error attempting to open the file) and do reasonable things in these cases (e.g., read from standard input by default and/or quit with an error message).
 
Last edited:
Unrelated to the current segfault, but as the problem will come up anyway later:
Code:
    largest_m = count_month [0];
   
    for ( int i = 0; i < 12; i++ )
    {
        if ( largest_m < count_month [i] )
        {
            largest_m = count_month [i];
           
        }
    }
    largest_m = month [i];
What do you expect this code to do?
Follow its execution step by step: What will it actually do? In particular, what will the value of "i" be when the last line is executed? And what do all the other lines do?

Same problem for the days.
 

Similar threads

  • · Replies 17 ·
Replies
17
Views
3K
  • · Replies 9 ·
Replies
9
Views
4K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 21 ·
Replies
21
Views
4K
  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 1 ·
Replies
1
Views
5K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 5 ·
Replies
5
Views
2K
  • · Replies 3 ·
Replies
3
Views
2K