0% found this document useful (0 votes)
3 views53 pages

code

The document contains a series of C programming exercises focused on string manipulation, including tasks such as printing words on separate lines, sorting names, reversing strings, replacing words, converting strings to integers, checking for palindromes, and counting character frequencies. Each exercise is accompanied by a code implementation and demonstrates various programming concepts such as functions, loops, and file handling. The final exercises involve reading from and writing to CSV files, as well as character frequency analysis using pointers.

Uploaded by

huyhung6212
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
0% found this document useful (0 votes)
3 views53 pages

code

The document contains a series of C programming exercises focused on string manipulation, including tasks such as printing words on separate lines, sorting names, reversing strings, replacing words, converting strings to integers, checking for palindromes, and counting character frequencies. Each exercise is accompanied by a code implementation and demonstrates various programming concepts such as functions, loops, and file handling. The final exercises involve reading from and writing to CSV files, as well as character frequency analysis using pointers.

Uploaded by

huyhung6212
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
Download as pdf or txt
You are on page 1/ 53

HOMEWORK

1. Write a program that allow users to enter a statement, then print that statement on the
screen in such a way that each line contains only one word.

#include <stdio.h>
#include <string.h>

int main() {
char string[100];

printf ("Input string: ");


gets (string);

printf ("One-line-for-each-word statement:\n");


for (int i=0;i<strlen(string);i++) {
if (string[i]==' ')
{
while (string [i+1]==' ') i++;
printf ("\n");
}
else printf ("%c", string[i]);
}

return 0;
}

2. Write a function to sort the names in a given list in ascending order and demonstrate the
usage

#include <stdio.h>
#include <string.h>

void sort_name (char name[][50], int n) {


char temp[50];

for (int i=0; i<n-1;i++) {


for (int j=i+1;j<n;j++) {
if (strcmp (name[i], name[j])>0) {
strcpy (temp,name[i]);
strcpy (name[i],name[j]);
strcpy (name[j],temp);
}
}
}
}
int main() {
int n;
printf ("Input number of words: ");
scanf ("%i",&n);

char name[n][50];
for (int a=0;a<n;a++) {
scanf ("%s",&name[a]);
}

sort_name (name,n);

for (int i = 0; i < n; i++) {


printf("%s ", name[i]);
}

printf("\n");
return 0;
}

3. Write a function to obtain a string entered via keyboard in the reverse order as per word, e.g.
“How Are You” change to “You Are How”. Write a program to demonstrate the usage.

#include <stdio.h>
#include <string.h>

int rev(char string[]) {


char temp[50];
int n=strlen(string);
int a=0;

for (int i=n-1;i>=0;i--) {


if (string[i]==' ') {
temp[a]='\0';
printf ("%s ",strrev(temp));
temp[0]='\0';
a=0;
}
else {
temp[a]=string[i];
a++;
}
}
printf ("%s",strrev(temp));
}

int main() {
char string[1000];

printf ("Enter string: ");


gets(string);

rev(string);
}

4. Write a program to enter a sentence(or paragraph) and a word (or a string), then replace
the word (string) within the sentence (paragraph) with the equal number of "*" at all
occurring. Design and use appropriate functions to perform the task.

#include <stdio.h>
#include <string.h>

void replace(char para[],char string[]) {


char FinalPara[1000];
char* p=FinalPara;

for (int i=0;i<strlen(para);i++) {


if (para[i]=='*') {
strcat(FinalPara,string);
p+=strlen(string);
}
else {
*p++=para[i];
}
}
printf ("%s", FinalPara);
}

int main() {
char para[100],string[100];

printf ("Enter the sentence:");


gets(para);

printf ("\nEnter the word:");


gets(string);

replace (para,string);
}

5. Write a function that converts a string like “124” to an integer 124. Write a program to
demonstrate the usage.

#include <stdio.h>
#include <string.h>
#include <math.h>

void convert(char str[],int num) {


int len=strlen(str);

for (int i=0;i<strlen(str);i++) {


num+=(str[i]-48)*pow(10,len-1);
len--;
}

printf ("\n%i",num);
}

int main() {
char str[1000];
int flag=0,num=0;

printf ("Input number string: ");


scanf("%s",str);

do {
for (int i=0;i<strlen(str);i++) {
if (str[i]<48 || str[i]>57) flag=1;
}
if (flag==1) {
flag=0;
printf ("\nPlease re-input with numbers only: ");
scanf("%s",str);
}
else break;
}
while (true);

convert (str,num);
}

6. Write a function to check whether string inputted by user is palindrome or not. Demonstrate
the usage.
#include <stdio.h>
#include <string.h>

void check_palindrome(char str1[]) {


int len = strlen(str1), flag=1;

for (int i=0;i<len;i++) {


if ( (int) str1[i] != (int) str1[len-1-i] ) {
flag=0;
break;
}
}

if (flag==0) printf ("The string is not palindrome");


if (flag==1) printf ("The string is palindrome");
}

int main () {
char str1[1000];

printf ("Please input string: ");


gets (str1);

check_palindrome (str1);
}

7. Write a function to remove all the extra blanks in a string. Demonstrate the usage.

#include <stdio.h>
#include <string.h>

void remove_blank(char str[]) {


int len = strlen(str);
char new_str[len];
int i=0,j=0;

if (str[i]!=' ') {
new_str[j]=str[i];
j++;
}

for (i=1; i<len;i++) {


if ((str[i]==' ') && (str[i-1]==' ') ) {
continue;
}
else {
new_str[j]=str[i];
j++;
}
}

new_str[j]='\0';

printf ("%s", new_str);


}

int main() {
char str[1000];

printf("Please input string: ");


gets (str);

printf("\nAfter removing extra blanks: ");


remove_blank (str);

return 0;
}

8. Write a program to enter any string and print the frequency of each character within the
string. The character with multiple frequencies should be displayed only once in the output,
with the frequency value. Design and use appropriate functions to perform the task.

#include <stdio.h>
#include <string.h>

void frequency(char str[]) {


char freq[256]={0};

int len=strlen(str);

for (int i=0;i<len;i++) {


freq[(int)str[i]]++;
}

for (int i=0;i<256;i++) {


if (freq[i]!=0) {
printf ("The frequency of character %c is %i\n",i,freq[i]);
}
}
}
int main() {
char str[1000];

printf ("Please input string:");


gets (str);

frequency(str);
}

9. Write a program to take a list of students in a programming class. The list should contain
the student id, student name and the final exam score. Write the student list to a csv file call
“ee3490E.csv” such that each line consists of student id, student name and the score. Each field
of information should be separated by a comma “,”; e.g.: 20200001, Adam Smith, 8.2. Design
and use appropriate functions and data types to perform the task.

#include <stdio.h>
#include <stdlib.h>

#define MAX_STUDENTS 100

struct student {
int id;
char name[50];
float score;
};

void write_student_list_to_csv(struct student students[], int num_students) {


FILE *fp;

fp = fopen("ee3490E.csv", "w");

fprintf(fp, "Student ID,Student Name,Final Exam Score\n");


for (int i = 0; i < num_students; i++) {
fprintf(fp, "%d,%s,%.1f\n", students[i].id, students[i].name,
students[i].score);
}

fclose(fp);
}

int main() {
struct student students[MAX_STUDENTS];
int num_students;
printf("Enter the number of students in the class (up to %d): ",
MAX_STUDENTS);
scanf("%d", &num_students);

for (int i = 0; i < num_students; i++) {


printf("Enter student %d's ID: ", i + 1);
scanf("%d", &students[i].id);

printf("Enter student %d's name: ", i + 1);


scanf(" %[^\n]", students[i].name);

printf("Enter student %d's final exam score: ", i + 1);


scanf("%f", &students[i].score);
}

write_student_list_to_csv(students, num_students);

printf("Student list has been written to ee3490E.csv.\n");

return 0;
}

10. Write a program to read a file which has the same format as described in problem 9.
Calculate the number of students who get A, B, C, D, and F. Design and use appropriate
functions and data types to perform the task.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_STUDENTS 100

typedef struct {
int id;
char name[100];
float score;
} Student;

void calculate_grades(Student students[], int num_students, int *num_a, int


*num_b, int *num_c, int *num_d, int *num_f) {
for (int i = 0; i < num_students; i++) {
if (students[i].score >= 8.5) {
(*num_a)++;
} else if (students[i].score >= 7.0) {
(*num_b)++;
} else if (students[i].score >= 5.5) {
(*num_c)++;
} else if (students[i].score >= 4) {
(*num_d)++;
} else {
(*num_f)++;
}
}
}

int main() {
FILE *fp;
char filename[100];
Student students[MAX_STUDENTS];
int num_students = 0;
int num_a = 0, num_b = 0, num_c = 0, num_d = 0, num_f = 0;

// get the filename from the user


printf("Enter the name of the input file: ");
scanf("%s", filename);

// open the file for reading


fp = fopen(filename, "r");
if (fp == NULL) {
printf("Error: could not open file.\n");
exit(1);
}

// read in the student data from the file


while (fscanf(fp, "%d,%[^,],%f", &students[num_students].id,
students[num_students].name, &students[num_students].score) == 3) {
num_students++;
}

// calculate the grades


calculate_grades(students, num_students, &num_a, &num_b, &num_c, &num_d,
&num_f);

// output the results


printf("Number of A's: %d\n", num_a);
printf("Number of B's: %d\n", num_b);
printf("Number of C's: %d\n", num_c);
printf("Number of D's: %d\n", num_d);
printf("Number of F's: %d\n", num_f);
// close the file
fclose(fp);

return 0;
}

11. Write a program in C to count the number of vowels and consonants in a string using a
pointer.

#include <stdio.h>
#include <ctype.h>
#include <string.h>

int countVowel (char *strPtr,int len);


int countConsonant (char *strPtr,int len);

int main() {
char str[1000];

int numVowel=0,numConso=0;

printf("Please input string: ");


gets (str);

char *strPtr=str;

while (*strPtr== (int) '\0') {


printf("Please re-input string: ");
gets(str);
}

int len=strlen(str);

numVowel=countVowel (strPtr,len);
numConso=countConsonant (strPtr,len);

printf ("\nNumber of vowels: %i", numVowel);


printf ("\nNumber of consonants: %i", numConso);

return 0;
}

int countVowel (char *strPtr,int len) {


int count=0;
for (int i=0;i<len;i++) {
if (
tolower(*(strPtr + i)) == (int) 'a' ||
tolower(*(strPtr + i)) == (int) 'e' ||
tolower(*(strPtr + i)) == (int) 'i' ||
tolower(*(strPtr + i)) == (int) 'o' ||
tolower(*(strPtr + i)) == (int) 'u' ||
tolower(*(strPtr + i)) == (int) 'y') ++count;
}

return count;
}

int countConsonant(char *strPtr,int len) {


int count = 0;

for (int i = 0; i<len; i++) {


if (isalpha(*(strPtr+i)) &&
!(tolower(*(strPtr + i)) == (int) 'a' ||
tolower(*(strPtr + i)) == (int) 'e' ||
tolower(*(strPtr + i)) == (int) 'i' ||
tolower(*(strPtr + i)) == (int) 'o' ||
tolower(*(strPtr + i)) == (int) 'u' ||
tolower(*(strPtr + i)) == (int) 'y')) {
count++;
}
}

return count;
}

12. Write a program in C to find the frequency of all characters and/or a given character in a
sentence entered by users. Do not use standard libraries related to string. Use pointers where
possible.

#include <stdio.h>
#include <stdlib.h>

int * charFreq (char *strPtr);

int main() {
char str[1000];

printf ("Please input string: ");


gets (str);
while (str[0]=='\0') {
printf ("String null, please re-input string: ");
gets (str);
}

char *strPtr=str;
int *outputPtr=NULL;

outputPtr=charFreq(strPtr);

int j=0;

for (j=0;j<128;j++) {
if (*(outputPtr+j) != 0) printf ("\nFrequency of character %c: %i",
(char) j, *(outputPtr+j));
}

free(outputPtr);

return 0;
}

int *charFreq (char *strPtr) {


int *chr = (int *) malloc (128*sizeof(int));
int j=0;

for (j = 0; j < 128; j++) {


*(chr + j) = 0;
}

j=0;

while (*(strPtr+j)!='\0') {
++*(chr + (int) *(strPtr+j));
j++;
}

return chr;
}

13. Write a program in C which allows users to provide a string then extract all the characters
in that string and print out them in alphabetic order. The function(s) designed should use a
pointer(s).
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

int * charFreq (char *strPtr);

int main() {
char str[1000];

printf ("Please input string: ");


gets (str);

while (str[0]=='\0') {
printf ("String null, please re-input string: ");
gets (str);
}

int i=0;
while (str[i]!='\0') {
str[i]=tolower(str[i]);
i++;
}

char *strPtr=str;
int *outputPtr=NULL;

outputPtr=charFreq(strPtr);

int j=0;

printf ("\nAll characters in string:");


for (j=0;j<128;j++) {
if (*(outputPtr+j) != 0) printf (" %c", (char) j);
}

free(outputPtr);

return 0;
}

int *charFreq (char *strPtr) {


int *chr = (int *) malloc (128*sizeof(int));
int j=0;

for (j = 0; j < 128; j++) {


*(chr + j) = 0;
}

j=0;

while (*(strPtr+j)!='\0') {
++*(chr + (int) *(strPtr+j));
j++;
}

return chr;
}

14. Write a program in C which allows users to provide a string then extract all the characters
in that string and print out them in alphabetic order. The function(s) designed should use a
pointer(s).

#include <stdio.h>
#include <stdbool.h>

bool checkAbundant (double num);


bool isInteger(double num);

int main() {
double num=0;

printf("Please input an integer number: ");


scanf("%lf", &num);

while (!isInteger(num) || num<=0) {


printf("\nInvalid number. Please re-input an integer number: ");
scanf("%lf", &num);
}

if (checkAbundant(num)) printf ("The number is abundant");


else printf ("The number is not abundant");

return 0;
}

bool checkAbundant (double num) {


int newNum=0;
int sum=0;

newNum= int(num);
for (int i=1;i<=newNum/2;i++) {
if ((newNum%i)==0) sum=sum+i;
}

printf("Sum of divisor(s) is: %i. ",sum);

if (sum>newNum) return true;


else return false;
}

bool isInteger(double num) {


int integerPart = (int) num;
return num == integerPart;
}

15. Write a program in C to find the Deficient numbers (integers) between two integers using
pointer(s). A deficient number or defective number is a number n for which the sum of divisors
of n is less than 2n. E.g. the proper divisors of 8 are 1, 2, and 4, and their sum is less than 8, so
8 is deficient.
Student can try to solve this problem using dynamic memory allocation.

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

//bool checkAbundant (double num);


bool checkDeficient (double num);
bool isInteger(double num);
int *arrayOfDeficientNum(double firstNum, double finalNum);

int main() {
double firstNum=0,secondNum=0;

printf("Please input first integer number: ");


scanf("%lf", &firstNum);

while (!isInteger(firstNum) || firstNum<=0) {


printf("\nInvalid number. Please re-input an integer number: ");
scanf("%lf", &firstNum);
}

printf("Please input second integer number: ");


scanf("%lf", &secondNum);
while (!isInteger(secondNum) || secondNum<=0) {
printf("\nInvalid number. Please re-input an integer number: ");
scanf("%lf", &secondNum);
}

int *resultArray=NULL;
resultArray=arrayOfDeficientNum(firstNum,secondNum);

printf ("\nThe deficient numbers are:");


for (int j=0;j<(secondNum - firstNum + 1);j++) {
if (*(resultArray+j)==0) break;
else {
printf(" %i", *(resultArray+j));
}
}

return 0;
}

/*bool checkAbundant (double num) {


int newNum=0;
int sum=0;

newNum= int(num);

for (int i=1;i<=newNum/2;i++) {


if ((newNum%i)==0) sum=sum+i;
}

if (sum>newNum) return true;


else return false;
}*/

bool checkDeficient (double num) {


int newNum=0;
int sum=0;

newNum= int(num);

for (int i=1;i<=newNum/2;i++) {


if ((newNum%i)==0) sum=sum+i;
}

if (sum<newNum) return true;


else return false;
}

bool isInteger(double num) {


int integerPart = (int) num;
return num == integerPart;
}

int *arrayOfDeficientNum(double firstNum, double finalNum) {


int *iniArr = (int*) malloc ((int) (finalNum - firstNum + 1)*sizeof(int));
int *newArr = (int*) calloc ((int) (finalNum - firstNum + 1),sizeof(int));

for (int j=0;j<((int) finalNum - firstNum + 1);j++) {


*(iniArr+j)=firstNum+j;
}

int k=0;
for (int j=0;j<((int) finalNum - firstNum + 1);j++) {
if (checkDeficient(*(iniArr+j))==0) continue;
else {
*(newArr+k)=*(iniArr+j);
k++;
}
}

return newArr;
}

16. Write a program in C to calculate the sum of numbers from 1 to n using recursion.

#include <stdio.h>
#include <stdbool.h>

int sumOfNum (double num);


bool isInteger(double num);

int main() {
double num;

printf ("Please input a positive integer number: ");


scanf ("%lf",&num);

while (!isInteger(num) || num<=0) {


printf("\nInvalid number. Please re-input a positive integer number: ");
scanf("%lf", &num);
}
printf ("Sum of numbers from 1 to %.0lf is %i", num, sumOfNum(num));

return 0;
}

int sumOfNum (double num) {


int n = (int) num;

if(n == 0) return 0;
else return n + sumOfNum(n-1);
}

bool isInteger(double num) {


int integerPart = (int) num;
return num == integerPart;
}

17a. Write a program in C to count the digits of a given number using recursion.

b. Write a program in C to find the sum of digits of a number using recursion.

#include <stdio.h>
#include <stdbool.h>
#include <math.h>

int digitCount(double num);


bool isInteger(double num);
int digitSum(double num);

int main() {
double num;

printf ("Please input a positive integer number: ");


scanf ("%lf",&num);

while (!isInteger(num) || num<=0) {


printf("\nInvalid number. Please re-input a positive integer number: ");
scanf("%lf", &num);
}

printf ("Number of digits of %.0lf is %i", num, digitCount(num));


printf ("\nSum of digits of %.0lf is %i", num, digitSum(num));
return 0;
}

int digitCount (double num) {


int n = (int) num;
if (n == 0) return 0;
else return 1 + digitCount (n/10);
}

int digitSum (double num) {


int n = (int) num;
if (n == 0) return 0;
else return (n%10) + digitSum (n/10);
}

bool isInteger(double num) {


int integerPart = (int) num;
return num == integerPart;
}

18. Write a program in C to find the first n number of prime numbers using recursion.

#include <stdio.h>
#include <stdbool.h>

bool isPrime(double num, int i);


void printPrimes(double num, int i);
bool isInteger(double num);

int main() {
double num;

printf ("Please input a positive integer number: ");


scanf ("%lf",&num);

while (!isInteger(num) || num<=0) {


printf("\nInvalid number. Please re-input a positive integer number: ");
scanf("%lf", &num);
}

printf("First %.0lf prime numbers are: ", num);


printPrimes(num, 2);
return 0;
}
bool isPrime(double num, int i) {
int newNum = (int) num;

if(i == 1) return true;


else {
if(newNum % i == 0) return false;
else return isPrime(newNum, i-1);
}
}

void printPrimes(double num, int i) {


int newNum = (int) num;

if(newNum == 0) return;
else {
if(isPrime(i, i-1)) {
printf("%d ", i);
printPrimes(newNum-1, i+1);
}
else printPrimes(newNum, i+1);
}
}

bool isInteger(double num) {


int integerPart = (int) num;
return num == integerPart;
}

19. Write a C program to print the square of array elements using callback function. Student
can try to solve this problem using dynamic memory allocation.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

bool isInteger(double num);


double *generateArray (double numElement);
void printSquaredArray (double numElement);

int main() {
double numElement=0;

printf ("Please input a positive integer number: ");


scanf ("%lf",&numElement);

while (!isInteger(numElement) || numElement<=0) {


printf("\nInvalid number. Please re-input a positive integer number: ");
scanf("%lf", &numElement);
}

printSquaredArray(numElement);

return 0;
}

bool isInteger(double num) {


int integerPart = (int) num;
return num == integerPart;
}

double *generateArray (double numElement) {


double* ptrArr = (double*) calloc ((int) numElement,sizeof(double));

for (int i=0;i< (int) numElement;i++) {


printf ("Enter value of element no.%i: ", i+1);
scanf ("%lf", ptrArr+i);
}

return ptrArr;
}

void printSquaredArray (double numElement) {


double *iniArr = generateArray(numElement);
//double *sqrArr = (double*) calloc ((int) numElement,sizeof(double));

printf ("The squared array:\n");


for (int i=0;i< (int) numElement;i++) {
printf ("%.4lf ", pow(*(iniArr+i),2));
}

return;
}

20. Create a linked-list consisting of public holidays of a year and description of each day (as
string), so that:

- A new public holiday can be added to the beginning of the list -Search for the description of
the day (input argument is a date including day and month)
- Delete a public holiday at the beginning of the list

- Delete a public holiday in the middle of the list (input argument is a date including day and
month)

- Clear the whole list

Write a program to demonstrate the usage of the above list.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct holiday {
char date[11];
char description[50];
struct holiday *next;
};

struct holiday *head = NULL;

void add_holiday(char date[], char description[]) {


struct holiday *new_holiday = (struct holiday*) malloc(sizeof(struct
holiday));
strcpy(new_holiday->date, date);
strcpy(new_holiday->description, description);
new_holiday->next = head;
head = new_holiday;
}

void search_holiday(char date[]) {


struct holiday *temp = head;
while (temp != NULL) {
if (strcmp(temp->date, date) == 0) {
printf("Description: %s\n", temp->description);
return;
}
temp = temp->next;
}
printf("Holiday not found.\n");
}

void delete_first_holiday() {
if (head == NULL) {
printf("List is empty.\n");
return;
}
struct holiday *temp = head;
head = head->next;
free(temp);
}

void delete_holiday(char date[]) {


if (head == NULL) {
printf("List is empty.\n");
return;
}
struct holiday *temp = head;
if (strcmp(temp->date, date) == 0) {
head = head->next;
free(temp);
return;
}
while (temp->next != NULL) {
if (strcmp(temp->next->date, date) == 0) {
struct holiday *del = temp->next;
temp->next = temp->next->next;
free(del);
return;
}
temp = temp->next;
}
printf("Holiday not found.\n");
}

void clear_holidays() {
struct holiday *temp = head;
while (temp != NULL) {
head = head->next;
free(temp);
temp = head;
}
}

void display_holidays() {
struct holiday *temp = head;
while (temp != NULL) {
printf("%s: %s\n", temp->date, temp->description);
temp = temp->next;
}
}
int main() {
FILE *fp = fopen("holidays.txt", "r");
if (fp == NULL) {
printf("Error opening file.\n");
return 0;
}
char date[11], description[50];
while (fscanf(fp, "%s %[^\n]", date, description) != EOF) {
add_holiday(date, description);
}
fclose(fp);
int choice;
char date_input[11], description_input[50];
do {
printf("\n1. Add holiday\n2. Search holiday\n3. Delete first holiday\n4.
Delete holiday\n5. Clear holidays\n6. Display holidays\n7. Exit\nEnter your
choice: ");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("Enter date (dd/mm/yyyy): ");
scanf("%s", date_input);
printf("Enter description: ");
scanf(" %[^\n]", description_input);
add_holiday(date_input, description_input);
printf("Holiday added.\n");
break;
case 2:
printf("Enter date to search (dd/mm/yyyy): ");
scanf("%s", date_input);
search_holiday(date_input);
break;
case 3:
delete_first_holiday();
printf("First holiday deleted.\n");
break;
case 4:
printf("Enter date to delete (dd/mm/yyyy): ");
scanf("%s", date_input);
delete_holiday(date_input);
break;
case 5:
clear_holidays();
printf("All holidays deleted.\n");
break;
case 6:
display_holidays();
break;
case 7:
printf("Exiting program.\n");
break;
default:
printf("Invalid choice.\n");
}
} while (choice != 7);
fp = fopen("holidays.txt", "w");
if (fp == NULL) {
printf("Error opening file.\n");
return 0;
}
struct holiday *temp = head;
while (temp != NULL) {
fprintf(fp, "%s %s\n", temp->date, temp->description);
temp = temp->next;
}
fclose(fp);
return 0;
}
MINI PROJECT

TASK 1.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

//define constant values


#define DEFAULT_NUM_SENSORS 1
#define DEFAULT_SAMPLING_TIME 30 //seconds
#define DEFAULT_MEASUREMENT_DURATION 24 //hours

void generateDustData(FILE *fp,int num_sensors,int sampling_time,int


measurement_duration) {
//get current time
time_t current_time = time(NULL);
struct tm *tm = localtime(&current_time);

//set current_time to the start of today's date and time 00:00:00


current_time -= (tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec);

fprintf(fp, "id,time,value\n");

srand(time(NULL));
int id=1;

//loop over time and generate random values


for (int j = 0; j < measurement_duration * 3600 / sampling_time; j++) {
time_t timestamp = current_time + j * sampling_time;
struct tm *tm = localtime(&timestamp);

for (int k=1; k<=num_sensors;k++) {


fprintf(fp, "%d,%04d:%02d:%02d %02d:%02d:%02d,%.1lf\n", k,
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
(tm->tm_hour), (tm->tm_min), (tm->tm_sec), ((double) (rand() % 6000 +
1)/10));
}
}

fclose(fp);
}

// function to write an error to the task 1 log file


void log_error(int error_code, const char* description) {
FILE* log_file;
log_file = fopen("task1.log", "a");

if (log_file != NULL) {
fprintf(log_file, "Error %02d: %s\n", error_code, description);
fclose(log_file);
} else {
printf("Error: could not open log file for writing\n");
}
}

int main(int argc, char *argv[]) {


int num_sensors = DEFAULT_NUM_SENSORS;
int sampling_time = DEFAULT_SAMPLING_TIME;
int measurement_duration = DEFAULT_MEASUREMENT_DURATION;

// Parse command-line arguments


for (int i = 1; i < argc; i += 2) {
if (strcmp(argv[i], "-n") == 0) {
if (i+1 >= argc) {
log_error(1, "missing value for -n argument");

}
num_sensors = atoi(argv[i+1]);
}else if (strcmp(argv[i], "-st") == 0) {
if (i+1 >= argc) {
log_error(1, "missing value for -st argument");

}
sampling_time = atoi(argv[i+1]);
}else if (strcmp(argv[i], "-si") == 0) {
if (i+1 >= argc) {
log_error(1, "missing value for -si argument");

}
measurement_duration = atoi(argv[i+1]);
} else {
log_error(1, "invalid command-line argument");

}
}

// check for missing arguments


if (num_sensors == DEFAULT_NUM_SENSORS && sampling_time ==
DEFAULT_SAMPLING_TIME && measurement_duration == DEFAULT_MEASUREMENT_DURATION) {
log_error(4, "no command-line arguments provided, using default values");
printf("Error: no command-line arguments provided, using default
values\n");
}

// check for invalid arguments


if (num_sensors <= 0) {
log_error(2, "invalid value for -n argument, must be a positive
integer");
printf("Error: invalid value for -n argument, must be a positive
integer\n");
}
if (sampling_time < 1) {
log_error(2, "invalid value for -st argument, must be a positive
integer greater than or equal to 1");
printf("Error: invalid value for -st argument, must be a positive
integer greater than or equal to 1\n");
}

if (measurement_duration < 1) {
log_error(2, "invalid value for -si argument, must be a positive
integer greater than or equal to 1");
printf("Error: invalid value for -si argument, must be a positive
integer greater than or equal to 1\n");
}
if( (num_sensors <= 0) || (sampling_time < 1) || (measurement_duration < 1)
){
return 1;
}

//create file
FILE *fp = fopen("dust_sensor.csv", "w");
if (fp == NULL) {
log_error(3," dust_sensor.csv access denied");
return 1;
}

// Generate simulation data


printf("Generating simulation data with %d sensors, sampling time %d seconds,
and measurement duration %d hours...\n", num_sensors, sampling_time,
measurement_duration);
generateDustData(fp, num_sensors, sampling_time, measurement_duration);
return 0;
}

id,time,value

1,2023:07:07 00:00:00,84.3

2,2023:07:07 00:00:00,270.7

3,2023:07:07 00:00:00,522.0

1,2023:07:07 00:00:10,501.2

2,2023:07:07 00:00:10,60.2

3,2023:07:07 00:00:10,227.9

TASK 2.

dust_process.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_LINE_LENGTH 1024


#define DEFAULT_FILENAME "dust_sensor.csv"
#define MAX_VALUES 10000
#define MIN_CONCENTRATION 5.0
#define MAX_CONCENTRATION 550.5

//struct to save the dust info


struct dust_sensor_data{
int id;
char timestamp[20];
double concentration;
};

//declare function
void log_error(int error_code,const char* description, int line_number);
int is_outlier(double value);
void decompose(const char *filename);
void check_wrong_intput(const char *filename);
void write_outliers(struct dust_sensor_data* data, int num_values);
//is_outlier function
int is_outlier(double concentration) {
return concentration < MIN_CONCENTRATION || concentration >
MAX_CONCENTRATION;
}
//decompse function
void decompose(const char *filename) {
FILE* input_file = fopen(filename, "r");
if (input_file == NULL) {
log_error(1, " input file not found or not accessible", 0);
printf("Error: could not open file '%s' for reading.\n", filename);
exit(1);
}

char line[MAX_LINE_LENGTH];
struct dust_sensor_data *data = NULL;
int num_values = 0;

// read and check the header row of the input file


char header[MAX_LINE_LENGTH];
fgets(header, MAX_LINE_LENGTH, input_file);

// dynamically allocate memory for the data array


data = malloc(sizeof(struct dust_sensor_data) * MAX_VALUES);
if (data == NULL) {
log_error(6, " failed to allocate memory", 0);
printf("Error: failed to allocate memory for data array.\n");
fclose(input_file);
exit(1);
}

// scan values
while (fgets(line, MAX_LINE_LENGTH, input_file) != NULL && num_values <
MAX_VALUES) {
char* token = strtok(line, ",");
if (token == NULL) {
continue;
}
data[num_values].id = atoi(token);
token = strtok(NULL, ",");
if (token == NULL) {
continue;
}
strncpy(data[num_values].timestamp, token, 20);
token = strtok(NULL, ",");
if (token == NULL) {
continue;
}
data[num_values].concentration = atof(token);
num_values++;
}
fclose(input_file);

write_outliers(data, num_values);

// free memory allocated for the data array


free(data);
}

void write_outliers(struct dust_sensor_data* data, int num_values) {


int num_outliers = 0;
for (int i = 0; i < num_values; i++) {
if (is_outlier(data[i].concentration)) {
num_outliers++;
}
}
//file for invalid values
FILE *outlier_file = fopen("dust_outlier.csv", "w");
if (outlier_file == NULL) {
log_error(5, " could not open outlier file for writing", 0);
printf("Error: could not open outlier file for writing\n");
fclose(outlier_file);
exit(1);
}
//file for valid values
FILE *valid_file = fopen("dust_valid.csv", "w");
if (valid_file == NULL) {
log_error(5, " could not open valid file for writing", 0);
printf("Error: could not open valid file for writing\n");
fclose(valid_file);
fclose(outlier_file);
exit(1);
}

fprintf(outlier_file, "number of outliers: %d\n", num_outliers);


fprintf(valid_file, "id,time,value\n");
fprintf(outlier_file, "id,time,value\n");
for (int i = 0; i < num_values; i++) {
if(data[i].concentration <= 0 ) continue;
if (is_outlier(data[i].concentration)) {
fprintf(outlier_file, "%d,%s,%.1f\n", data[i].id, data[i].timestamp,
data[i].concentration);
}else {
fprintf(valid_file, "%d,%s,%.1lf\n", data[i].id, data[i].timestamp,
data[i].concentration);
}

fclose(outlier_file);
fclose(valid_file);

return;
}

//check wrong data in inputfile


void check_wrong_intput(const char *filename){
FILE* input_file = fopen(filename, "r");
char line[100]; // Assuming max line length is 100
int line_number = 0;
while (fgets(line, 100, input_file) != NULL) {
if (line_number == 0) {
// Check header format
char* id_str = strtok(line, ",");
char* time_str = strtok(NULL, ",");
char* value_str = strtok(NULL, ",");
if (id_str == NULL || strcmp(id_str, "id") != 0 ||
time_str == NULL || strcmp(time_str, "time") != 0 ||
value_str == NULL || strcmp(value_str, "value\n") != 0) {
log_error(2, " invalid csv file format", 0);
}
} else {
// Check data format
char* id_str = strtok(line, ",");
char* time_str = strtok(NULL, ",");
char* value_str = strtok(NULL, ",");
if (id_str == NULL || atoi(id_str) < 0 ||
time_str == NULL || strstr(time_str, ":") == NULL ||
value_str == NULL || atof(value_str) <= 0.0) {
log_error(4, " data is missing", line_number);
exit(1);
}
}
line_number++;
}
fclose(input_file);
}
void log_error( int error_code,const char* description, int line_number) {

FILE* task2_log = fopen("task2.log", "a"); // Append to log file

// Write the error message in the log file


if (error_code == 4) {
fprintf(task2_log, "Error 04: %s at line %d\n", description,
line_number);
} else {
fprintf(task2_log, "Error %02d: %s\n", error_code, description);
}

// Close the log file


fclose(task2_log);
}

int main(int argc, char* argv[]) {


const char *filename ;
if (argc == 1) {
filename = DEFAULT_FILENAME;
log_error(3, "no command-line arguments provided, using default file ",
0);
printf("Error: no command-line arguments provided, using default file
\n");
} else if (argc == 2) {
filename = argv[1];
} else {
log_error(3, "Invalid command ", 0);
printf("Usage: C:\\dust_process [data_filename.csv]\n");
exit(1);
}

check_wrong_intput(filename);
decompose(filename);

return 0;
}

number of outliers: 844

id,time,value
1,2023:07:07 00:00:50,571.4

2,2023:07:07 00:00:50,564.3

3,2023:07:07 00:01:10,587.9

dust_aqi.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

//define max min valid values


#define MIN_VALID_VALUE 5.0
#define MAX_VALID_VALUE 550.5

//define AQI values


#define AQI_GOOD_MAX 50
#define AQI_MODERATE_MAX 100
#define AQI_SLIGHTLY_UNHEALTHY_MAX 150
#define AQI_UNHEALTHY_MAX 200
#define AQI_VERY_UNHEALTHY_MAX 300
#define AQI_HAZARDOUS_MAX 400
#define AQI_EXTREMELY_HAZARDOUS_MAX 500

//declare function
void log_error(int error_code, const char* description);
int findMaxSensorID(const char *filename);
void processDustData(const char *input_filename, int MaxID);

//create structures for dust data


typedef struct {
int id;
char time[20];
double value;
} DustData;

typedef struct {
double sum;
int count;
} HourlyData;

int findMaxSensorID(const char *filename) {


FILE *file = fopen(filename, "r");

int MaxID = -1;


char line[256];

while (fgets(line, sizeof(line), file)) {


int id;
sscanf(line, "%d,", &id);
if (id > MaxID) {
MaxID = id;
}
}

fclose(file);
return MaxID;
}

void processDustData(const char *input_filename, int MaxID) {


// Read dust_valid.csv
FILE *input_file = fopen(input_filename, "r");
if (input_file == NULL) {
log_error(1, " could not open input file ");
printf("Error: could not open input file: %s\n", input_filename);
fclose(input_file);
return;
}

// File for AQI values


FILE *aqi_file = fopen("dust_aqi.csv", "w");
if (aqi_file == NULL) {
log_error(1, " could not open aqi file ");
printf("Error: could not open AQI file for writing\n");
fclose(input_file);
return;
}

char line[256]; // String to hold each line of .csv file


DustData data;
HourlyData hourly_data[24][MaxID + 1];
int current_hour = -1;

fprintf(aqi_file, "id,time,value,aqi,pollution\n");

while (fgets(line, sizeof(line), input_file)) {


sscanf(line, "%d,%[^,],%lf", &data.id, data.time, &data.value); // Copy
values to declared variables

// Check if new hour has started


int hour = atoi(&data.time[11]);
if (hour != current_hour) {
// Calculate AQI for previous hour
if (current_hour != -1) {
for (int i = 1; i <= MaxID; i++) {
double hourly_average = 0;
int aqi;
char pollution[20];
if (hourly_data[current_hour][i].count > 0) {
hourly_average = hourly_data[current_hour][i].sum /
hourly_data[current_hour][i].count;
}
if (hourly_average >= 0 && hourly_average < 12) {
aqi = (int)round((hourly_average - 0) * (AQI_GOOD_MAX -
0) / (12 - 0));
strcpy(pollution, "Good");
} else if (hourly_average >= 12 && hourly_average < 35.5) {
aqi = (int)round(((hourly_average - 12) *
(AQI_MODERATE_MAX - AQI_GOOD_MAX) / (35.5 - 12)) + AQI_GOOD_MAX);
strcpy(pollution, "Moderate");
} else if (hourly_average >= 35.5 && hourly_average < 55.5) {
aqi = (int)round(((hourly_average - 35.5) *
(AQI_SLIGHTLY_UNHEALTHY_MAX - AQI_MODERATE_MAX) / (55.5 - 35.5)) +
AQI_MODERATE_MAX);
strcpy(pollution, "Slightly unhealthy");
} else if (hourly_average >= 55.5 && hourly_average < 150.5)
{
aqi = (int)round(((hourly_average - 55.5) *
(AQI_UNHEALTHY_MAX - AQI_SLIGHTLY_UNHEALTHY_MAX) / (150.5 - 55.5)) +
AQI_SLIGHTLY_UNHEALTHY_MAX);
strcpy(pollution, "Unhealthy");
} else if (hourly_average >= 150.5 && hourly_average < 250.5)
{
aqi = (int)round(((hourly_average - 150.5) / (250.5 -
150.5) * (AQI_VERY_UNHEALTHY_MAX - AQI_UNHEALTHY_MAX)) + AQI_UNHEALTHY_MAX);
strcpy(pollution, "Very unhealthy");
} else if (hourly_average >= 250.5 && hourly_average < 350.5)
{
aqi = (int)round(((hourly_average - 250.5) / (350.5 -
250.5) * (AQI_HAZARDOUS_MAX - AQI_VERY_UNHEALTHY_MAX)) + AQI_VERY_UNHEALTHY_MAX);
strcpy(pollution, "Hazardous");
} else {
aqi = (int)round(((hourly_average - 350.5) / (500 -
350.5) * (AQI_EXTREMELY_HAZARDOUS_MAX - AQI_HAZARDOUS_MAX)) + AQI_HAZARDOUS_MAX);
strcpy(pollution, "Extremely hazardous");
}

// Write AQI data to file


char date[11];
strncpy(date, data.time, 10);
date[10] = '\0';
fprintf(aqi_file, "%d,%s %02d:00:00,%.1lf,%d,%s\n", i, date,
current_hour+1, hourly_average, aqi, pollution);
}
}

// Reset hourly data


for (int i = 0; i < 24; i++) {
for (int j = 1; j <= MaxID; j++) {
hourly_data[i][j].sum = 0;
hourly_data[i][j].count = 0;
}
}
current_hour = hour;
}

// Add data to hourly data


if (data.value >= MIN_VALID_VALUE && data.value <= MAX_VALID_VALUE) {
hourly_data[current_hour][data.id].sum += data.value;
hourly_data[current_hour][data.id].count++;
}
}

// Close files
fclose(input_file);
fclose(aqi_file);
}

void log_error(int error_code, const char* description) {


FILE* log_file;
log_file = fopen("task2.log", "a");

if (log_file != NULL) {
fprintf(log_file, "Error %02d: %s\n", error_code, description);
fclose(log_file);
} else {
printf("Error: could not open log file for writing\n");
}
}

int main(int argc, char *argv[]) {


//Check command-line arguments
if (argc != 2) {
log_error(3, "Invalid command line. Correct usage:
C:\\dust_aqi [data_filename.csv]");
printf("Invalid command line. Correct usage: %s [data_filename.csv]\n",
argv[0]);
return 1;
}

int MaxID=findMaxSensorID(argv[1]);
processDustData(argv[1],MaxID);

return 0;
}

id,time,value,aqi,pollution

1,2023:07:07 01:00:00,271.2,321,Hazardous

2,2023:07:07 01:00:00,251.9,301,Hazardous

3,2023:07:07 01:00:00,271.2,321,Hazardous

dust_summary.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct DateTime {
int year;
int month;
int day;
int hour;
int minute;
int second;
};
int calculateSeconds(struct DateTime dt1, struct DateTime dt2);
int daysInMonth(int month, int year);
int findMaxSensorID(const char *filename);
void generateSummary(const char *data_filename, int MaxID);
void log_error(int error_code, const char* description);

int daysInMonth(int month, int year) {


int days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if (month == 2 && (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)))
return 29;
return days[month - 1];
}

int calculateSeconds(struct DateTime dt1, struct DateTime dt2) {


int seconds = 0;

// Calculate the seconds for each year


for (int year = dt1.year; year < dt2.year; year++) {
seconds += 365 * 24 * 60 * 60;
if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
seconds += 24 * 60 * 60; // Add a leap day
}

// Calculate the seconds for each month


for (int month = 1; month < dt2.month; month++)
seconds += daysInMonth(month, dt2.year) * 24 * 60 * 60;
for (int month = 1; month < dt1.month; month++)
seconds -= daysInMonth(month, dt1.year) * 24 * 60 * 60;

// Calculate the seconds for each day


seconds += (dt2.day - dt1.day) * 24 * 60 * 60;

// Calculate the seconds for each hour, minute, and second


seconds += (dt2.hour - dt1.hour) * 60 * 60;
seconds += (dt2.minute - dt1.minute) * 60;
seconds += dt2.second - dt1.second;

return seconds;
}

// Function to find the maximum sensor ID


int findMaxSensorID(const char *filename) {
FILE *file = fopen(filename, "r");
if (file == NULL) {
printf("Error: could not open file: %s\n", filename);
return -1;
}

int MaxID = -1;


char line[256];

while (fgets(line, sizeof(line), file)) {


int id;
sscanf(line, "%d,", &id);
if (id > MaxID) {
MaxID = id;
}
}

fclose(file);
return MaxID;
}

// Function to generate the summary


void generateSummary(const char *data_filename, int MaxID) {
// Create dust_summary.csv file
FILE *summary_file = fopen("dust_summary.csv", "w");
if (summary_file == NULL) {
log_error(3, " could not create summary file ");
printf("Error: could not create summary file\n");
return;
}

fprintf(summary_file, "id,parameter,time,value\n");

FILE *data_file = fopen(data_filename, "r");


if (data_file == NULL) {
log_error(2, " could not open input file ");
printf("Error: could not open input file: %s\n", data_filename);
return;
}

char line[256];
fgets(line, sizeof(line), data_file); // Skip header line

struct DateTime first_timestamp;


struct DateTime last_timestamp;
int first_timestamp_initialized = 0;

while (fgets(line, sizeof(line), data_file)) {


int sensor_id;
struct DateTime timestamp;
double value;

sscanf(line, "%d,%d:%d:%d %d:%d:%d,%lf", &sensor_id, &timestamp.year,


&timestamp.month, &timestamp.day, &timestamp.hour, &timestamp.minute,
&timestamp.second, &value);

if (!first_timestamp_initialized) {
first_timestamp = timestamp;
first_timestamp_initialized = 1;
}

last_timestamp = timestamp;
}

fclose(data_file);

int seconds = calculateSeconds(first_timestamp, last_timestamp);

for (int id = 1; id <= MaxID; id++) {


double max_value = 0.0, min_value = 0.0, mean_value = 0.0, sum = 0.0;
int count = 0;

data_file = fopen(data_filename, "r");


if (data_file == NULL) {
printf("Error: could not open data file: %s\n", data_filename);
fclose(summary_file);
return;
}

fgets(line, sizeof(line), data_file); // Skip header line

struct DateTime min_time, max_time;


int first_time_initialized = 0;

while (fgets(line, sizeof(line), data_file)) {


int sensor_id;
struct DateTime time;
double value;

sscanf(line, "%d,%d:%d:%d %d:%d:%d,%lf", &sensor_id, &time.year,


&time.month, &time.day, &time.hour, &time.minute, &time.second, &value);

if (sensor_id == id) {
if (!first_time_initialized) {
min_time = time; // Initialize min_time with the first time
min_value = value; // Initialize min_value with the first
value
first_time_initialized = 1;
}

if (value > max_value) {


max_value = value;
max_time = time; // Update max_time for the new maximum value
}

if (value < min_value) {


min_value = value;
min_time = time; // Update min_time for the new minimum value
}

sum += value;
count++;
}
}

fclose(data_file);

if (count > 0) {
mean_value = sum / count;

fprintf(summary_file, "%d,max,%d:%02d:%02d %02d:%02d:%02d,%.1lf\n",


id, max_time.year, max_time.month, max_time.day, max_time.hour, max_time.minute,
max_time.second, max_value);
fprintf(summary_file, "%d,min,%d:%02d:%02d %02d:%02d:%02d,%.1lf\n",
id, min_time.year, min_time.month, min_time.day, min_time.hour, min_time.minute,
min_time.second, min_value);
fprintf(summary_file, "%d,mean,%02d:%02d:%02d,%.1lf\n", id, seconds /
3600, (seconds % 3600) / 60, seconds % 60, mean_value);
}
}

fclose(summary_file);
printf("Summary generated successfully.\n");
}

void log_error(int error_code, const char* description) {


FILE* log_file;
log_file = fopen("task2.log", "a");
if (log_file != NULL) {
fprintf(log_file, "Error %02d: %s\n", error_code, description);
fclose(log_file);
} else {
printf("Error: could not open log file for writing\n");
}
}

int main(int argc, char *argv[]) {


// Check command-line arguments
if (argc != 2) {
log_error(1, "Invalid command line. Correct usage:
C:\\dust_summary [data_filename.csv] ]");
printf("Invalid command line. Correct usage:
C:\\dust_summary [data_filename.csv]\n", argv[0]);
return 1;
}

// Check input file


/*FILE *input_file = fopen(argv[1], "r");
if (input_file == NULL) {
log_error(2, " could not open input file ");
printf("Error: could not open input file: %s\n", argv[1]);

return 1;
}*/

// Find the maximum sensor ID


int MaxID = findMaxSensorID(argv[1]);

// Generate the summary


generateSummary(argv[1], MaxID);

return 0;
}

id,parameter,time,value

1,max,2023:07:07 00:10:20,550.5

1,min,2023:07:07 08:10:50,5.0
1,mean,09:15:30,264.0

2,max,2023:07:07 07:29:20,550.5

2,min,2023:07:07 02:16:30,5.0

2,mean,09:15:30,262.5

3,max,2023:07:07 02:03:30,550.2

3,min,2023:07:07 02:07:00,5.1

3,mean,09:15:30,268.0

Dust_statistics.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_POLLUTION_LEVELS 7

void log_error(int error_code, const char* description);


int findMaxSensorID(const char *filename);
void processDustData(const char *dataFilename, int maxID);

typedef struct {
int id;
char pollution[20];
int duration;
} SensorData;

// Function to find the maximum sensor ID in the data file


int findMaxSensorID(const char *filename) {
FILE *file = fopen(filename, "r");

int maxID = -1;


char line[256];
while (fgets(line, sizeof(line), file)) {
int id;
sscanf(line, "%d,%*[^,],%*f,%*d,%*[^,\n]", &id);

if (id > maxID) {


maxID = id;
}
}

fclose(file);

return maxID;
}

// Function to process the dust data and generate statistics


void processDustData(const char *dataFilename, int maxID) {
FILE *inputFile = fopen(dataFilename, "r");
if (inputFile == NULL) {
log_error(1, "could not open input file");
printf("Error: could not open input file: %s\n", dataFilename);
return;
}

SensorData sensorData[maxID][MAX_POLLUTION_LEVELS];
int i, j;

// Initialize sensor data


for (i = 0; i < maxID; i++) {
for (j = 0; j < MAX_POLLUTION_LEVELS; j++) {
sensorData[i][j].id = i + 1;
sensorData[i][j].duration = 0;

switch (j) {
case 0:
strcpy(sensorData[i][j].pollution, "Good");
break;
case 1:
strcpy(sensorData[i][j].pollution, "Moderate");
break;
case 2:
strcpy(sensorData[i][j].pollution, "Slightly unhealthy");
break;
case 3:
strcpy(sensorData[i][j].pollution, "Unhealthy");
break;
case 4:
strcpy(sensorData[i][j].pollution, "Very unhealthy");
break;
case 5:
strcpy(sensorData[i][j].pollution, "Hazardous");
break;
case 6:
strcpy(sensorData[i][j].pollution, "Extremely hazardous");
break;
default:
break;
}
}
}

char line[256];
while (fgets(line, sizeof(line), inputFile)) {
int id, aqi;
char pollution[20];

sscanf(line, "%d,%*[^,],%*f,%d,%[^,\n]", &id, &aqi, pollution);

if (id >= 1 && id <= maxID) {


for (j = 0; j < MAX_POLLUTION_LEVELS; j++) {
if (strcmp(pollution, sensorData[id - 1][j].pollution) == 0) {
sensorData[id - 1][j].duration++;
break;
}
}
}
}

fclose(inputFile);

// Write to the dust_statistics.csv file


FILE *outputFile = fopen("dust_statistics.csv", "w");
if (outputFile == NULL) {
log_error(1, " could not open output file: dust_statistics.csv ");
printf("Error: could not open output file: dust_statistics.csv\n");
return;
}

fprintf(outputFile, "id,pollution,duration\n");

for (i = 0; i < maxID; i++) {


for (j = 0; j < MAX_POLLUTION_LEVELS; j++) {
if (sensorData[i][j].duration > 0) {
fprintf(outputFile, "%d,%s,%d\n", sensorData[i][j].id,
sensorData[i][j].pollution, sensorData[i][j].duration);
}
}
}

fclose(outputFile);
}

void log_error(int error_code, const char* description) {


FILE* log_file;
log_file = fopen("task2.log", "a");

if (log_file != NULL) {
fprintf(log_file, "Error %02d: %s\n", error_code, description);
fclose(log_file);
} else {
printf("Error: could not open log file for writing\n");
}
}

int main(int argc, char *argv[]) {


if (argc != 2) {
log_error(3, "Invalid command line. Correct usage:
C:\\dust_summary [data_filename.csv] ]");
printf("Invalid command line. Correct usage: %s [data_filename.csv]\n",
argv[0]);
return 1;
}

// Find the maximum sensor ID in the data file


int MaxID = findMaxSensorID(argv[1]);
if (MaxID == -1) {
return 1;
}

// Process the dust data and generate statistics


processDustData(argv[1], MaxID);

return 0;
}

id,pollution,duration

1,Hazardous,9

2,Hazardous,9

3,Hazardous,9
TASK 3.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

void convertToHexPacket(const char* dataFilename, const char* hexFilename);


unsigned char calculateChecksum(const unsigned char* packet, size_t length);
void appendHexPacket(FILE* file, const unsigned char* packet, size_t length);
unsigned int convertTimestamp(const char* timestamp);
unsigned int pm25ToFloat(float pm25);
void log_error( int error_code, char* description, int line_number);
void check_wrong_intput(const char *datafile);

int main(int argc, char* argv[]) {


if (argc != 3) {
log_error(1, "Invalid command line. Correct usage:
C:\\dust_summary [data_filename.csv] [hex_filename.dat]" , 0);
printf("Invalid number of arguments. Usage: dust_convert
[data_filename.csv] [hex_filename.dat]\n");
return 1;
}
// Check input file
FILE *dataFile = fopen(argv[1], "r");
if (dataFile == NULL) {
log_error(1 , " could not open datafile ", 0);
printf("Error: could not open datafile: %s\n", argv[1]);
return 1;
}
fclose(dataFile);
//check hex file
FILE *hexFile = fopen(argv[2], "r");
if (dataFile == NULL) {
log_error(5 , " cannot override hex_filename.dat ", 0);
printf("Error: cannot override %s\n", argv[2]);
return 1;
}
fclose(hexFile);

const char* dataFilename = argv[1];


const char* hexFilename = argv[2];

check_wrong_intput(dataFilename);
convertToHexPacket(dataFilename, hexFilename);

printf("Conversion completed successfully.\n");

return 0;
}

void log_error( int error_code, char* description, int line_number) {

FILE* task3_log = fopen("task3.log", "a"); // Append to log file

// Write the error message in the log file


if (error_code == 4) {
fprintf(task3_log, "Error 04: %s at line %d\n", description,
line_number);
} else {
fprintf(task3_log, "Error %02d: %s\n", error_code, description);
}

// Close the log file


fclose(task3_log);
}

void check_wrong_intput(const char *datafile){


FILE* input_file = fopen(datafile, "r");
char line[100]; // Assuming max line length is 100
int line_number = 0;
while (fgets(line, 100, input_file) != NULL) {
if (line_number == 0) {
// Check header format
char* id_str = strtok(line, ",");
char* time_str = strtok(NULL, ",");
char* value_str = strtok(NULL, ",");
if (id_str == NULL || strcmp(id_str, "id") != 0 ||
time_str == NULL || strcmp(time_str, "time") != 0 ||
value_str == NULL || strcmp(value_str, "value\n") != 0) {
log_error(2, "invalid csv file format", 0);
}
} else {
// Check data format
char* id_str = strtok(line, ",");
char* time_str = strtok(NULL, ",");
char* value_str = strtok(NULL, ",");
if (id_str == NULL || atoi(id_str) < 0 ||
time_str == NULL || strstr(time_str, ":") == NULL ||
value_str == NULL || atof(value_str) < 0.0) {
log_error(4, "Error 04: data is missing", line_number);
}
}
line_number++;
}
fclose(input_file);
}

void convertToHexPacket(const char* dataFilename, const char* hexFilename) {


FILE* dataFile = fopen(dataFilename, "r");

FILE* hexFile = fopen(hexFilename, "w");

// read and check in the header row of the input file


char header[100];
fgets(header, 100, dataFile);
char line[256];

while (fgets(line, sizeof(line), dataFile)) {


// Skip empty lines and lines starting with a comment character
if (line[0] == '\n' || line[0] == '#') {
continue;
}

// Extract the values from the CSV line


unsigned int id;
char timestamp[20];
double value;
unsigned int aqi;
char pollution[20];

sscanf(line, "%u,%19[^,],%lf,%u,%19s", &id, timestamp, &value, &aqi,


pollution);

// Convert the values to the corresponding packet format


unsigned char packet[16];
packet[0] = 0x7A; // Start byte

packet[1] = 0x0F; // Packet length (15 bytes)

packet[2] = (unsigned char)id; // ID


unsigned int timestampValue = convertTimestamp(timestamp);
memcpy(&packet[3], &timestampValue, sizeof(timestampValue)); // Time

unsigned int pm25Value = pm25ToFloat((float)value);


memcpy(&packet[7], &pm25Value, sizeof(pm25Value)); // PM2.5 concentration

packet[11] = (unsigned char)(aqi >> 8); // AQI (high byte)


packet[12] = (unsigned char)aqi; // AQI (low byte)

unsigned int checksum = calculateChecksum(packet, sizeof(packet) - 2); //


Exclude the start byte and checksum itself
memcpy(&packet[13], &checksum, sizeof(checksum)); // Checksum
packet[14] = 0x7F; // Stop byte

// Write the packet as a hex string to the output file


appendHexPacket(hexFile, packet, sizeof(packet));
}

fclose(dataFile);
fclose(hexFile);
}

unsigned char calculateChecksum(const unsigned char* packet, size_t length) {

unsigned int sum = 0;


// Sum the bytes of the data packet
for (unsigned int i = 0; i < length; i++) {

sum += packet[i];

// Take the two's complement of the sum


unsigned char checksum = (~sum + 1) & 0xFF;

return checksum;
}

void appendHexPacket(FILE* file, const unsigned char* packet, size_t length) {


for (size_t i = 0; i < length-1; i++) {
fprintf(file, "%02X ", packet[i]);
}
fprintf(file, "\n");
}

unsigned int convertTimestamp(const char* timestamp) {


unsigned int year, month, day, hour, minute, second;
sscanf(timestamp, "%u:%u:%u %u:%u:%u", &year, &month, &day, &hour, &minute,
&second);

// Convert the timestamp to Unix timestamp format


struct tm tm;
tm.tm_year = year - 1900;
tm.tm_mon = month - 1;
tm.tm_mday = day;
tm.tm_hour = hour;
tm.tm_min = minute;
tm.tm_sec = second;
tm.tm_isdst = -1;

time_t unixTimestamp = mktime(&tm);


// Convert the Unix timestamp to big-endian byte order
unsigned int bigEndianTimestamp =
((unixTimestamp & 0xff000000) >> 24) |
((unixTimestamp & 0x00ff0000) >> 8) |
((unixTimestamp & 0x0000ff00) << 8) |
((unixTimestamp & 0x000000ff) << 24);

return bigEndianTimestamp;
}

unsigned int pm25ToFloat(float pm25) {


unsigned int sign, exponent, fraction;

// Convert the PM2.5 concentration to binary format


unsigned int pm25Bits = *(unsigned int*)&pm25;

// Extract the sign, exponent, and fraction fields


sign = (pm25Bits >> 31) & 0x1;
exponent = ((pm25Bits >> 23) & 0xff) - 127;
fraction = pm25Bits & 0x7fffff;

// Combine the sign, exponent, and fraction fields into a 32-bit binary value
unsigned int floatBits = (sign << 31) | ((exponent + 127) << 23) | fraction;

// Convert the 32-bit binary value to big-endian byte order manually


unsigned int bigEndianFloatBits =
((floatBits & 0xff000000) >> 24) |
((floatBits & 0x00ff0000) >> 8) |
((floatBits & 0x0000ff00) << 8) |
((floatBits & 0x000000ff) << 24);

return bigEndianFloatBits;
}

7A 0F 01 64 A7 01 20 43 87 99 9A 01 41 0B 7F

7A 0F 02 64 A7 01 20 43 7B E6 66 01 2D 06 7F

7A 0F 03 64 A7 01 20 43 87 99 9A 01 41 03 7F

7A 0F 01 64 A7 0F 30 43 7D CC CD 01 2F A0 7F

7A 0F 02 64 A7 0F 30 43 7C CC CD 01 2E 04 7F

7A 0F 03 64 A7 0F 30 43 83 80 00 01 38 A7 7F

7A 0F 01 64 A7 1D 40 43 8C 73 33 01 4A A7 7F

7A 0F 02 64 A7 1D 40 43 80 33 33 01 32 0A 7F

You might also like