CSM210: Systems Programming in C. Practical Session 1

Solution to strncpy amended to manage dynamic memory allocations



/* prog is called with a.out n [filename] */

/* strmcpy(s, t, n) copy n chars from s to t. */
#include 
#include 

struct string {
 char a;
 struct string *ptr;
} copy;

// defines the first item of a linked list 

int strmcpy(FILE *,  struct string *, int n);

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

struct string *ptr2copy = ©
// pointer which points to first item in linked list

int copy_from = 0;
FILE *fp;
int c;

 if (argc < 2 || argc > 3)
 { printf("Errors in input\n");
 return 0;
 }
 
copy_from=atoi(*(argv+1));

// if third arg is present then it's a file name, otherwise take input from stdin

if (argc == 3) {
 if ((fp = fopen(*(argv+2), "r")) == NULL) {
    printf("Error opening file...\n"); 
    return 0;
 } 
} else /* argc is 2 */{
	fp = stdin;
}


// we'll now pass a pointer to standard input or the file, as appropriate

strmcpy(fp, ptr2copy, copy_from); 

// right, now print the contents of the linked list...

ptr2copy = © // reset the pointer in case it's been changed

// cycle through the linked list

while (ptr2copy->ptr != NULL) {
	putchar(ptr2copy->a);
	ptr2copy = ptr2copy->ptr;
}

// when the pointer is null, the item contains the last character of the string
putchar(ptr2copy->a);
putchar('\n');

fclose(fp);
}

int strmcpy(FILE *fp, struct string *ptr2copy, int n) {

int k = 0;
struct string *tmp; // temp pointer to string struct

if (n == 0) {
	ptr2copy->a = '\0';
	ptr2copy->ptr = NULL;
	return 1;
}

 while (n > k++) {
  tmp = ptr2copy;
  tmp->a = getc(fp); // read next char into tmp->a
  ptr2copy = (struct string *) malloc(sizeof(struct string)); // request space
  tmp->ptr = ptr2copy; // set tmp->ptr to address of next item
 }
 tmp->ptr = NULL; // set last pointer to NULL
 return 1;
}