close

Remove sub-string by delimiter in C

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
/*
 * strmhead.c
 *
 * Created by Jackie Xie on 2011-07-17.
 * Copyright 2011 Jackie Xie. All rights reserved.
 *
 */

#include <getopt.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* ======================(function header)========================
Function Name: int matchStrPosAt (const char *, const char *)
Description: find the sub-string from the source string.
Arguments: const char *, const char *
Return: Returns "the array element number"(or "position") where 
 "sub-string" matches before in "original string", or return 
 "-1" if substr is not present in "original string".
written by jackie xie
Date : 2007/07/10
================================================================*/
/* 
 * delimiters <= n:return position before n-th matched substr.
 * delimiters = 0:do nothing.
 * delimiters >= n:return position after n-th matched substr.
 */
int matchStrPosAt (char * substr, char * str, int delimiters)
{
	int i = -1, k, str_index;
	int substr_len = strlen(substr), str_len = strlen(str);
	int matchpos = -1;
	int delimiter[str_len], ind_delim = 0;
	//int n = abs(delimiters);

	for(k=0; k<=str_len ; k++)
		delimiter[k] = -1;

	if (str == NULL || substr == NULL) return -1;

	/* substr has to be smaller than str */
	if (substr_len > str_len) return -1;

	/* look through str for substr, stopping at end of string or when the length
 * of substr exceeds the remaining number of characters to be searched */ 
	while (str[++i] != '\0' && (str_len - i + 1) > substr_len) 
	{
		for (str_index = 0; str_index < substr_len; ++str_index)
		{
			/* definitely not at location i */
			if (str[i + str_index] != substr[str_index])
				break;
			/* if last letter matches, then we know the whole thing matched */
			else if (str_index == substr_len - 1)
			{
				if(delimiters >= 1)
				{
					i += substr_len -1;
					delimiter[++ind_delim] = i;
					printf("delimiter[%d] = %d\n", ind_delim, delimiter[ind_delim]);
				}
			}
		}
	}

	if(delimiters < ind_delim)
		matchpos = delimiter[delimiters];
	else
		matchpos = delimiter[ind_delim];

	return matchpos;
}

/* ======================(function header)========================
Function Name: int strmhead (char *str, const char *n, int pos)
Description: To cut the front of sub-string which is starting at the
 matched delimiter and ending of the input string.
Arguments: char *, const char *
Return: The string which was cut the front of input string till the 
 specified delimiter.
written by Jackie Xie
Date : 2011/08/12
================================================================*/
char *strmhead (char *str, const char *n, int pos)
{
	int i, _matchedStrLen = matchStrPosAt(n, str, abs(pos));
	int str_len = strlen(str);
	int _newStrLen = 0;
	
	char* _new;
	
	printf("copied string(%d) : %s\n", str_len, str);
	printf("matched position = %d\n", _matchedStrLen);
	
	if(_matchedStrLen > 0){
		if (pos >= 0)
			_matchedStrLen -= strlen(n);
			
		_newStrLen = str_len - _matchedStrLen;

		if ((_new = (char *)malloc(_newStrLen)) == NULL)
			return "NULL";

		(_new)[_newStrLen+1] = '\0';		

		/* copy sub-string from specified delimiter */
		for (i = 0; i < _newStrLen; ++i)
			(_new)[i] = str[_matchedStrLen +1 + i];
		printf("New string length is %d\n", _newStrLen);
		printf("New string is %s\n", _new);
		strcpy(str, _new);
		free (_new);
	}
	
	return str;
}

/* ======================(function header)========================
Function Name: int strcutail (char *str, const char *n, int pos)
Description: To remove the sub-string which is starting at 
 n-th delimiter(or include it) to the end of input string.
Arguments: char *, const char *
Return: Returns the string which was cut the tailed sub-string off.
written by Jackie Xie
Date : 2011/07/15
================================================================*/
char *strcutail (char *str, const char *startstr, int n)
{
	int i = -1, retpos = -1;
	char* _new;

	retpos = matchStrPosAt(startstr, str, abs(n));
	
	if(retpos > 0){
		if (n >= 0)
			++retpos;
			
		if ((_new = (char *)malloc(retpos)) == NULL)
			return "NULL";

		(_new)[retpos] = '\0';
		
		/* copy part before match */
		for (i = 0; i < retpos; ++i)
			(_new)[i] = str[i];

		strcpy(str, _new);
		printf("retpos length = %d\n", retpos);
		printf("strrmtail() : %s\n", str);
		free (_new);
	}
	return str;
}

int main(int argc, char* argv[])
{
	char* str = "Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test";
	char* startstr = "{i}";
	int position=0, c;
    char help_msg[1024] = "Usage: strmhead [-s string] [-d delimiter] [-p n]\n\n";
    
    strcat(help_msg, "strmhead command summary\n");
    strcat(help_msg, "\tstrmhead is a function to cut input string off from the begining of string to the nth delimiter in a string.\n");
    strcat(help_msg, "\tstring:input a string which is to be cut off by delimiter.\n");
    strcat(help_msg, "\tdelimiter:a token to specify the boundary between separate, independent regions from input string.\n");
    strcat(help_msg, "\tn:delimiter position\n");
    strcat(help_msg, "\tn >= 0:return a string which remove the sub-string from the beginning of string to the n-th delimiter.\n");
    strcat(help_msg, "\tn = 0:do nothing.\n");
    strcat(help_msg, "\tn <= 0:return a string which remove the sub-string from the beginning of string to the previous position of the n-th delimiter.\n\n");
 
	while ((c = getopt(argc, argv, "s:p:d:h")) != -1)
		switch (c) {
			case 's':
				str = optarg;
				break;
			case 'p':
				position = atoi(optarg);
				break;
			case 'd':
				startstr = optarg;					
				break;
			case 'h':
				fprintf(stderr, "%s", help_msg);
				exit(0);
				break;
			default:
				break;
		}
	
	printf("call strmhead() before : %s\n", str);
	printf("delimiter = %s\n", startstr);
	printf("position = %d\n", position);
	printf("After remove front string : %s\n", strmhead(str, startstr, position));
		
	return 0;
}

To run this program 'strmhead' after compiled.

[ jackie ~/test/opensource ]# ./strmhead -h
Usage: strmhead [-s string] [-d delimiter] [-p n]

strmhead command summary
        strmhead is a function to cut input string off from the begining of string to the nth delimiter in a string.
        string:input a string which is to be cut off by delimiter.
        delimiter:a token to specify the boundary between separate, independent regions from input string.
        n:delimiter position
        n >= 0:return a string which remove the sub-string from the beginning of string to the n-th delimiter.
        n  = 0:do nothing.
        n <= 0:return a string which remove the sub-string from the beginning of string to the previous position of the n-th delimiter.

[ jackie ~/test/opensource ]# ./strmhead -d .{i}. -s Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test -p 1
call strmhead() before : Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
delimiter = .{i}.
position = 1
delimiter[1] = 20
delimiter[2] = 44
delimiter[3] = 64
delimiter[4] = 74
copied string(79) : Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
matched position = 20
New string length is 64
New string is .{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
After remove front string : .{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
[ jackie ~/test/opensource ]# ./strmhead -d .{i}. -s Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test -p -1
call strmhead() before : Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
delimiter = .{i}.
position = -1
delimiter[1] = 20
delimiter[2] = 44
delimiter[3] = 64
delimiter[4] = 74
copied string(79) : Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
matched position = 20
New string length is 59
New string is WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
After remove front string : WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
[ jackie ~/test/opensource ]# ./strmhead -d .{i}. -s Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test -p 1
call strmhead() before : Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
delimiter = .{i}.
position = 1
delimiter[1] = 20
delimiter[2] = 44
delimiter[3] = 64
delimiter[4] = 74
copied string(79) : Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
matched position = 20
New string length is 64
New string is .{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
After remove front string : .{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
[ jackie ~/test/opensource ]# ./strmhead -d .{i}. -s Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test -p -1
call strmhead() before : Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
delimiter = .{i}.
position = -1
delimiter[1] = 20
delimiter[2] = 44
delimiter[3] = 64
delimiter[4] = 74
copied string(79) : Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
matched position = 20
New string length is 59
New string is WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
After remove front string : WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
[ jackie ~/test/opensource ]# ./strmhead -d .{i}. -s Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test -p -2
call strmhead() before : Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
delimiter = .{i}.
position = -2
delimiter[1] = 20
delimiter[2] = 44
delimiter[3] = 64
delimiter[4] = 74
copied string(79) : Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
matched position = 44
New string length is 35
New string is WANIPConnection.{i}.Stats.{i}.test
After remove front string : WANIPConnection.{i}.Stats.{i}.test
[ jackie ~/test/opensource ]# ./strmhead -d .{i}. -s Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test -p 2
call strmhead() before : Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
delimiter = .{i}.
position = 2
delimiter[1] = 20
delimiter[2] = 44
delimiter[3] = 64
delimiter[4] = 74
copied string(79) : Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
matched position = 44
New string length is 40
New string is .{i}.WANIPConnection.{i}.Stats.{i}.test
After remove front string : .{i}.WANIPConnection.{i}.Stats.{i}.test
[ jackie ~/test/opensource ]# ./strmhead -d .{i}. -s Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test -p 3
call strmhead() before : Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
delimiter = .{i}.
position = 3
delimiter[1] = 20
delimiter[2] = 44
delimiter[3] = 64
delimiter[4] = 74
copied string(79) : Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
matched position = 64
New string length is 20
New string is .{i}.Stats.{i}.test
After remove front string : .{i}.Stats.{i}.test
[ jackie ~/test/opensource ]# ./strmhead -d .{i}. -s Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test -p -3
call strmhead() before : Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
delimiter = .{i}.
position = -3
delimiter[1] = 20
delimiter[2] = 44
delimiter[3] = 64
delimiter[4] = 74
copied string(79) : Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
matched position = 64
New string length is 15
New string is Stats.{i}.test
After remove front string : Stats.{i}.test
[ jackie ~/test/opensource ]# ./strmhead -d .{i}. -s Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test -p -4
call strmhead() before : Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
delimiter = .{i}.
position = -4
delimiter[1] = 20
delimiter[2] = 44
delimiter[3] = 64
delimiter[4] = 74
copied string(79) : Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
matched position = 74
New string length is 5
New string is test
After remove front string : test
[ jackie ~/test/opensource ]# ./strmhead -d .{i}. -s Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test -p 4
call strmhead() before : Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
delimiter = .{i}.
position = 4
delimiter[1] = 20
delimiter[2] = 44
delimiter[3] = 64
delimiter[4] = 74
copied string(79) : Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
matched position = 74
New string length is 10
New string is .{i}.test
After remove front string : .{i}.test
[ jackie ~/test/opensource ]# ./strmhead -d .{i}. -s Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test -p -100
call strmhead() before : Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
delimiter = .{i}.
position = -100
delimiter[1] = 20
delimiter[2] = 44
delimiter[3] = 64
delimiter[4] = 74
copied string(79) : Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
matched position = 74
New string length is 5
New string is test
After remove front string : test
[ jackie ~/test/opensource ]# ./strmhead -d .{i}. -s Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test -p 100
call strmhead() before : Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
delimiter = .{i}.
position = 100
delimiter[1] = 20
delimiter[2] = 44
delimiter[3] = 64
delimiter[4] = 74
copied string(79) : Device.WANDevice.{i}.WANConnectionDevice.{i}.WANIPConnection.{i}.Stats.{i}.test
matched position = 74
New string length is 10
New string is .{i}.test
After remove front string : .{i}.test
[ jackie ~/test/opensource ]#
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 Bluelove1968 的頭像
    Bluelove1968

    藍色情懷

    Bluelove1968 發表在 痞客邦 留言(2) 人氣()