*More fully fledged applications can be found on the Products page. The Bash page is dedicated to fully commented oneliners, and a MySQL quick reference is available here.
/*
* Will Bergen - 2019
* Pendulum swing period calculator
* Answer to the following (likely textbook) question:
*
* Input: Prompt user to input the data from the screen in a manner ..
* - Assume list of pairs (x, N), (N, x) where N is given and x is to be found
* - Pairs are (Length, Period)
* Output: Print a table of pendulum lengths and swing times like following:
*
* Length (m) Period (sec)
* 0.5 -
* 1.0 -
* - 10.0
* - 20.0
* 0.32 -
*
*
* NB. pi is available from math.h as M_PI
*
* Forumla:
* T (period) = 2 * pi * sqrt(L (length) / gravity)
*
* Solved for L:
* L = ( (T / (2 * pi) )^2 ) / GRAVITY
*
*
* Quick test via heredoc:
./a.out << EOF
0.5,X
1.0,X
X,10.0
X,20.0
0.32,X
EOF
*
* Compile against math:
* gcc swing_table.c -lm -o swing_table
* */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define BUF_SIZE 256
#define NUM_PAIRS 5
#define GRAVITY 9.81
double solveForTime(double length)
{
// printf("Solving for Time\n");
return 2 * M_PI * sqrt(length / GRAVITY);
}
double solveForLength(double time)
{
// printf("Solving for Period\n");
return pow((time / 2 * M_PI), 2) / GRAVITY;
}
int main(void) {
// Read pairs from stdin
char buf[BUF_SIZE];
double lens[NUM_PAIRS];
double periods[NUM_PAIRS];
char *ptr;
// Print instructions:
printf("Please enter %i pairs of the form:\n", NUM_PAIRS);
printf("<Length of pendulum>,<Swing Period>\n");
printf("Make one an X to solve for it\n");
printf("eg. 0.5,X or X,10 - No Spaces!\n\n");
// Get Pairs:
int i = 0;
for (i; i < NUM_PAIRS; i++)
{
printf("Enter pair %i: ", i+1);
fgets(buf, BUF_SIZE, stdin);
printf("Pair %i: %s", i+1, buf);
double len = strtod(buf,&ptr);
/* Here, ptr points to the next char in buf that's NOT number
* so if input is '10,50' then ptr -> ','
* adding 1 to ptr trivially gets around ',', but is very breakable
* lets instead consume until we've explictly eaten a ','
* -- This is escessive without other bounds checking
* -- If we assume no spaces and a single comma, we just increment once...
* */
char *next_char = ptr;
// Check for ptr already pointing at ',':
if (strncmp(next_char, ",", 1) == 0)
{
next_char = next_char + sizeof(char);
} else {
// If it doesn't already point at a comma, consume to find:
while (strncmp(next_char, ",", 1) != 0)
{
next_char = next_char + sizeof(char);
}
// Comma found, consume:
next_char = next_char + sizeof(char);
}
// Convert the string again from updated pointer:
double period = strtod(next_char,&ptr);
// One of the vars will be 0. Solve and append to result arrays:
// Time is unknown:
if (period == 0.0)
{
periods[i] = solveForTime(len);
lens[i] = len;
}
// Length is unknown:
if (len == 0.0)
{
lens[i] = solveForLength(period);
periods[i] = period;
}
// Reset buf:
memset(buf, 0, sizeof(buf));
}
// Display output table with red headings:
printf("\n\033[1;31mLength (m)\tPeriod (sec)\033[0m\n");
i = 0;
for (i; i < NUM_PAIRS; ++i)
{
printf("%f\t%f\n", lens[i], periods[i]);
}
return 0;
}