======Data Structures Journal====== =====Week 1===== - Being that this is the first week of class, I have been given the assignment to re-familiarize myself with last semesters concepts. - I signed up for the mailing list at [[http://lab46.corning-cc.edu/mailman/listinfo/DATA]] - Joined the Irssi channel using /join csci * I submitted the first "PROJECT", "PROJECT INTRO" using the following lab46:~$ submit data intro http://lab46.corning-cc.edu/opus/spring2014/jkosty6/start Submitting data project "intro": -> http://lab46.corning-cc.edu/opus/spring2014/jkosty6/start(OK) SUCCESSFULLY SUBMITTED lab46:~$ ===Project Datatypes=== ==Scope== * We had to write a program that would display in standard output - Size in bytes - low bounds - upper bounds - total quantity of possible values * This needed to be done for signed and unsigned versions of - char - short int - int - long int - long long int * The program needed to make use of fprintf() and sizeof() ==Results== * Using the provided code, I was able to get a working version of the program. * I had to look back at last semesters version of this program to get a feel for it again * This is how it looks when run lab46:~/src/datastruct$ ./datatypes TYPE: unsigned char, bytes: 1, low: 0, high: 255, qty: 256 TYPE: signed char, bytes: 1, low: -128, high: 127, qty: 256 TYPE: unsigned short int, bytes: 2, low: 0, high: 65535, qty: 65536 TYPE: signed short int, bytes: 2, low: -32768, high: 32767, qty: 65536 TYPE: unsigned int, bytes: 4, low: 0, high: 4294967295, qty: 4294967296 TYPE: signed int, bytes: 4, low: -2147483648, high: 2147483647, qty: 4294967296 TYPE: unsigned long int, bytes: 8, low: 0, high: 18446744073709551615, qty: 18446744073709551615 +1 that I cant display TYPE: signed long int, bytes: 8, low: -9223372036854775808, high: 9223372036854775807, qty: 18446744073709551615 +1 that I cant display TYPE: unsigned long long int, bytes: 8, low: 0, high: 18446744073709551615, qty: 18446744073709551615 +1 that I cant display TYPE: signed long long int, bytes: 8, low: -9223372036854775808, high: 9223372036854775807, qty: 18446744073709551615 +1 that I cant display lab46:~/src/datastruct$ * As shown in the results, I was unable to display the real total quantity for long types. * 64 bit systems can only store a max of 2^64 which is 18446744073709551615 or a unsigned long long * I really doubt there is a way around this without splitting the string in some way. ==Reflection== * Throughout the project, I found two data types to appear the same. Long Long and Long Signed and unsigned values * This more than likely is due to the architecture of the system being 64 bits and Long and Long Long seem change their values with the architecture * This is not universal since on (most?)(all?) 32 bit system(s) a long would be the same size as an int. * If I had to guess, I would imagine it is this way so that things would be near universal no matter what architecture was chosen * Printf * fprintf - sends its output to what ever output stream is specified * printf - sends its output by default to the standard output stream * stdout - the default output location for applications. The default location for the stdout is the current screen * %s - format specifier for character strings * %hhu - format for unsigned short short int, or char * %hu - format for unsigned short int * %u - format for unsigned int * %d - format for signed int * %13s - Specifies how many spaces to provide to a given output string * Sign * If the sign is left unspecified it defaults to positive / unsigned values * & and | * & - bitwise and - Takes 2 values of even length and does a logical AND of bits * | - bitwise or - Takes 2 values of even length and does a logical OR of bits * Through this we were able to get the max and min values of a datatype by getting it to set all values to either 0 , for min, and 1 , for max * Troubles * As stated earlier, I had trouble getting the total quantities for long and long long datatypes. * This was due to the total number of numerical values they can store being 1 larger than their max value (blame zero for being able to store something) * Total Bits For : signed char - 1 unsigned short int - 2 unsigned int - 4 signed int - 4 signed long long int - 8 ==Closing== * This was a fun review. It is quite amazing how much you can forget over Christmas break. Too much pokemon * Submitted the project using lab46:~/src/datastruct$ submit data datatypes datatypes.c Submitting data project "datatypes": -> datatypes.c(OK) SUCCESSFULLY SUBMITTED lab46:~/src/datastruct$ =====Week 2===== ===Node Project=== ==Initial Thoughts== * This kind of seemed a bit overwhelming since its this sort of stuff that I am bad at. ==Pointers== * We learned of the two things in C associated with memory access - * - dereference - & - address of * we declare a pointer using * (example int *var; - a pointer it is a memory variable - we don't store values - we store memory addresses ==Node== * Self Created variable of sorts * nodes are the building blocks of linked lists * a peer to the array * Memory is only allocated a node at a time. * allows a best fit for the data set we are working with. ==Completion== * Worked through the node project, and I was able to get it to run as specified in the assignment sheet. lab46:~/src/datastruct$ ./node Enter a value (-1 to quit): 1 Enter a value (-1 to quit): 3 Enter a value (-1 to quit): 3 Enter a value (-1 to quit): 7 Enter a value (-1 to quit): 5 Enter a value (-1 to quit): 4 Enter a value (-1 to quit): 1 Enter a value (-1 to quit): 7 Enter a value (-1 to quit): -1 1 -> 3 -> 3 -> 7 -> 5 -> 4 -> 1 -> 7 -> NULL lab46:~/src/datastruct$ * WILL POST DIAGRAM ONCE I GET MY SCANNER HOOKED UP =====Week 3 and Week 4===== * I have been working on my nodes project. * I have implimented a few things such as - Remove - Append - Insert - Build List - Node Count - List Nodes * My next step is to break the code up into smaller files. Hopefully by the end of the week * My code so far. Pretty messy /* * node.c - A program to store values using nodes, structs, and pointers * to simulate dynamic memory allocation * * * A program by NAME for CSCS2320 DATA STRUCTURES (SPRING 2014) * * Compile with: gcc -o node node.c * Execute with: ./node */ #include #include struct node{ // set up our struct named node int value; struct node *next; }; typedef struct node Node; // eliminates the need for later use of 'struct' keyword int main(){ int response, search; // value for in which a value is taken for input Node *first=NULL, *tmp=NULL, *tmp2=NULL, *tmp3=NULL; // sets starting values to nothing or Null while (response!=8) { printf("What would you like to do?\n\n1 - List Nodes\n2 - Build List\n3 - Append Nodes\n4 - Insert Before Nodes\n5 - Remove Node\n6 - Count Node Quantity\n8 - Quit \n\n"); scanf("%d", &response); if (response==1) { if(first!=NULL) { tmp3=tmp; tmp=first; // I couldnt get my code to work for a long time until I int position = 0; // the initial value for the node counter do { printf("[%d] ", position); // displays the numerical value of the node currently displayed printf("%d -> ", tmp->value); //prints out the value of the element value tmp=tmp->next; // sets tmp to the next element position++; } while(tmp!=NULL); // only loop if doesnt equal null printf("NULL\n\n"); // prints null if tmp null tmp=tmp3; } else { printf("\nNo values exist\n\n"); } } else if (response==2) { while(response!=-1) // if -1 is not typed then the loop continues { printf("Enter a value (-1 to quit): "); //prompt user for input scanf("%d", &response); // take numerical input and store in response if(response != -1) // if response is not negative 1 { if(first == NULL) //checks to see if first is pointing yet { first = (Node *) malloc (sizeof(Node)); // sets the pointer to the pointe and how much memory is allocated tmp = first; // makes tmp point to the same pointe as first tmp -> value = response; // tmp uses a pointer to set the element of value equal to response tmp -> next = NULL; // sets the objects next property to null value } else // after first points to a pointe, all things go through this statement { tmp -> next = (Node *) malloc (sizeof(Node)); // allocates memory to the next element in the node tmp = tmp -> next; // sees to set tmp to the next element tmp -> value = response; // struct tmp uses a pointer to set the element value equal to response tmp -> next = NULL; // sets next to null - important for breaking loop during the printf } } } } else if (response==3) //append node { printf("Which node would you like to append? : "); scanf("%d", &response); tmp3=tmp; tmp=first; { for(search=0; search<(response); search++) { tmp=tmp->next; } printf("Enter value for appended node: "); scanf("%d", &response); tmp2=(Node*)malloc(sizeof(Node)); tmp2->value=response; tmp2->next=tmp->next; tmp->next=tmp2; tmp=first; } tmp=tmp3; } else if (response==4) //insert node { printf("Which node would you like to insert before?: "); scanf("%d", &response); tmp3=tmp; tmp=first; { for(search=0; search<(response-1); search++) { tmp=tmp->next; } if(response==0) { printf("Enter value for inserted node: "); scanf("%d", &response); tmp2=(Node*)malloc(sizeof(Node)); tmp2->value=response; tmp2->next=NULL; tmp2->next=tmp; first=tmp2; } else { printf("Enter value for inserted node: "); scanf("%d", &response); tmp2=(Node*)malloc(sizeof(Node)); tmp2->value=response; tmp2->next=tmp->next; tmp->next=tmp2; } tmp=first; } tmp=tmp3; } else if (response==5) //remove node { printf("Which node to Remove: "); scanf("%d", &response); tmp3=tmp; tmp=first; { for(search=0; search<(response-1);search++) { tmp=tmp->next; } if(response==0) { tmp2=tmp->next; tmp->next=NULL; first=tmp2; } else { tmp2=tmp->next; tmp->next=tmp2->next; tmp2->next=NULL; } tmp=first; response=0; } tmp=tmp3; } else if (response==6) { if(first!=NULL) { tmp3=tmp; tmp=first; int position = 0; do { tmp=tmp->next; // sets tmp to the next element position++; } while(tmp!=NULL); printf("%d Nodes in list. \n\n", position); tmp=tmp3; } else { printf("\nNo values exist\n\n"); } } } return(0); } =====March 4th 2014===== * I am able to compile all of my list functions, but the tests all fail. I must be missing something, or maybe I am doing it completely wrong. Who knows. ===Append.c=== #include "list.h" // append() - append newNode after place in myList // List *append(List *myList, Node *place, Node *newNode) { Node *temp=myList->end; { if(place==temp) { newNode->next=NULL; place->next=newNode; myList->end=newNode; } else { newNode->next=place->next; place->next=newNode; } } myList->qty++; return(myList); } ===Cp.c=== #include "list.h" // Duplicate an existing list // List *cplist(List *myList) { List *tmpList = NULL; Node *tmp = myList -> start; tmpList = mklist(); while (tmp -> next != NULL) { tmpList = append(tmpList, tmpList -> end, cpnode(tmp)); tmp = tmp -> next; } return(tmpList); } ===Display.c=== #include "list.h" #include // displayf() - display the list forward from start to end // void displayf(List *myList) { Node *temp=(myList->start); int check=0; while(temp !=NULL) { fprintf(stdout, "[%d] %d -> ", check, temp->value); temp=temp->next; check++; } fprintf(stdout, "NULL\n"); } // displayb() - display the list in reverse // void displayb(List *myList) { Node *temp; int printcount=0; int nodecount=myList->qty; fprintf(stdout, "NULL\n"); while(nodecount >= 0) { temp=myList->start; while (printcount < nodecount) { temp=temp->next; printcount++; } fprintf(stdout, "[%d] %d -> ", nodecount, temp->value); printcount=0; nodecount--; } } ===Getnode.c=== #include "list.h" // getNode() - take indicated node out of list // List *getNode(List *myList, Node **tmp) { Node *temp; int position = getpos(myList, *tmp); temp = setpos(myList, position-1); if(myList->start->next==NULL) { myList->start=NULL; } else if(*tmp==myList->start) { myList->start=myList->start->next; } else if(*tmp==myList->end) { myList->end=temp; myList->end->next=NULL; } else { temp->next=(*tmp)->next; } myList->qty--; return(myList); } ===Insert.c=== #include "list.h" // insert() - insert newNode before place in myList // List *insert(List *myList, Node *place, Node *newNode) { Node *temp; int position; position = getpos(myList, place); temp=setpos(myList, position-1); if(place==myList->start) { newNode->next=place; myList->start=newNode; } else { newNode->next=place; temp->next=newNode; } myList->qty++; return(myList); } ===Mk.c=== #include "list.h" List *mklist() { List *tmp = (List *) malloc (sizeof(List)); tmp -> start = NULL; tmp -> end = NULL; tmp -> qty = 0; return(tmp); } ===Pos.c=== #include "list.h" // Get the numerical node position (0 being first node) // int getpos(List *myList, Node *tmp) { Node *tmp2; tmp2=tmp; int nodecount=myList->qty-1; while(tmp2->next!=NULL) { tmp2=tmp2->next; nodecount--; } // } return(nodecount); } // Set a pointer to a numerical node position (0 being first node) // Node *setpos(List *myList, int pos) { Node *tmp; tmp = myList->start; int check=0; while(tmp!=NULL) { if (check!=pos) { tmp=tmp->next; check++; } else { break; } } return(tmp); } ===Rm.c=== #include "list.h" List *rmlist(List *myList) { Node *tmp = myList->start; //set tmp to the start of the list Node *tmp2; //set up a extra pointer int count=0; //set up a counter while(tmp != NULL) //while tmp doesnt equal null { tmp = tmp->next;//cycle through the nodes count++; } tmp = myList->start; //set tmp to the start of the list for(; count>0; count--) //while count is greater than 0 do then reduce by 1 { if(tmp == myList->end) //if tmp is the end of the list { myList->end = NULL; //the end of the list is null myList->start = NULL; //the start of the list is null free(tmp); //free the pointer } else { tmp2 = tmp->next; //set tmp2 to the value of tmp next tmp->next = NULL; //set tmp next to the value null myList->start = tmp2; //set the beginining of the list to tmp2 free(tmp);//free tmps valuye tmp = tmp2; //set the value of tmp to tmp2 } } myList->qty = 0; //set the nodeqt to 0 return(myList); } ===Search.c=== #include "list.h" Node *searchlist(List *myList, int test) { Node *tmp; tmp = myList->start; ///set tmp to the pointer start while(tmp!=NULL) //while the node doesnt equal null { int baz = tmp->value; //set the variable baz to the value of the node if (baz != test) //if the variable doesnt equal the value { tmp=tmp->next; //cycle nodes } else //if it doesnt equal { break; //break loop } } return(tmp); // to be implemented } ===Sort.c=== #include "list.h" // Sort list based on mode // modes are: // 0 - least to greatest // 1 - greatest to least // 2 - reverse current order // List *sortlist(List *myList, int mode) { Node *tmp; Node *tmp2; tmp = myList->start; Node *highest; Node *lowest; int behind; int count = myList->qty; int first = count; if (mode == 0) { while (first >1) { tmp = myList->start; //set tmp to the start tmp2 = myList->start; //set tmp2 to the start highest = tmp; //seet high checker to the stat while( count>0) //while node count doesnt equal zero { if(highest->value < tmp2->value) //check which value is higher { highest = tmp2; //set the higher value to highest } tmp2 = tmp2->next;//cycle tmp count--; //reduce counter } myList = getNode(myList, &highest); //grab node highest tmp = myList->start; //set tmp to the start for(behind = 0; behind<(first-2); behind++) ////loop for node placement { tmp = tmp->next; //cycle to proper node } myList = append(myList, tmp, highest); //readd in highesty node first--; //reduce first by one } return(myList); } else if (mode ==1) //same as before { while (first >1) { tmp = myList->start; tmp2 = myList->start; lowest = tmp; while( count>0) { if(lowest->value > tmp2->value) //check for lower of two values { lowest = tmp2; } tmp2 = tmp2->next; count--; } myList = getNode(myList, &lowest); tmp = myList->start; for(behind = 0; behind<(first-2); behind++) { tmp = tmp->next; } myList = append(myList, tmp, lowest); first--; } return(myList); } else if (mode ==2) { List *tmpList = NULL; Node *tmp=myList->start; tmpList = mklist(); while (tmp != NULL) { tmpList = insert(tmpList, tmpList -> start, cpnode(tmp)); tmp = tmp -> next; } return(tmpList); } } ===Swap.c=== #include "list.h" // Swap two nodes in a list (not values, but nodes) // List *swapnode(List *myList, Node *tmp, Node *tmp2) { int tmp1check = getpos(myList, tmp); //get the position of tmp in the liist int tmp2check = getpos(myList, tmp2); //get the position of the tmp2 in the list Node *tmpprev; Node *tmp2prev; Node *temp; tmpprev=setpos(myList, tmp1check-1);//point to the node before tmp1 tmp2prev=setpos(myList, tmp2check-1); //point to the node before tmp2 temp=tmp; if (tmp != myList->start) { tmpprev->next=tmp2; //set tmp previous next to tmp2 } if (tmp2 != myList->start) { tmp2prev->next=tmp; //set tmp2previous next to tmp } tmp->next=tmp2->next; //set the old tmps next to tmp 2 next tmp2->next=temp; return(myList); } =====March 24th 2014===== * I believe I completed the stack project correctly. I couldnt get the test program to work though. ===peek.c=== #include "stack.h" Node *peek(Stack *myStack) { // exercise left to the implementer return(myStack->top); } ===push.c=== #include "stack.h" Stack *push(Stack *myStack, Node *newNode) { if ((myStack->size<=0) || ((myStack->data->qty) < (myStack->size))) //check to see how many are in stack { myStack->data=append(myStack->data,myStack->data->end,newNode); //add node to end of list myStack->top=myStack->data->end; //set top to the end of the list } return(myStack); } ===pop.c=== #include "stack.h" Node *pop(Stack **myStack) { Node *temp = NULL; if ((*myStack)!=NULL) //checks to see if stack is empty { temp=(*myStack)->data->end; //sets temp to the end of the list (*myStack)->data=getNode((*myStack)->data,(&temp)); //removes the node from the top of the list (*myStack)->top=(*myStack)->data->end; //set the new top to the new end of list } return (temp); } =====March 27th 2014===== * Started working on the double linked list * adding prev to most of the functions fixed problems I had with node count * the parts that I do have changed seemed to work fine ===append.c=== #include "list.h" // append() - append newNode after place in myList // List *append(List *myList, Node *place, Node *newNode) { Node *temp=myList->end; { if(myList->qty==0) { newNode->prev=NULL; newNode->next=NULL; myList->end=newNode; myList->start=newNode; myList->qty++; //increase the quantity of nodes by 1 due to adding a node } else if(place==temp) { newNode->prev=place; place->next=newNode; // the current places next is the new node newNode->next=NULL; //The newnode's next points to NULL myList->end=newNode; //the new node is the end of the list myList->qty++; //increase the quantity of nodes by 1 due to adding a node } else { newNode->prev=place; place->next->prev=newNode; newNode->next=place->next;//the new nodes next points to where the current place points place->next=newNode; //set the current places next to the new node myList->qty++; //increase the quantity of nodes by 1 due to adding a node } } return(myList); } ===insert.c=== #include "list.h" // insert() - insert newNode before place in myList // List *insert(List *myList, Node *place, Node *newNode) { if(myList->qty == 0) { newNode->next=NULL; newNode->prev=NULL;///// myList->start=newNode; myList->end=newNode; myList->qty++; // the qty of the list is increased by one } else if(place==myList->start) // if the current place is the start, the new node is { newNode->next=place; //the new nodes next is the place place->prev=newNode; newNode->prev=NULL; myList->start=newNode; //the start of the list is the new node myList->qty++; // the qty of the list is increased by one } else { newNode->next=place; // the new nodes next value si place place->prev->next=newNode; newNode->prev=place->prev; place->prev=newNode; myList->qty++; // the qty of the list is increased by one } return(myList); } ===getnode.c=== #include "list.h" // getNode() - take indicated node out of list // List *getNode(List *myList, Node **tmp) { Node *temp; int position = getpos(myList, *tmp); temp = setpos(myList, position-1); int nodec = myList->qty; if(nodec <= 1) // if the current spot is the end and the beginining { myList->start=NULL; //set the start to null myList->end=NULL; nodec = 0; } else if(*tmp==myList->start) // if the position of the current node is at the start { myList->start=myList->start->next; //set the start node to the old next myList->start->prev=NULL; (*tmp)->next=NULL; nodec--; } else if(*tmp==myList->end) // if the node being removed is at the end of the list { myList->end=myList->end->prev; //set the end of the list to that of temp, or "prev" myList->end->next=NULL; // set the next of the list to NULL since it is the end of the list (*tmp)->prev=NULL; nodec--; } else { (*tmp)->prev->next=(*tmp)->next; (*tmp)->next->prev=(*tmp)->prev; (*tmp)->prev=(*tmp)->next=NULL; nodec--; } myList->qty=nodec; return(myList); } ===Things left to do=== * I believe the things left to change to double linked are - rm.c for lists - sort.c - swap.c * I need to start the queues eventually too =====April 9th 2014===== I seem to have gotten the doubly versions of a few more functions to work. The test programs all work ===swap.c=== #include "list.h" // Swap two nodes in a list (not values, but nodes) // List *swapnode(List *myList, Node *tmp, Node *tmp2) { Node *tmp1c; Node *tmp2c; tmp1c=tmp->next; tmp2c=tmp2->prev; if (tmp != myList->start) { tmp->prev->next=tmp2; tmp2->prev=tmp->prev; } if (tmp2 != myList->start) { tmp2c->next=tmp; //set tmp2previous next to tmp tmp->prev=tmp2c; } tmp->next=tmp2->next; //set the old tmps next to tmp 2 next tmp2->next=tmp1c; return(myList); } * Ironically I believe that the way I implemented my code with the last project has lead to me not needing to change anything else. The tests all function perfectly with only the 4 or 5 function changes ===things left to do=== * I have to get queues to work right ======Systems Programming Journal====== =====January,21st 2014===== * Today being the first day of class, we re-familiarized ourselves with C programming. * We wrote a program that could read the values within a file, and insert them into an array #include #include int main() { FILE *fptr; //file pointer named fptr int *data; //make pointer inside of data int i, count=0, j; fptr=fopen("data.txt","r"); if(fptr==NULL) { fprintf(stdout,"Error Opening File!\n"); exit(1); } while(fscanf(fptr,"%d",&i) !=EOF) { // fprintf(stdout,"%d\n",i); //Debugging statement count++; } fclose(fptr); //close the file using fclose fptr=fopen("data.txt","r"); data=(int*)malloc(sizeof(int)*count); for(i=0; i * Running the program would output our file exactly how we had it. As long as the file only contained numbers =====January,22nd 2014===== * Started Reading through the book "Understanding Unix/Linux Programing" * I will be listing the exercises throughout the book as I come to them ===Chapter 1=== ==Stdio program== The first program we come accross in the book is one that takes from standard input and puts it in standard output #include #include /*copy from stdin to stdout */ main() { int c; while ( ( c = getchar() ) != EOF ) putchar(c); } ==New understanding== * This chapter really helped me get a clear understanding of just what a kernel is. I never really knew, which is kind of sad. * This chapter also exposed me to the calculator "bc". I am sure I will be making good use of that soon enough. Though the book says bc is not a calculator. I will need to look into this more * So bc is a translator like process for dc which is the actual calculator ==More Command== * The second program the book has us make is our own "More command" /* more01.c - version 0.1 of more * read and print 24 lnes then pause for a few special commands */ #include #define PAGELEN 24 #define LINELEN 512 void do_more(FILE *); int see_more(); int main ( int ac , char *av[] ) { FILE *fp; if ( ac == 1 ) do_more( stdin ); else while ( --ac ) if ( (fp = fopen( *++av , "r" )) != NULL ) { do_more( fp ) ; fclose( fp ); } else exit(1); return 0; } void do_more( FILE *fp ) /* *read pagelen lines then call see_more for further instructions */ { char line[LINELEN]; int num_of_lines = 0; int see_more(), reply; while ( fgets( line, LINELEN, fp ) ){ // more input if ( num_of_lines == PAGELEN ) { // full screen? reply = see_more(); // y: ask user if ( reply == 0 ) // n: done break; num_of_lines -= reply; // reset count } if ( fputs( line, stdout ) == EOF ) // show line exit(1); // or die num_of_lines++; // count it } } int see_more() /* *print message, wait for reponse, return # of lines to advance *q means no, space means yes, cr means one line */ { int c; printf("\033[7m more? \033[m"); // reverse on a vt100 while( (c=getchar()) !=EOF ) // get response { if ( c == 'q' ) // g -> N return 0; if ( c == ' ' ) // ' ' => nest page return PAGELEN; // home many to show if ( c == '\n' ) // enter key => 1 line return 1; } return 0; } * The program works just like the built in "more" command. * There are a few issues though. * q doesnt quit until enter is pressed * space doesnt skip a page unless enter is pressed * We can create a version 2 program that takes from standard input /* more01.c - version 0.1 of more * read and print 24 lnes then pause for a few special commands * feature of version reads directly from dev tty for commands */ #include #define PAGELEN 24 #define LINELEN 512 void do_more(FILE *); int see_more(); int main ( int ac , char *av[] ) { FILE *fp; if ( ac == 1 ) do_more( stdin ); else while ( --ac ) if ( (fp = fopen( *++av , "r" )) != NULL ) { do_more( fp ) ; fclose( fp ); } else exit(1); return 0; } void do_more( FILE *fp ) /* *read pagelen lines then call see_more for further instructions */ { char line[LINELEN]; int num_of_lines = 0; int see_more(), reply; FILE *fp_tty; fp_tty = fopen( "/dev/tty", "r" ); // new : CMD Stream if ( fp_tty == NULL ) // if open fails exit(1); // no use in running while ( fgets( line, LINELEN, fp ) ){ // more input if ( num_of_lines == PAGELEN ) { // full screen? reply = see_more(fp_tty); // y: ask user if ( reply == 0 ) // n: done break; num_of_lines -= reply; // reset count } if ( fputs( line, stdout ) == EOF ) // show line exit(1); // or die num_of_lines++; // count it } } int see_more(FILE *cmd) //new accepts arg /* *print message, wait for reponse, return # of lines to advance *q means no, space means yes, cr means one line */ { int c; printf("\033[7m more? \033[m"); // reverse on a vt100 while( (c=getc(cmd)) !=EOF ) // read from tty { if ( c == 'q' ) // g -> N return 0; if ( c == ' ' ) // ' ' => nest page return PAGELEN; // home many to show if ( c == '\n' ) // enter key => 1 line return 1; } return 0; } == Thoughts on chapter 1== * I really like this book so far. * It was nice to finally be able to understand how the different software systems of unix are actually written * I couldnt wrap my head around it for a long time, but writing the more program really gave me insight =====January,23rd 2014===== * Today we worked to improve our program * The program can now accept command line arguments * If we ./program-name file-name , the program will read the file "file-name" and output the values into out.txt #include #include int main(int argc, char **argv) //argc = argument count from command line //argv = is the string of the argument contains what it is { FILE *fptr; //file pointer named fptr int *data; //make pointer inside of data int i, count=0, j, low, pos; char filename[20]; if (argc==1) { sprintf(filename, "data txt"); //sprintf = string print } else { sprintf(filename, "%s", argv[1]); } fptr=fopen(filename,"r"); if(fptr==NULL) { fprintf(stdout,"Error Opening File!\n"); exit(1); } while(fscanf(fptr,"%d",&i) !=EOF) { count++; } fclose(fptr); //close the file using fclose fptr=fopen(filename,"r"); data=(int*)malloc(sizeof(int)*count); for(i=0; i2) { sprintf(filename,"%s",argv[2]); } else { sprintf(filename,"out.txt"); } if((fptr=fopen(filename,"w"))==NULL) //define output file (w is for write) { fprintf(stderr,"Error open my file for work\n"); exit(2); } for(i=0;i =====January,27th - 28th 2014===== ===Chapter 2=== * I decided to continue my reading through the book * This chapter seems to be focusing on users, files, and random commands I use all the time such as man who cp login. =====February, 3rd 2014===== ===Group of=== * Have been working non stop on the "group of" project. * Take commands - ./groupof -a SINGULARNAME -g GROUPNAME ~ adds new entries to the animal.txt file - ./groupof -l ~ lists entries - ./groupof -e ~ counts number of entries - ./groupof -v SINGULARNAME ~ gives you the group name of the singular name - ./groupof -h ~ gives you a list of some of the basic commands #include /* for printf */ #include /* for exit */ #include #include int main(int argc, char ** argv) { int c, aflag, gflag; unsigned long count = 0; FILE *fptr; int digit_optind = 0; int line_num = 1; int find_result = 0; char tempstring[30]; while (1) { int this_option_optind = optind ? optind : 1; int option_index = 0; static struct option long_options[] = { {"add-animal", 1, 0, 'a'}, {"add-group", 1, 0, 'g'}, {"list", 0, 0, 'l'}, {"help", 0, 0, 'h'}, {"entries", 0, 0, 'e'}, {"verbose", 1, 0, 'v'}, {0, 0, 0, 0} }; c = getopt_long(argc, argv, "a:g:lchev:", long_options, &option_index); if(c == -1) break; switch (c) { case 'a': if (argc > 4) { if (strcmp(argv[3], "-g") == 0) { fptr=fopen("animal.txt","r"); while(fgets(tempstring, 30, fptr) != NULL) { if((strstr(tempstring, argv[2])) != NULL) { printf("\nEntry "); printf ("%s ", optarg); printf("already exists, and its group is "); printf("%s\n", &(tempstring[strlen(optarg)+1])); find_result++; break; } } fclose(fptr); if(find_result == 0) { aflag = 1; fptr=fopen("animal.txt","a"); fprintf(fptr, "%s,", optarg); fclose(fptr); break; } } else { gflag = 1; printf("Please enter your animal in the following format.\n -a animalname -g groupname\n"); break; } } else { gflag = 1; printf("Please enter your animal in the following format.\n -a animalname -g groupname\n"); break; } case 'g': if (aflag == 0) { if (gflag == 1) { } else if (gflag = 0) { printf("Please enter your animal in the following format.\n -a animalname -g groupname\n"); } } else if (aflag ==1) { fptr=fopen("animal.txt","a"); fprintf(fptr, "%s\n", optarg); fclose(fptr); } break; case 'l': fptr=fopen("animal.txt","r"); if (fptr) { while ((c = getc(fptr)) != EOF) putchar(c); } fclose(fptr); break; case 'h': printf("\nGroup of tool. \n"); printf("=========================================================================\n"); printf("Add animal with -a ANIMAL-NAME -g GROUP-NAME.\n"); printf("List entries with -l \n"); printf("Count entries with -e\n"); printf("=========================================================================\n"); break; case 'e': fptr=fopen("animal.txt","r"); if (fptr) { while ((c = getc(fptr)) != EOF) { if ( c == '\n' ) { count++; } } } fclose(fptr); printf("%lu total entries.\n", count); break; case 'v': fptr=fopen("animal.txt","r"); strcat(optarg, ","); while(fgets(tempstring, 30, fptr) != NULL) { if((strstr(tempstring, argv[2])) != NULL) { printf("\nA group of "); printf ("%.*s" ,strlen(argv[2])-1, optarg); printf(" is a "); printf("%s\n", &(tempstring[strlen(optarg)])); find_result++; } } if(find_result == 0) { printf("\nNo Matches Found.\n"); } fclose(fptr); break; case '?': printf("option ? with value '%s'\n", optarg); break; default: printf("?? getopt returned character code 0%o ??\n", c); } } exit(EXIT_SUCCESS); } * Definitely not finished and is still very basic. * Will add commented version later on =====February, 11th 2014===== ===PWD Command=== * Read through chapter 4 and created the pwd command for class. * It doesnt work right, but I imagine it will after class /* spwd.c: a simplified version of pwd * * starts in current directory and recursively * climbs up to root of filesystem, prints top part * then prints current part * * uses readdir() to get info about each thing * * bug: prints an empty string if run from "/" **/ #include #include #include #include #include #include ino_t get_inode(char *); void printpathto(ino_t); void inum_to_name(ino_t , char *, int ); int main() { printpathto( get_inode( "." ) ); /* print path to here */ putchar('\n'); /* then add newline */ return 0; } void printpathto( ino_t this_inode ) /* * prints path leading down to an object with this inode * kindof recursive */ { ino_t my_inode ; char its_name[BUFSIZ]; if ( get_inode("..") != this_inode ) { chdir( ".." ); /* up one dir */ inum_to_name(this_inode,its_name,BUFSIZ);/* get its name*/ my_inode = get_inode( "." ); /* print head */ printpathto( my_inode ); /* recursively */ printf("/%s", its_name ); /* now print */ /* name of this */ } } void inum_to_name(ino_t inode_to_find , char *namebuf, int buflen) /* * looks through current directory for a file with this inode * number and copies its name into namebuf */ { DIR *dir_ptr; /* the directory */ struct dirent *direntp; /* each entry */ dir_ptr = opendir( "." ); if ( dir_ptr == NULL ){ perror( "." ); exit(1); } /* * search directory for a file with specified inum */ while ( ( direntp = readdir( dir_ptr ) ) != NULL ) if ( direntp->d_ino == inode_to_find ) { strncpy( namebuf, direntp->d_name, buflen); namebuf[buflen-1] = '\0'; /* just in case */ closedir( dir_ptr ); return; } fprintf(stderr, "error looking for inum %d\n", inode_to_find); exit(1); } ino_t get_inode( char *fname ) /* * returns inode number of the file */ { struct stat info; if ( stat( fname , &info ) == -1 ){ fprintf(stderr, "Cannot stat "); perror(fname); exit(1); } return info.st_ino; } * Code worked after adding the correct header files. * Program needed to be placed into a different folder or ran off of a bare metal linux installation or else it would not run. * This is due to the way that the virtual machine that lab 46 runs on has its file system ===LS Command=== * We created this program a few classes ago but I forgot to put it up #include #include #include void process ( char *); int main ( int argc, char **argv) { if( argc == 1) process("."); else { while (--argc) { fprintf(stdout, "%s:\n", *++argv); process( *argv); } } return(0); } void process( char *dirname) { DIR *dirPtr; struct dirent *direntp; if((dirPtr = opendir(dirname))==NULL) fprintf(stderr, "ls: cannot open %s \n", dirname); else { while((direntp = readdir(dirPtr))!=NULL) { fprintf(stdout, "name: %s, reclen: %hu, type: %hhu\n", direntp -> d_name, direntp -> d_reclen, direntp-> d_type); } closedir(dirPtr); } } * Works pretty much like regular LS does ===CHMOD Command=== * We created a chmod program #include #include #include #include #include int main ( int argc, char **argv) { if (argc != 3) { fprintf(stderr, "%s: missing operand\n" , argv[0]); exit(1); } if(chmod(argv[2], strtol(argv[1], NULL, 8)) < 0) /*strtol is string to long integer*/ { fprintf(stderr, "%s: error in chmod(%s, %s) - %d (%s)\n", argv[0], argv[2], argv[1], errno, strerror(errno)); exit(1); } return(0); } =====February, 20th 2014===== * Started work on the matrix multiplier last week in class. * Finished a basic functioning version of it. * Next Step is to add command line arguments. #include int main() { int matrix1[80][80], matrix2[80][80]; int counter1,counter2,counter3,dispcounter=0; int row1, column1, row2, column2; int matrixokay=0, output; while(matrixokay != 1) { printf("\n"); printf("Please Enter Row Count For Matrix One : "); scanf("%d", &row1); printf("Please Enter Column Count For Matrix One : "); scanf("%d", &column1); printf("Please Enter Row Count For Matrix Two : "); scanf("%d", &row2); printf("Please Enter Column Count For Matrix Two : "); scanf("%d", &column2); printf("\n"); if (column1 != row2) { printf("\n\nERROR!\n\n"); printf("Matrix 1 has a column value of %d, ", column1); printf("and it is unequal to the Matrix 2 row value of %d.\n", row2); printf("Please re-enter the row and column values for matrix 1 and 2\n\n\n"); } else { matrixokay++; } } printf("Please Enter Numbers For Matrix One\n"); for(counter1=0;counter1 9 && dispcounter < 20) { printf("%dth Value : ", dispcounter); } else if (dispcounter % 10 == 1) { printf("%dst Value : ", dispcounter); } else if (dispcounter % 10 == 2) { printf("%dnd Value : ", dispcounter); } else if (dispcounter % 10 == 3) { printf("%drd Value : ", dispcounter); } else { printf("%dth Value : ", dispcounter); } scanf("%d", &matrix1[counter1][counter2]); } } printf("\nPlease Enter Numbers For Matrix Two\n"); dispcounter=0; for(counter1=0;counter1 9 && dispcounter < 20) { printf("%dth Value : ", dispcounter); } else if (dispcounter % 10 == 1) { printf("%dst Value : ", dispcounter); } else if (dispcounter % 10 == 2) { printf("%dnd Value : ", dispcounter); } else if (dispcounter % 10 == 3) { printf("%drd Value : ", dispcounter); } else { printf("%dth Value : ", dispcounter); } scanf("%d", &matrix2[counter1][counter2]); } } printf ("\nResult is \n"); for(counter1=0;counter1 =====February, 24th 2014===== ====Group Of==== * I believe I am almost completely if not completely done with the group of project * I could probably add in some error statements but I have complete functionality otherwise #include /* for printf */ #include /* for exit */ #include #include int main(int argc, char ** argv) { int c; int aflag = 0; unsigned long count = 0; FILE *fptr; int digit_optind = 0; int line_num = 1; int find_result = 0; char tempstring[30]; while (1) { int this_option_optind = optind ? optind : 1; int option_index = 0; static struct option long_options[] = { {"add-animal", 1, 0, 'a'}, {"add-group", 1, 0, 'g'}, {"list", 0, 0, 'l'}, {"help", 0, 0, 'h'}, {"entries", 0, 0, 'e'}, {"verbose", 1, 0, 'v'}, {0, 0, 0, 0} }; c = getopt_long(argc, argv, "a:g:lchev:", long_options, &option_index); if(c == -1) break; switch (c) { case 'a': if (argc > 4) { if (strcmp(argv[3], "-g") == 0) { size_t len = strlen(argv[2]); char * testvar = malloc(len+1); strcpy(testvar, argv[2]); testvar[0] = toupper(testvar[0]); strcat(testvar, ","); fptr=fopen("animal.txt","r"); while(fgets(tempstring, 30, fptr) != NULL) { if((strstr(tempstring, testvar)) != NULL) { printf("\nEntry "); printf ("%s " ,optarg); printf("already exists, and its group is "); printf("%s\n", &(tempstring[strlen(optarg)+1])); find_result++; aflag = 0; break; } } fclose(fptr); if(find_result == 0) { aflag = 1; fptr=fopen("animal.txt","a"); fprintf(fptr, "%s", testvar); fclose(fptr); break; } } else { break; } } else { break; } case 'g': if (aflag == 0) { break; } else if (aflag ==1) { fptr=fopen("animal.txt","a"); optarg[0] = toupper(optarg[0]); fprintf(fptr, "%s\n", optarg); fclose(fptr); } break; case 'l': fptr=fopen("animal.txt","r"); if (fptr) { while ((c = getc(fptr)) != EOF) putchar(c); } fclose(fptr); break; case 'h': printf("\nGroup of tool. \n"); printf("=========================================================================\n"); printf("Add animal with -a ANIMAL-NAME -g GROUP-NAME.\n"); printf("List entries with -l \n"); printf("Count entries with -e\n"); printf("=========================================================================\n"); break; case 'e': fptr=fopen("animal.txt","r"); if (fptr) { while ((c = getc(fptr)) != EOF) { if ( c == '\n' ) { count++; } } } fclose(fptr); printf("%lu total entries.\n", count); break; case 'v': break; case '?': printf("option ? with value '%s'\n", optarg); break; default: printf("?? getopt returned character code 0%o ??\n", c); } } if (argc == 2) if (optind < argc) { fptr=fopen("animal.txt","r"); size_t len = strlen(argv[1]); char * testvar = malloc(len+1); strcpy(testvar, argv[1]); testvar[0] = toupper(testvar[0]); strcat(testvar, ","); while(fgets(tempstring, 30, fptr) != NULL) { if((strstr(tempstring, testvar)) != NULL) { printf("\nA group of "); printf ("%.*s" ,argv[1]); printf(" is a "); printf("%s\n", &(tempstring[strlen(argv[1])+1])); find_result++; } } if(find_result == 0) { printf("\nNo Matches Found.\n"); } fclose(fptr); } exit(EXIT_SUCCESS); } ====Matrix Multiplier==== * I am having a very messy start with the program + command line arguments. * Hopefully I can have code worth showing by the end of the week =====March 4th 2014===== * Today we created a program from the book called play_again3.c * It seems to simulate the yes and no transaction of an ATM #include #include #include #include #define ASK "Do you want another transaction?" #define TRIES 3 #define SLEEPTIME 2 #define BEEP putchar('\a') int get_response(char *question, int maxtries); int get_ok_char(); void set_cr_noecho_mode(); void set_nodelay_mode(); void tty_mode(int how); int main() { int response; tty_mode(0); set_cr_noecho_mode(); set_nodelay_mode(); response = get_response(ASK, TRIES); tty_mode(1); return (response); } int get_response(char *question, int maxtries) { int input; printf("%s (y/n)?", question); fflush(stdout); while(1) { sleep(SLEEPTIME); input = tolower(get_ok_char()); if (input == 'y') return (0); if (input == 'n') return (1); if (maxtries-- == 0) return (2); BEEP; } } int get_ok_char() { int c; while (( c = getchar() ) != EOF && strchr("yYnN",c) == NULL); return (c); } void set_cr_noecho_mode() { struct termios ttystate; tcgetattr( 0, &ttystate); ttystate.c_lflag &= ~ICANON; ttystate.c_lflag &= ~ECHO; ttystate.c_cc[VMIN] = 1; tcsetattr( 0 , TCSANOW, &ttystate); } void set_nodelay_mode() { int termflags; termflags = fcntl(0, F_GETFL); printf("termflags %X, O_NDELAY %X\n", termflags , O_NDELAY); termflags |= O_NDELAY; fcntl(0, F_SETFL, termflags); } void tty_mode(int how) { static struct termios original_mode; static int original_flags; if ( how == 0 ) { tcgetattr(0, &original_mode); original_flags = fcntl(0, F_GETFL); } else { tcsetattr(0, TCSANOW, &original_mode); fcntl( 0, F_SETFL, original_flags); } } =====March 27th 2014===== ===I/o redirection=== * When you run a program the main 4 file pointers are open * To daemonize them you would need to fclose all stdout stderr etc. * proc directory contains directories that are named after the pid's of processes on the system - cat cmdline shows the commands entered into the command line along with the file name of the process ===Example io redirect code=== #include #include #include int main() { int fd,newfd; char line[100]; fgets( line, 100, stdin ); printf("%s", line ); fgets( line, 100, stdin ); printf("%s", line ); fgets( line, 100, stdin ); printf("%s", line ); fd = open("/etc/passwd", O_RDONLY); close(0); newfd=dup(fd); if ( newfd != 0 ) { fprintf(stderr,"Could not open data as fd 0\n"); exit(1); } close(fd); fgets( line, 100, stdin ); printf("%s", line ); fgets( line, 100, stdin ); printf("%s", line ); fgets( line, 100, stdin ); printf("%s", line ); sleep(1800); return(0); }