What happened to OC? - CLOSED Carnage?!
Sign in to follow this  
Followers 0
Nerdenator

*EMERGENCY* need help on C code project

Got a major, major problem in a class I need at least a B in.

I had a lab assignment due today at 5:00 PM (it's now 8:00 PM CDT) in my C programming class.

It compiles, but segfaults.

Here's the code, and it's a doozie:

/*
Aaron McRuer
Lab F
Labcode:
Lab 10
4-17-12
*/
#include<stdio.h>
#include<stdlib.h>
/*maximum number of emperors listed in a single file*/
#define MAX 15
/*maximum length of the emperor's name*/
#define MAX_LENGTH 30
/*define structure to store emperors information*/
typedef struct data{
char name[MAX_LENGTH];
int birth;
int death;
int reign;
} DATA;
/*create two global file pointers for input and output files*/
FILE *in, *out;
/*create global array to have access from any function*/
DATA emperors[MAX];

/*prototypes*/
int openFiles(char* input, char* output);
int readContent();
int emperor_to_live_longest (int size);
int youngest_emperor_to_die (int size);
int longest_lifetime_reign (int size);
int emperor_to_rule_longest(int size);
void writeFile(int oldest, int youngest, int longest, int successful, int size);
void closeFiles();
int main(int argc, char* argv[])
{
char* input;
char* output;
input = argv[1];
output = argv[2];
if (argc !=3)
{
 printf("Not enough args. Usage: a.out <input> <output>\n");
 return -1;
}
/*create emperors with default info*/
DATA emperors = {"", 0, 0, 0};
openFiles( input,  output);
int size = readContent();
int oldest = emperor_to_live_longest(size);
int youngest = youngest_emperor_to_die(size);
int longest = longest_lifetime_reign(size);
int successful= emperor_to_rule_longest(size);
writeFile( oldest,  youngest,  longest,  successful,  size);
closeFiles();
return 0;
}
/* this function should take argv[1] and argv[2] as input and output file names.
Return -1 if files couldn't be opened. Open input in read mode and output in write mode*/
int openFiles(char* input, char* output)
{

/*fopen opens the file; exits if file cannot be opened*/
if((((in = fopen(input, "r")) == NULL) || ((out = fopen(output, "w")) == NULL)))
{
 printf("File could not be opened.\n");
 return -1;
} /*end if*/

else
{
 return 0;
}
}
/* this function reads whole file and returns the number of emperors listed in the file. This number is stored in the first line of the .txt file.*/
int readContent()
{
int i = 0;
int number_of_emperors;
fscanf(in, "%d", &number_of_emperors);
for(i = 0; i < number_of_emperors; i++)
{
 fscanf(in, "%s", emperors[i].name);
 fscanf(in, "%d", &emperors[i].birth);
 fscanf(in, "%d", &emperors[i].death);
 fscanf(in, "%d", &emperors[i].reign);
}

return number_of_emperors;
}
/* this function scans through the list of emperors, and finds the oldest emperor to die. Return the index of the array (NOT the age) back to
main function.*/
int emperor_to_live_longest(int size)
{
int n; /*counter*/
int max;
int index;
int age = (emperors[n].death - emperors[n].birth);
max = age;

for ( n = 0 ; n < size ; n++ )
{
 int age = (emperors[n].death - emperors[n].birth);

 if ( max < age )	
 {
  max = age;
  index = n;
 }
}

return index;
}
/* this function scans the array and finds the youngest emperor to die. Similarly to the previous function, return the index, do not return
the age of the emperor.*/
int youngest_emperor_to_die(int size)
{
int n;
int min_age;
int index;
int age = (emperors[n].death - emperors[n].birth);
min_age = age;

for (n = 0; n < size; n++)
{
 int age = (emperors[n].death - emperors[n].birth);
 if (min_age > age)
 {
  min_age = age;
  index = n;
 }
}

return index;
}
/* scans the list, find the emperor that spent most of his lifetime in reign (hint: age- years of reign is the smallest). Return the index in the
array. With the index you will be able to extract name and age as well.*/
int longest_lifetime_reign(int size)
{
int m;
int max;
int index;
int age = (emperors[n].death - emperors[n].birth);
max = age;

for (n = 0; n < size; n++)
{
 int age = (emperors[n].death - emperors[n].birth);
 int longest = (age - emperors[n].reign);
 if (max > longest)
 {
  longest = max;
  index = n;
 }
}

return index;
}
/*Emperor who spent most of years in reign. As usual, only return index to main function.*/
int emperor_to_rule_longest (int size)
{
int n;
int max;
int mage;
float age = (emperors[n].death - emperors[n].birth);
float most_of_life_in_rule = (age / emperors[n].reign);

for (n = 0; n > size; n++)
{
 age = (emperors[n].death - emperors[n].birth);
 most_of_life_in_rule = (age / emperors[n].reign);

 if (max > most_of_life_in_rule)
 {
  most_of_life_in_rule = max;
  mage = n;
 }
}

return mage;
}
/*Once you calculate all the numbers, print the list of emperors into the output file, and lastly the summary required by the history department.
It is worth noting the first four arguments, passed to the funciton are the INDEXES, last argument is the size of the array. Example output will give
you better understanding on how to format the output file.*/
void writeFile(int oldest, int youngest, int longest, int successful, int size)
{
int i;

for(i = 0; i < size; i++)
{
 fprintf(out,"%s Birth: %d, Death: %d, Reign: %d \n", emperors[i].name, emperors[i].birth, emperors[i].death, emperors[i].reign);
}

fprintf(out, "---------------\n");
fprintf(out, "Oldest emperor to die: %s, Age: %d\n", emperors[oldest].name, (emperors[oldest].death-emperors[oldest].birth));
fprintf(out, "Youngest emperor to die: %s, Age: %d\n", emperors[youngest].name, (emperors[youngest].death-emperors[youngest].birth));
fprintf(out, "Emperor to rule longest: %s, %d years.\n",emperors[longest].name, emperors[longest].reign);
fprintf(out, "Emperor to spend most of lifetime in reign: %s, %d years in reign. Died at age of %d.", emperors[successful].name, emperors[successful].reign, (emperors[successful].death- emperors[successful].birth));

}
void closeFiles()
{
fclose(in);
fclose(out);
}

Basically, you have a list of Roman emperors and some details about their lives. You have a Linux/UNIX command line console, and enter "a.out emperors.txt output.txt" - the first one would be the input file, the second argument is the output file name.

Here's the emperors.txt file:

11
Caligula
12
41
3
Vespasian
9
79
9
Nero
37
68
13
Titus
39
81
2
Trajan
53
117
19
Marcus_Aurelius
121
180
19
Commodus
161
192
12
Septimius_Severus
145
211
17
Macrinus
165
218
1
Severus_Alexander
208
235
13
Diocletianus
244
311
20

You will need to place that file in to the exact same directory you have the compiled file (a.out) running from.

Now, here's where it segfaults, according to GDB:

/* scans the list, find the emperor that spent most of his lifetime in reign (hint: age- years of reign is the smallest). Return the index in the
array. With the index you will be able to extract name and age as well.*/

int longest_lifetime_reign(int size)
{
int n;
int max;
int index;
int age = (emperors[n].death - emperors[n].birth);
max = age;

for (n = 0; n < size; n++)
{
 int age = (emperors[n].death - emperors[n].birth);
 int longest = (age - emperors[n].reign);
 if (max > longest)
 {
  longest = max;
  index = n;
 }
}

return index;
}

I'd recommend using Linux and the GNU C tool chain. GCC is the compiler, and GDB is the debugger. Hopefully one of you guys know how this works and is better with GDB than I am and can find a better way to find out what's wrong. I really need to get it in in the next four hours.

http://pastebin.com/7b3JDjPB - Program

http://pastebin.com/re6WmtBL- emperors.txt

I'll be monitoring this thing continuously. Thanks in advance for your help. Means the difference between a B and a C in the class for the semester.

Share this post


Link to post
Share on other sites

Tiddy-bits:

Sign in to follow this  
Followers 0
  • Recently Browsing   0 members

    No registered users viewing this page.