// crudwork // Copyright 2004 by Steve T. Pham (http://www.crudwork.com) // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with This program. If not, see <http://www.gnu.org/licenses/>. using System; using System.Collections.Generic; using System.Text; namespace crudwork.Utilities { /// <summary> /// Collection of manipulations, parsers, and other /// methods related to Character. /// </summary> public static class CharUtil { /// <summary> /// Test an input character if it is contained in a character list. /// </summary> /// <param name="inputChar"></param> /// <param name="inputList"></param> /// <returns></returns> public static bool ContainsChar(char inputChar, char[] inputList) { List<char> clist = new List<char>(); clist.AddRange(inputList); return clist.Contains(inputChar); } } }
Month: February 2011
Buffer for characters
// CharBuffer.cs // // Copyright (C) 2003-2004 Ryan Seghers // // This software is provided AS IS. No warranty is granted, // neither expressed nor implied. USE THIS SOFTWARE AT YOUR OWN RISK. // NO REPRESENTATION OF MERCHANTABILITY or FITNESS FOR ANY // PURPOSE is given. // // License to use this software is limited by the following terms: // 1) This code may be used in any program, including programs developed // for commercial purposes, provided that this notice is included verbatim. // // Also, in return for using this code, please attempt to make your fixes and // updates available in some way, such as by sending your updates to the // author. using System; namespace RTools_NTS.Util { /// <summary> /// Buffer for characters. This approximates StringBuilder /// but is designed to be faster for specific operations. /// This is about 30% faster for the operations I'm interested in /// (Append, Clear, Length, ToString). /// This trades off memory for speed. /// </summary> /// <remarks> /// <para>To make Remove from the head fast, this is implemented /// as a ring buffer.</para> /// <para>This uses head and tail indices into a fixed-size /// array. This will grow the array as necessary.</para> /// </remarks> public class CharBuffer { #region Fields int capacity = 128; char[] buffer; int headIndex; // index of first char int tailIndex; // index 1 past last char #endregion #region Properties /// <summary> /// Gets/Sets the number of characters in the character buffer. /// Increasing the length this way provides indeterminate results. /// </summary> public int Length { get { return(tailIndex - headIndex); } set { tailIndex = headIndex + value; if (tailIndex >= capacity) throw new IndexOutOfRangeException("Tail index greater than capacity"); } } /// <summary> /// Returns the capacity of this character buffer. /// </summary> public int Capacity { get { return(capacity); } } #endregion #region Constructors /// <summary> /// Default constructor. /// </summary> public CharBuffer() { buffer = new char[capacity]; } /// <summary> /// Construct with a specific capacity. /// </summary> /// <param name="capacity"></param> public CharBuffer(int capacity) { this.capacity = capacity; buffer = new char[capacity]; } #endregion #region Non-Public Methods /// <summary> /// Reallocate the buffer to be larger. For the new size, this /// uses the max of the requested length and double the current /// capacity. /// This does not shift, meaning it does not change the head or /// tail indices. /// </summary> /// <param name="requestedLen">The new requested length.</param> protected void Grow(int requestedLen) { int newLen = Math.Max(capacity*2, requestedLen); newLen = Math.Max(newLen, 16); char[] newBuffer = new char[newLen]; Array.Copy(buffer, 0, newBuffer, 0, capacity); buffer = newBuffer; capacity = newLen; } /// <summary> /// Ensure that we're set for the requested length by /// potentially growing or shifting contents. /// </summary> /// <param name="requestedLength"></param> protected void CheckCapacity(int requestedLength) { if (requestedLength + headIndex >= capacity) { // have to do something if ((requestedLength + headIndex > (capacity >> 1)) && (requestedLength < capacity - 1)) { // we're more than half-way through the buffer, and shifting is enough // so just shift ShiftToZero(); } else { // not far into buffer or shift wouldn't be enough anyway Grow(0); } } } /// <summary> /// Move the buffer contents such that headIndex becomes 0. /// </summary> protected void ShiftToZero() { int len = Length; for (int i = 0; i < len; i++) { buffer[i] = buffer[i + headIndex]; } headIndex = 0; tailIndex = len; } #endregion #region Public Methods and Indexer /// <summary> /// Overwrite this object's underlying buffer with the specified /// buffer. /// </summary> /// <param name="b">The character array.</param> /// <param name="len">The number of characters to consider filled /// in the input buffer.</param> public void SetBuffer(char[] b, int len) { capacity = b.Length; buffer = b; headIndex = 0; tailIndex = len; } /// <summary> /// Append a character to this buffer. /// </summary> /// <param name="c"></param> public void Append(char c) { if (tailIndex >= capacity) CheckCapacity(Length + 1); buffer[tailIndex++] = c; } /// <summary> /// Append a string to this buffer. /// </summary> /// <param name="s">The string to append.</param> public void Append(string s) { if (s.Length + tailIndex >= capacity) CheckCapacity(Length + s.Length); for(int i = 0; i < s.Length; i++) buffer[tailIndex++] = s[i]; } /// <summary> /// Append a string to this buffer. /// </summary> /// <param name="s">The string to append.</param> public void Append(CharBuffer s) { if (s.Length + tailIndex >= capacity) CheckCapacity(Length + s.Length); for(int i = 0; i < s.Length; i++) buffer[tailIndex++] = s[i]; } /// <summary> /// Remove a character at the specified index. /// </summary> /// <param name="i">The index of the character to remove.</param> /// <returns></returns> public void Remove(int i) { Remove(i, 1); } /// <summary> /// Remove a specified number of characters at the specified index. /// </summary> /// <param name="i">The index of the characters to remove.</param> /// <param name="n">The number of characters to remove.</param> public void Remove(int i, int n) { n = Math.Min(n, Length); if (i == 0) { headIndex += n; } else { Array.Copy(buffer, i + headIndex + n, buffer, i + headIndex, tailIndex - (i + headIndex + n)); } } /// <summary> /// Find the first instance of a character in the buffer, and /// return its index. This returns -1 if the character is /// not found. /// </summary> /// <param name="c">The character to find.</param> /// <returns>The index of the specified character, or -1 /// for not found.</returns> public int IndexOf(char c) { for (int i = headIndex; i < tailIndex; i++) { if (buffer[i] == c) return(i - headIndex); } return(-1); } /// <summary> /// Empty the buffer. /// </summary> public void Clear() { headIndex = 0; tailIndex = 0; } /// <summary> /// Indexer. /// </summary> public char this [int index] { get { return(buffer[index + headIndex]); } set { buffer[index + headIndex] = value; } } /// <summary> /// Return the current contents as a string. /// </summary> /// <returns>The new string.</returns> public override String ToString() { return(new String(buffer, headIndex, tailIndex - headIndex)); } #endregion } }
demonstrates IsSymbol.
using System; public class IsSymbolSample { public static void Main() { string str = "non-symbolic characters"; Console.WriteLine(Char.IsSymbol('+')); Console.WriteLine(Char.IsSymbol(str, 8)); } }
Char.IsLowSurrogate(), IsHighSurrogate(), IsSurrogatePair() method
using System;
class Sample
{
public static void Main()
{
char cHigh = 'uD800';
char cLow = 'uDC00';
string s1 = new String(new char[] {'a', 'uD800', 'uDC00', 'z'});
Console.WriteLine(“cHigh: {0:X4}”, (int)cHigh);
Console.WriteLine(“cLow: {0:X4}”, (int)cLow);
for(int i = 0; i < s1.Length; i++){
Console.WriteLine("{0:X4} ", (int)s1[i]);
}
Console.WriteLine("cLow? - {0}", Char.IsHighSurrogate(cLow));
Console.WriteLine("cHigh? - {0}", Char.IsHighSurrogate(cHigh));
Console.WriteLine("s1[0]? - {0}", Char.IsHighSurrogate(s1, 0));
Console.WriteLine("s1[1]? - {0}", Char.IsHighSurrogate(s1, 1));
Console.WriteLine("cLow? - {0}", Char.IsLowSurrogate(cLow));
Console.WriteLine("cHigh? - {0}", Char.IsLowSurrogate(cHigh));
Console.WriteLine("s1[0]? - {0}", Char.IsLowSurrogate(s1, 0));
Console.WriteLine("s1[2]? - {0}", Char.IsLowSurrogate(s1, 2));
Console.WriteLine("cHigh and cLow? - {0}", Char.IsSurrogatePair(cHigh, cLow));
Console.WriteLine("s1[0] and s1[1]? - {0}", Char.IsSurrogatePair(s1, 0));
Console.WriteLine("s1[1] and s1[2]? - {0}", Char.IsSurrogatePair(s1, 1));
Console.WriteLine("s1[2] and s1[3]? - {0}", Char.IsSurrogatePair(s1, 2));
}
}
[/csharp]
Char: Get Unicode Category
using System; using System.Text.RegularExpressions; public class Example { public static void Main() { char[] chars = { 'a', 'X', '8', ',', ' ', 'u0009', '!' }; foreach (char ch in chars) Console.WriteLine("'{0}': {1}", Regex.Escape(ch.ToString()), Char.GetUnicodeCategory(ch)); } }
IsDigit, IsLetter, IsWhiteSpace, IsLetterOrDigit, IsPunctuation
using System; using System.Collections.Generic; using System.Text; class Program { static void Main(string[] args) { Console.WriteLine("-> char.IsDigit('K'): {0}", char.IsDigit('K')); Console.WriteLine("-> char.IsDigit('9'): {0}", char.IsDigit('9')); Console.WriteLine("-> char.IsLetter('10', 1): {0}", char.IsLetter("10", 1)); Console.WriteLine("-> char.IsLetter('p'): {0}", char.IsLetter('p')); Console.WriteLine("-> char.IsWhiteSpace('Hello There', 5): {0}",char.IsWhiteSpace("Hello There", 5)); Console.WriteLine("-> char.IsWhiteSpace('Hello There', 6): {0}",char.IsWhiteSpace("Hello There", 6)); Console.WriteLine("-> char.IsLetterOrDigit('?'): {0}",char.IsLetterOrDigit('?')); Console.WriteLine("-> char.IsPunctuation('!'): {0}",char.IsPunctuation('!')); Console.WriteLine("-> char.IsPunctuation('>'): {0}",char.IsPunctuation('>')); Console.WriteLine("-> char.IsPunctuation(','): {0}",char.IsPunctuation(',')); } }
A queue class for characters
/*
C# A Beginner's Guide
By Schildt
Publisher: Osborne McGraw-Hill
ISBN: 0072133295
*/
/*
Project 5-2
A queue class for characters.
*/
using System;
class Queue {
public char[] q; // this array holds the queue
public int putloc, getloc; // the put and get indices
public Queue(int size) {
q = new char[size+1]; // allocate memory for queue
putloc = getloc = 0;
}
// put a character into the queue
public void put(char ch) {
if(putloc==q.Length-1) {
Console.WriteLine(” — Queue is full.”);
return;
}
putloc++;
q[putloc] = ch;
}
// get a character from the queue
public char get() {
if(getloc == putloc) {
Console.WriteLine(” — Queue is empty.”);
return (char) 0;
}
getloc++;
return q[getloc];
}
}
// Demonstrate the Queue class.
public class QueueDemo1 {
public static void Main() {
Queue bigQ = new Queue(100);
Queue smallQ = new Queue(4);
char ch;
int i;
Console.WriteLine(“Using bigQ to store the alphabet.”);
// put some numbers into bigQ
for(i=0; i < 26; i++)
bigQ.put((char) ('A' + i));
// retrieve and display elements from bigQ
Console.Write("Contents of bigQ: ");
for(i=0; i < 26; i++) {
ch = bigQ.get();
if(ch != (char) 0) Console.Write(ch);
}
Console.WriteLine("
");
Console.WriteLine("Using smallQ to generate erros.");
// Now, use smallQ to generate some errors
for(i=0; i < 5; i++) {
Console.Write("Attempting to store " +
(char) ('Z' - i));
smallQ.put((char) ('Z' - i));
Console.WriteLine();
}
Console.WriteLine();
// more errors on smallQ
Console.Write("Contents of smallQ: ");
for(i=0; i < 5; i++) {
ch = smallQ.get();
if(ch != (char) 0) Console.Write(ch);
}
}
}
[/csharp]