How to make a class scheduler and optimizer - c

So basically, I want to create some code that takes input from the user. First the program should know the completed classes with the ability to add new classes once the semester ends. I type in a class and it crosschecks the pre-requistes with my completed classes. If I meet the pre-requites it will add the class to the schedule for the semester and checks it off in my future classes. Then it calculates the amount of time I have left by dividing my credits completed and added by my total credits by 15 per semester. It should be able to give me the best optimized schedule by listing every variation at the end. I don't even know where to start, or even know how to make the database of completed classes. My database to write to a txt file is below
#include <stdio.h>
#include <stdlib.h>
#define DATA_SIZE 1000
int main()
{
/* Variable to store user content */
char data[DATA_SIZE];
/* File pointer to hold reference to our file */
FILE * fPtr;
/*
* Open file in w (write) mode.
* "data/file1.txt" is complete path to create file
*/
fPtr = fopen("database.txt", "a+");
/* fopen() return NULL if last operation was unsuccessful */
if(fPtr == NULL)
{
/* File not created hence exit */
printf("Unable to create file.\n");
exit(EXIT_FAILURE);
}
/* Input contents from user to store in file */
printf("Enter contents to store in file : \n");
fgets(data, DATA_SIZE, stdin);
/* Write data to file */
fputs(data, fPtr);
/* Close file to save file data */
fclose(fPtr);
/* Success message */
printf("File created and saved successfully. 🙂 \n");
return 0;
}

At first, you could make a "CompletedClasses.txt, and write in it whenever you completed the pre-requisites of completing a specific class.
As I read your post, your concern is, in fact, a bunch of ifs to get sorted.
That's like a path to follow and once you got to a checkpoint you fprintf(MyFile,"%s",MyCompletedClasses); and so on and so forth once you get your final program.
Try to get it cleared out at first, you'll get a much wider view of the issue after.
GoodLuck !

Related

Open file, print to stdout, append to file, and print to stdout again

In the following C-code I open a file called test.txt which contains a few lines. I then read in those lines in a while-loop and print them to stdout. Afterwards I make a few changes in the file by e.g. appending the number 42 to it. I then want to print the contents of the changed file to stdout but I seem to missing something there. Here is my code so far (unnecessarily commented):
#include <stdio.h>
#include <stdlib.h> /* for exit() */
main ()
{ /* Declare variables */
FILE *file_read;
char file_save[100];
int number = 42;
/* Open file */
file_read = fopen("/home/chb/files/Cground/test.txt", "a+");
/* Check if file exists. */
if (file_read == NULL) {
fprintf(stderr, "Cannot open file\n");
exit(1);
}
/* Print what is currently in the file */
printf("This is what is currently in the file:\n");
while(fgets(file_save, 100, file_read) != NULL) {
printf("%s", file_save);
}
/* Change the contents of the file */
fprintf(file_read, "%d\n", number);
/* Print what is in the file after the call to fscanf() */
printf("This is what is now in the file:\n");
/* Missing code */
fclose(file_read);
}
It seems that a simple while-loop placed where Missing code is, similar to the one already used before will not suffice. Can someone please explain what is going on. I don't mind technicalities!
In order to read the file from the start again you have to call fseek() first, like so
fseek(file_read, 0, SEEK_SET);
this sets the stream position indicator back to the start of the file.
See http://www.cplusplus.com/reference/cstdio/fseek/ for more info.
You do not set the file pointer back to start. As it's already at the end of the file, there's nothing more to read.
Before reading the file again, do:
rewind(file_read); //before the "missing code" comment
to set it back at the start of the file.

read multiple fasta sequence using external library kseq.h

I am trying to find fasta sequences of 5 ids/name as provided by user from a big fasta file (containing 80000 fasta sequences) using an external header file kseq.h as in: http://lh3lh3.users.sourceforge.net/kseq.shtml. When I run the program in a for loop, I have to open/close the big fasta file again and again (commented in the code) which makes the computation time slow. On the contrary, if I open/close only once outside the loop, the program stops if it encounters an entry which is not present in the big fasta file I.e. it reaches end of the file. Can anyone suggest how to get all the sequences without losing computational time. The code is:
#include <zlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "ext_libraries/kseq.h"
KSEQ_INIT(gzFile, gzread)
int main(int argc, char *argv[])
{
char gwidd_ids[100];
kseq_t *seq;
int i=0, nFields=0, row=0, col=0;
int size=1000, flag1=0, l=0, index0=0;
printf("Opening file %s\n", argv[1]);
char **gi_ids=(char **)malloc(sizeof(char *)*size);
for(i=0;i<size;i++)
{
gi_ids[i]=(char *)malloc(sizeof(char)*50);
}
FILE *fp_inp = fopen(argv[1], "r");
while(fscanf(fp_inp, "%s", gwidd_ids) == 1)
{
printf("%s\n", gwidd_ids);
strcpy(gi_ids[index0], gwidd_ids);
index0++;
}
fclose(fp_inp);
FILE *f0 = fopen("xxx.txt", "w");
FILE *f1 = fopen("yyy.txt", "w");
FILE *f2 = fopen("zzz", "w");
FILE *instream = NULL;
instream = fopen("fasta_seq_uniprot.txt", "r");
gzFile fpf = gzdopen(fileno(instream), "r");
for(col=0;col<index0;col++)
{
flag1=0;
// FILE *instream = NULL;
// instream = fopen("fasta_seq_nr_uniprot.txt", "r");
// gzFile fpf = gzdopen(fileno(instream), "r");
kseq_t *seq = kseq_init(fpf);
while((kseq_read(seq)) >= 0 && flag1 == 0)
{
if(strcasecmp(gi_ids[col], seq->name.s) == 0)
{
fprintf(f1, ">%s\n", gi_ids[col]);
fprintf(f2, ">%s\n%s\n", seq->name.s, seq->seq.s);
flag1 = 1;
}
}
if(flag1 == 0)
{
fprintf(f0, "%s\n", gi_ids[col]);
}
kseq_destroy(seq);
// gzclose(fpf);
}
gzclose(fpf);
fclose(f0);
fclose(f1);
fclose(f2);
for(i=0;i<size;i++)
{
free(gi_ids[i]);
}
free(gi_ids);
return 0;
}
A few examples of inputfile (fasta_seq_uniprot.txt) is:
P21306
MSAWRKAGISYAAYLNVAAQAIRSSLKTELQTASVLNRSQTDAFYTQYKNGTAASEPTPITK
P38077
MLSRIVSNNATRSVMCHQAQVGILYKTNPVRTYATLKEVEMRLKSIKNIEKITKTMKIVASTRLSKAEKAKISAKKMD
-----------
-----------
The user entry file is
P37592\n
Q8IUX1\n
B3GNT2\n
Q81U58\n
P70453\n
Your problem appears a bit different than you suppose. That the program stops after trying to retrieve a sequence that is not present in the data file is a consequence of the fact that it never rewinds the input. Therefore, even for a query list containing only sequences that are present in the data file, if the requested sequence IDs are not in the same relative order as the data file then the program will fail to find some of the sequences (it will pass them by when looking for an earlier-listed sequence, never to return).
Furthermore, I think it likely that the time savings you observe comes from making only a single pass through the file, instead of a (partial) pass for each requested sequence, not so much from opening it only once. Opening and closing a file is a bit expensive, but nowhere near as expensive as reading tens or hundreds of kilobytes from it.
To answer your question directly, I think you need to take these steps:
Move the kseq_init(seq) call to just before the loop.
Move the kseq_destroy(seq) call to just after the loop.
Put in a call to kseq_rewind(seq) as the last statement in the loop.
That should make your program right again, but it is likely to kill pretty much all your time savings, because you will return to scanning the file from the beginning for each requested sequence.
The library you are using appears to support only sequential access. Therefore, the most efficient way to do the job both right and fast would be to invert the logic: read sequences one at a time in an outer loop, testing each one as you go to see whether it matches any of the requested ones.
Supposing that the list of requested sequences will contain only a few entries, like your example, you probably don't need to do any better testing for matches than just using an inner loop to test each requested sequence id vs. the then-current sequence. If the query lists may be a lot longer, though, then you could consider putting them in a hash table or sorting them into the same order as the data file to make it possible to test more efficiently for matches.

Why is the data write not reflected to the file using fprintf file stream

This is my program:
#include <stdio.h>
int main() {
FILE *logh;
logh = fopen("/home/user1/data.txt", "a+");
if (logh == NULL)
{
printf("error creating file \n");
return -1;
}
// write some data to the log handle and check if it gets written..
int result = fprintf(logh, "this is some test data \n");
if (result > 0)
printf("write successful \n");
else
printf("couldn't write the data to filesystem \n");
while (1) {
};
fclose(logh);
return 0;
}
When i run this program, i see that the file is getting created but it does not contain any data. what i understand i that there is data caching in memory before the data is actually written to the filesystem to avoid multiple IOs to increase performance. and I also know that i can call fsync/fdatasync inside the program to force a sync. but can i force the sync from outside without having to change the program?
I tried running sync command from Linux shell but it does not make the data to appear on the file. :(
Please help if anybody knows any alternative to do the same.
One useful information: I was researching some more on this and finally found this, to remove internal buffering altogether, the FILE mode can be set to _IONBF using int setvbuf(FILE *stream, char *buf, int mode, size_t size)
The IO functions usingFILE pointers cache the data to be written in an internal buffer within the program's memory until they decide to perform a system call to 'really' write it (which is for normal files usually when the size of the data cached reaches BUFSIZ).
Until then, there is no way to force writing from outside the progam.
The problem is that your program does not close the file because of your while statement. Remove these lines:
while (1) {
};
If the intent is to wait forever, then close the file with fclose before executing the while statement.

How to write an array to file in C

I have a 2 dimensional matrix:
char clientdata[12][128];
What is the best way to write the contents to a file? I need to constantly update this text file so on every write the previous data in the file is cleared.
Since the size of the data is fixed, one simple way of writing this entire array into a file is using the binary writing mode:
FILE *f = fopen("client.data", "wb");
fwrite(clientdata, sizeof(char), sizeof(clientdata), f);
fclose(f);
This writes out the whole 2D array at once, writing over the content of the file that has been there previously.
I would rather add a test to make it robust !
The fclose() is done in either cases otherwise the file system will free the file descriptor
int written = 0;
FILE *f = fopen("client.data", "wb");
written = fwrite(clientdata, sizeof(char), sizeof(clientdata), f);
if (written == 0) {
printf("Error during writing to file !");
}
fclose(f);
How incredibly simple this issue turned out to be...
The example given above handle characters, this is how to handle an array of integers...
/* define array, counter, and file name, and open the file */
int unsigned n, prime[1000000];
FILE *fp;
fp=fopen("/Users/Robert/Prime/Data100","w");
prime[0] = 1; /* fist prime is One, a given, so set it */
/* do Prime calculation here and store each new prime found in the array */
prime[pn] = n;
/* when search for primes is complete write the entire array to file */
fwrite(prime,sizeof(prime),1,fp); /* Write to File */
/* To verify data has been properly written to file... */
fread(prime,sizeof(prime),1,fp); /* read the entire file into the array */
printf("Prime extracted from file Data100: %10d \n",prime[78485]); /* verify data written */
/* in this example, the 78,485th prime found, value 999,773. */
For anyone else looking for guidance on C programming, this site is excellent...
Refer: [https://overiq.com/c-programming/101/fwrite-function-in-c/

File IO does not appear to be reading correctly

Disclaimer: this is for an assignment. I am not asking for explicit code. Rather, I only ask for enough help that I may understand my problem and correct it myself.
I am attempting to recreate the Unix ar utility as per a homework assignment. The majority of this assignment deals with file IO in C, and other parts deal with system calls, etc..
In this instance, I intend to create a simple listing of all the files within the archive. I have not gotten far, as you may notice. The plan is relatively simple: read each file header from an archive file and print only the value held in ar_hdr.ar_name. The rest of the fields will be skipped over via fseek(), including the file data, until another file is reached, at which point the process begins again. If EOF is reached, the function simply terminates.
I have little experience with file IO, so I am already at a disadvantage with this assignment. I have done my best to research proper ways of achieving my goals, and I believe I have implemented them to the best of my ability. That said, there appears to be something wrong with my implementation. The data from the archive file does not seem to be read, or at least stored as a variable. Here's my code:
struct ar_hdr
{
char ar_name[16]; /* name */
char ar_date[12]; /* modification time */
char ar_uid[6]; /* user id */
char ar_gid[6]; /* group id */
char ar_mode[8]; /* octal file permissions */
char ar_size[10]; /* size in bytes */
};
void table()
{
FILE *stream;
char str[sizeof(struct ar_hdr)];
struct ar_hdr temp;
stream = fopen("archive.txt", "r");
if (stream == 0)
{
perror("error");
exit(0);
}
while (fgets(str, sizeof(str), stream) != NULL)
{
fscanf(stream, "%[^\t]", temp.ar_name);
printf("%s\n", temp.ar_name);
}
if (feof(stream))
{
// hit end of file
printf("End of file reached\n");
}
else
{
// other error interrupted the read
printf("Error: feed interrupted unexpectedly\n");
}
fclose(stream);
}
At this point, I only want to be able to read the data correctly. I will work on seeking the next file after that has been finished. I would like to reiterate my point, however, that I'm not asking for explicit code - I need to learn this stuff and having someone provide me with working code won't do that.
You've defined a char buffer named str to hold your data, but you are accessing it from a separate memory ar_hdr structure named temp. As well, you are reading binary data as a string which will break because of embedded nulls.
You need to read as binary data and either change temp to be a pointer to str or read directly into temp using something like:
ret=fread(&temp,sizeof(temp),1,stream);
(look at the doco for fread - my C is too rusty to be sure of that). Make sure you check and use the return value.

Resources