I\'ve written this program to take a text file containing names and ages. Under
ID: 3533062 • Letter: I
Question
I've written this program to take a text file containing names and ages. Under linux is compiles and run properly. Under Microsoft Visual Studio 2010 I get "Unhandled exception at 0x1020d440 (msvcr100d.dll) in p5.exe: 0xC0000005: Access violation reading location 0xcccccccc."
Can someone tell what's going on? It seems to blow up in the sort_list function on the second while loop.
#include <stdio.h> /* Include directive for input/output functions */
#include <stdlib.h> /* Include directive for system exit functions */
#include <string.h> /* Include directive for working with strings */
#include <errno.h> /* Include directive for error condition macros */
#include <ctype.h> /* Include directive for c type functions */
#define WORD_LEN 81 /* word length constant */
#define FILE_NAME_LEN 129 /* file name length constant */
#define MAX_PERSONS 50 /* max number of array elements */
/* Struct: Document
Used for representing a file
*/
struct Document
{
FILE *file; /* file pointer for the CLI file */
char file_name[FILE_NAME_LEN]; /* file name from CLI */
char names[MAX_PERSONS+1][WORD_LEN]; /* for storing names from file */
int ages[MAX_PERSONS+1]; /* for storing ages from file */
char *sorted_names[MAX_PERSONS+1]; /* for storing sorted names from file */
int *sorted_ages[MAX_PERSONS+1]; /* for storing sorted ages from file */
int list_size; /* for the size of the list in the file */
};
/* Prototype: initialize */
void initialize(int argument_count);
/* Prototype: file_check */
void file_check(struct Document document);
/* Prototype: remove_spaces */
void remove_spaces(char *r);
/* Prototype: isempty */
int isempty(char *str);
/* Prototype: strstrip */
char *strstrip(char *s);
/* Prototype: count_words */
void sort_list(char *names[], int *ages[], int min, int max);
/* Prototype: print_header */
void print_header(char title[]);
/* Prototype: report */
void report(struct Document document);
/* Name: main */
int main(int argc, char *argv[])
{
struct Document document; /* declares a Document struct variable */
int line_count; /* int for counting the number of non blank lines */
int char_count; /* int for counting chars in a string */
int num_count; /* int for counting numbers found in a string */
int i; /* int for counting array elements */
char str[WORD_LEN]; /* char string for storing a line from the file */
char tmp_str[WORD_LEN]; /* char string for manipulating line from file for validations */
char num_str[WORD_LEN]; /* char string for storing chars that are found to be digits in a string */
/* initialize and check argument count */
initialize(argc);
/* string copy the document's file name from CLI argument */
strcpy(document.file_name, argv[1]);
/* assign the file from command line */
document.file = fopen(argv[1], "r");
/* check the file */
file_check(document);
/* initialize line count */
line_count = 0;
/* scan each line in the file */
while(fgets(str, WORD_LEN, document.file) != 0) {
/* remove new line chars */
if(str[strlen(str) - 1] == ' ')
str[strlen(str) - 1] = '';
/* make a temporary string that can be manipulated for validation checks */
strcpy(tmp_str, str);
/* Only take valid strings, no empty strings allowed */
if(!isempty(tmp_str)) {
/* check if MAX_PERSONS has been reached */
if(line_count > MAX_PERSONS) {
printf("A maxium of 50 persons has been reached. ");
exit(EXIT_FAILURE);
}
/* initialize empty place holders */
char_count = 0;
num_count = 0;
/* loop through each char */
while(char_count < strlen(str)) {
/* take anything that isn't a digit as a name */
if(!isdigit(str[char_count]))
document.names[line_count][char_count] = str[char_count];
/* take anything that isn't a digit as a name */
if(isdigit(str[char_count]))
num_str[num_count++] = str[char_count];
/* increment char_count */
++char_count;
}
/* store converted string to long integer from num_str on the document's ages array */
document.ages[line_count] = strtol(num_str, NULL, 10);
/* strip extra white space from name */
strstrip(document.names[line_count]);
/* increment line count */
++line_count;
}
}
/* Store new array for sorting */
for(i=0; i < line_count; i++) {
document.sorted_names[i] = document.names[i];
document.sorted_ages[i] = &document.ages[i];
}
document.list_size = line_count;
/* close the file */
fclose(document.file);
/* show report */
report(document);
/* return control to OS */
return(0);
}
/*
Name: sort_list
Sorts original list of names and ages using the Quicksort algorithm.
*/
void sort_list(char *names[], int *ages[], int min, int max)
{
int i; /* for storing original min */
int j; /* for storing original max */
char *x; /* for storing a pivot element */
char temp_str[WORD_LEN]; /* temporary string for element swapping on a name */
int *temp_int; /* temporary int for element swaping on an age */
i = min;
j = max;
/* pick a pivot element */
x = names[(min+max)/2];
do {
/* increment i until we find and element that belongs to the right of the pivot */
while((strcmp(names[i],x) < 0) && (i < max))
i++;
/* increment j until we find and element that belongs to the left of the pivot */
while((strcmp(names[j],x) > 0) && (j > min))
j--;
/* Reorder the list so that all elements with values less than the pivot come before
the pivot, while all elements with values greater than the pivot come after it
(equal values can go either way).
*/
if(i <= j) {
strcpy(temp_str, names[i]);
strcpy(names[i], names[j]);
strcpy(names[j], temp_str);
temp_int = ages[i];
ages[i] = ages[j];
ages[j] = temp_int;
i++;
j--;
}
} while(i <= j);
/* Recursively apply the above algorithm to the sub-list of elements with smaller
values and separately the sub-list of elements with greater values.
*/
if(min < j)
sort_list(names, ages, min, j);
if(i < max)
sort_list(names, ages, i, max);
}
/*
Name: initialize
Checks to make sure there are enough command line arguments
*/
void initialize(int argument_count)
{
if(argument_count < 2) {
/* Print program and author information */
printf("Provide a datafile ");
exit(EXIT_SUCCESS);
}
}
/* Name: file_check
Checks the existance of a file passed in from CLI
*/
void file_check(struct Document document)
{
/* Check file */
if(document.file == NULL) {
/* tell the user that there were problems opening the file */
printf("Error opening file %s: %s ", document.file_name, strerror(errno));
exit(EXIT_FAILURE);
}
}
/*
Name: remove_spaces
Removes spaces from a string
*/
void remove_spaces(char *r) {
char *w = r;
do { *w = *r++; w += *w && !isspace(*w); } while (*w);
}
/*
Name: isempty
Checks if a string is empty by removing spaces and checking
for a blank string or null pointers
*/
int isempty(char *str)
{
if(str == NULL) return 1;
remove_spaces(str);
return !strcmp(str, "");
}
/*
Name: strstrip
Removes trailing whitespace characters
*/
char *strstrip(char *s)
{
size_t size; /* for representing string size in bytes */
char *end; /* char pointer for accessing the char before null char */
/* get the string size */
size = strlen(s);
/* if the string has no size, then return it */
if (!size)
return s;
/* get the next to last char */
end = s + size - 1;
/* remove all trailing spaces */
while (end >= s && isspace(*end))
end--;
*(end + 1) = '';
/* increment the char */
while (*s && isspace(*s))
s++;
return s;
}
/*
Name: print_header
Prints a horizontal line header with a title
to standared out
*/
void print_header(char title[])
{
printf(" %s ", title);
printf(" ---------------------------------------- ");
}
/*
Name: report
Prints a formated report to standard out
containing the original list and the
alphabetized list
*/
void report(struct Document document)
{
int n;
/* print the original list */
print_header("Original list");
for(n=0; n < document.list_size; n++)
printf(" %-25s %d ", document.names[n], document.ages[n]);
/* sort the list */
sort_list(document.sorted_names, document.sorted_ages, 0, document.list_size);
/* print the alphabetized list */
print_header("Alphabetized list");
for(n=0; n < document.list_size; n++)
printf(" %-25s %d ", document.sorted_names[n], *document.sorted_ages[n]);
}
Explanation / Answer
public event UnhandledExceptionEventHandler UnhandledException This event provides notification of uncaught exceptions. It allows the application to log information about the exception before the system default handler reports the exception to the user and terminates the application. If sufficient information about the state of the application is available, other actions may be undertaken
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.