[ create a new paste ] login | about

Link: http://codepad.org/QZL317EK    [ raw code | fork ]

C, pasted on Apr 25:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAXLIST 1024
#define MAXLINE 1024

static int getline(char *s, int lim, FILE *fp);
static char *stringcopy(char *dest, char *source, int n);
static char* getword(char *s, const char *sep);

int cut(int argc, char *argv[])
{
	FILE *fp;
	char c, delim[] = "\t";
	int field = 0, character = 0;
	char line[MAXLINE], *charpos = NULL, *fieldpos = NULL;

	/* parse the optional arguments */
	while(--argc && (*++argv)[0] == '-')
	{
		c = *++argv[0];
		switch(c)
		{
			case 'c':
				if(field)			/* -f option already given in command line */
				{
					printf("cut: providing both options -c and -f is illegal usage\n");
					argc = 0;
					break;
				}
				character = 1;
				charpos = &*++argv[0];
				break;
			case 'f':
				if(character)		/* -c option already given in command line */
				{
					printf("cut: providing both options -c and -f is illegal usage\n");
					argc = 0;
					break;
				}
				field = 1;
				fieldpos = &*++argv[0];
				break;
			case 'd':
				if(character)
				{
					printf("cut: -d option can only be provided with -f option\n");
					argc = 0;
					break;
				}
				if(!field)
				{
					printf("cut: -d option can only be provided with -f option\n");
					argc = 0;
					break;
				}
				delim[0] = *++argv[0];
				break;
			default:
				printf("cut: illegal option %c\n", c);
				argc = 0;
				break;
		}
	}

	if(argc != 1 || (!field && !character))
	{
		printf("(Usage: cut -clist [file ...] or cut -flist [-dchar] [file ...].\n");
		return 1;
	}

	/* open file in read mode*/
	if((fp = fopen(*argv, "r")) == NULL)
	{
		printf("cut: cannot open file %s\n", *argv);
		return 1;
	}

	if(field)				/* -f option is given */
	{
		/* read line from input file */
		while(getline(line, sizeof(line), fp))
		{
			char copy[MAXLIST], *pos, *word;
			int wordpos;

			/* copy field options in seperate memory */
			stringcopy(copy, fieldpos, sizeof(copy));

			/* cut line according to the field options given */
			for(pos = strtok(copy, ","), word = getword(line, (const char*)delim), wordpos = 1; pos; pos = strtok(NULL, ","))			/* get the field value by tokenizing the copied string */
			{
				int k;

				if((k = atoi(pos)) < 1)		/* get the field pos. field position should be greater then 0 */
					continue;

				/* find the word in line at position given by j */
				for(; wordpos < k; wordpos++)
					word = getword(NULL, (const char*)delim);

				fprintf(stdout, "%s	", word);
			}
			fprintf(stdout, "\n");
		}
	}
	else					/* -c option is given */
	{
		/* read line from input file */
		while(getline(line, sizeof(line), fp))
		{
			char copy[MAXLIST], *pos, *linepos = &line[0];

			/* copy field options in seperate memory */
			stringcopy(copy, charpos, sizeof(copy));

			for(pos = strtok(copy, ","); pos; pos = strtok(NULL, ","))			/* get character range by tokenizing the copied string */
			{
				char *dashpos;
				/* check if it is a range or a single character */
				for(dashpos = pos; *dashpos != '\0' && *dashpos != '-'; dashpos++);

				if(*dashpos == '-')		/* it is a character range */
				{
					int start_char_pos, end_char_pos;
					char *start_char_p, *end_char_p;

					if((start_char_pos = atoi(pos)) < 1)
						continue;

					if((end_char_pos = atoi(++dashpos)) < 1)
						continue;

					/* bring linepos to start */
					for(start_char_p = &line[start_char_pos-1]; *linepos != '\n' && linepos < start_char_p; linepos++);
					if(*linepos == '\n')
						continue;

					/* print the character range */
					for(end_char_p = &line[end_char_pos-1]; *linepos != '\n' && linepos <= end_char_p; linepos++)
						fprintf(stdout, "%c", *linepos);
				}
				else					/* it is a character pos */
				{
					int cur_char_pos;
					char *cur_pos_p;

					if((cur_char_pos = atoi(pos)) < 1)
						continue;

					for(cur_pos_p = &line[cur_char_pos-1]; *linepos != '\n' && linepos < cur_pos_p; linepos++);
					if(*linepos != '\n')
						fprintf(stdout, "%c", *linepos);
				}
			}
			fprintf(stdout, "\n");
		}
	}
	return 0;
}

static int getline(char *s, int lim, FILE *fp)
{
	int i;
	char c;

	for(i = 0; i < (lim-1) && (c = getc(fp)) != EOF && c != '\n'; i++)
		s[i] = c;

	if(c == '\n')
		s[i++] = c;

	s[i] = '\0';

	return i;
}

static char *stringcopy(char *dest, char *source, int n)
{
	int i;

	for(i = 0; (i < (n-1)) && ((dest[i] = source[i]) != '\0'); i++);
	dest[i] = '\0';

	return dest;
}

static char* getword(char *s, const char *sep)
{
	char *p, *tokenptr;

	/* static pointer pointing to the current position in s */
	static char *currentp = NULL;

	/* if s is not NULL, point currentp to starting of NULL */
	if(s != NULL)
		currentp = s;

	/* when the function is called for the first time and s is NULL, return NULL */
	if(s == NULL && currentp == NULL)
		return NULL;

	/* bypass the initial seperator characters */
	for(p = currentp; *p != '\0'; p++)
	{
		const char *sep_p;

		/* check if the character is seperator */
		for(sep_p = sep; *sep_p != '\0'; sep_p++)
		{
			if(*sep_p == *p)
				break;
		}

		if(*sep_p == '\0')
			break;						/* if character other then separator is found, break out of the loop */
	}

	/* end of string is reached */
	if(*p == '\0')
	{
		currentp = NULL;
		return NULL;
	}

	/* find the next seperator character */
	for(tokenptr = p; *p != '\0'; p++)
	{
		const char *sep_p;

		for(sep_p = sep; *sep_p != '\0'; sep_p++)
		{
			if(*sep_p == *p)
				break;
		}

		if(*sep_p != '\0')
			break;					/* if the character is separator then break out of loop */
	}

	if(*p == '\0')
		currentp = p;
	else
	{
		currentp = p+1;
		*p = '\0';
	}
	return tokenptr;
}


Create a new paste based on this one


Comments: