======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);
}