I'm newbie to c#, So i tried the below program, which will change the case of the first character of the string
public class StringBuilder
{
public static string ChangeFirstLetterCase(string inputdata)
{
if(inputdata.Length > 0)
{
char[] charArray = inputdata.ToCharArray();
charArray[0] = char.IsUpper(charArray[0]) ?
char.ToLower(charArray[0]) : char.ToUpper(charArray[0]);
//return new string(charArray);
return charArray.ToString();
}
return inputdata;
}
}
class Program
{
static void Main(string[] args)
{
var a = StringBuilder.ChangeFirstLetterCase("vishnu");
Console.WriteLine(a);
Console.ReadLine();
}
}
Since the return type of this method ChangeFirstLetterCase() is a string. So I'm just doing the conversion like below
`return charArray.ToString();`
So in the method call it is returning the System.Char[]
Alternatively I tried the below one as well
`return new string(charArray);`
So this is returning the value as expected
Argument to the method - "vishnu"
Return value - "Vishnu"
So my question here is
Since the return type of the method is string, what's wrong with below conversion?
return charArray.ToString();
How do we know when to return as new string?.
return new string(charArray);
Please provide me some example
If you return the char array as a String, it will return you the name of the object System.Char[]. This is because the ToString method of char arrays does not build the characters of the array into a usable string, but simply makes a String that states the type of object.
However, if you use new String(char[]), this will read the contents of the char array to build a string out of whatever characters are in the char array. So, you will want to use new String(char[]) for most of your String building, I cannot think of any real uses for using the ToString() on a char array.
So, for your example, you should use return new String(charArray); instead of return charArray.ToString();.
charArray.ToString(); returns the type name because it's implemented that way, for getting string back from a character array you will always have to use String class constructor.
ToString method for char[] is not implemented in a way to return the character array back as a string literal, so use String constructor as you did in the second case.
You could return:
if(inputData[0].IsLower())
return string.Concat(inputData[0].ToUpper(), inputData.Substring(1));
else
return string.Concat(inputData[0].ToLower(), inputData.Substring(1));
Your value would already be a usable string and wouldn't need to have a char[].
I'm not really sure what you gain from converting the string to a char array to being with.
Related
Why doesn't my code work?? I am writing a cypher program in C# and would like to know why this isn't working. The error that I keep on getting is 'not all code paths return a value'
this is my code:
If passed string will be empty then the return will never be hit, so the method will not return anything.
public static string cypher(string word)
{
// If word is null, we just return null.
if(string.IsNullOrEmpty(word))
return null;
// Process string. This will return after first char...
foreach (char d in word)
{
char charCypher = System.Convert.ToChar((int)d+2);
return Convert.ToString(charCypher);
}
}
Not exactly what the question is about, but you iterate through each char of a word, but you return after first char. You probably want to cypher every char and return cyphered word. In this case you need to modify your code:
public static string cypher(string word)
{
// If word is null, we just return null.
if(string.IsNullOrEmpty(word))
return null;
StringBuilder builder = new StringBuilder();
foreach (char d in word)
{
char charCypher = System.Convert.ToChar((int)d+2);
builder.Append(Convert.ToString(charCypher));
}
return builder.ToString();
}
The foreach loop in cypher can contain an empty string, so the loop won't be executed if that's the case. Therefore it won't hit your return statement.
A workaround for this problem could be adding return String.Empty before the last closing brace or your method.
It seems, that you want to implement Caesar cipher:
using System.Linq;
...
public static string cypher(string word) {
//DONE: do not forget to validate public method's arguments
if (string.IsNullOrEmpty(word))
return word;
//TODO: you may want to make some amendments
// 1. Filter out which characters to encode (e.g. skip new lines)
// 2. Add modulo operator (e.g. to encode letters as letters)
return string.Concat(word.Select(d => (char)(d + 2)));
}
Please, do not forget to cast integer back to char when concatenating the string
I'm learning C# and C and this C# code is giving me an error I don't understand. I'm reading about extension methods and this code is giving the error: No overload for method 'WriteTextToConsole' takes 1 arguments. As you can see, it takes exactly 1 arguments? I created the variables c and count only to be able to construct the string object. So I could try the extension in the String class. Is it right understood that the way you create an extension method: is to precede the parameter with the "this" keyword and the parameter is of the type of class to be extended?
The code is here:
Console.WriteLine();
M.WriteTextToConsole("Hello, world. Programming in C# is fun");
char c = 'A';
int count = 14;
String str = new String(c, count);
str.WriteTextToConsole("This is a string");
The method is here:
static class M
{
public static void WriteTextToConsole(this string text)
{
Console.WriteLine(text);
}
}
you need to call it as str.WriteTextToConsole();. In this case str would be passed as a single argument to M.WriteTextToConsole() method
When you call the extension method on the string the "this string text" parameter refers to the string itself,for example if it where "this Bitmap b" it would be an extension method for the bitmap and assuming you had created a bitmap object named bit the call would be bit.WriteTextToConsole().If you want to had other parameters you need to add those to to the method declaration and to make so it is an option for the caller make it with the params keyword like so:
static class M
{
public static void WriteTextToConsole(this string text,params string[] str)
{
if (str.Length > 0)
{
//do something with extra string or strings
//you can make params Object[] but for this
//example i choose string[]
Console.WriteLine(text);
return;
}
Console.WriteLine(text);
}
}
Just remenber the this keyword must be the first parameter,refering to the type you are extending.
In the case of having optional strings i left the code with the duplicate console.WriteLine(text) you can rewrite it if you in both cases want the string displayed in the console(just remove the return and console writeline above it).
In Java there is a method splitByCharacterType that takes a string, for example 0015j8*(, and split it into "0015","j","8","*","(". Is there a built in function like this in c#? If not how would I go around building a function to do this?
public static IEnumerable<string> SplitByCharacterType(string input)
{
if (String.IsNullOrEmpty(input))
throw new ArgumentNullException(nameof(input));
StringBuilder segment = new StringBuilder();
segment.Append(input[0]);
var current = Char.GetUnicodeCategory(input[0]);
for (int i = 1; i < input.Length; i++)
{
var next = Char.GetUnicodeCategory(input[i]);
if (next == current)
{
segment.Append(input[i]);
}
else
{
yield return segment.ToString();
segment.Clear();
segment.Append(input[i]);
current = next;
}
}
yield return segment.ToString();
}
Usage as follows:
string[] split = SplitByCharacterType("0015j8*(").ToArray();
And the result is "0015","j","8","*","("
I recommend you implement as an extension method.
I don't think that such method exist. You can follow steps as below to create your own utility method:
Create a list to hold split strings
Define strings with all your character types e.g.
string numberString = "0123456789";
string specialChars = "~!##$%^&*(){}|\/?";
string alphaChars = "abcde....XYZ";
Define a variable to hold the temporary string
Define a variable to note the type of chars
Traverse your string, one char at a time, check the type of char by checking the presence of the char in predefined type strings.
If type is new than the previous type(check the type variable value) then add the temporary string(not empty) to the list, assign the new type to type variable and assign the current char to the temp string. If otherwise, then append the char to temporary string.
In the end of traversal, add the temporary string(not empty) to the list
Now your list contains the split strings.
Convert the list to an string array and you are done.
You could maybe use regex class, somthing like below, but you will need to add support for other chars other than numbers and letters.
var chars = Regex.Matches("0015j8*(", #"((?:""[^""\\]*(?:\\.[^""\\]*)*"")|[a-z]|\d+)").Cast<Match>().Select(match => match.Value).ToArray();
Result
0015,J,8
I want to pass a string array (separated by commas), then use a function to split the passed array by a comma, and add in a delimiter in place of the comma.
I will show you what I mean in further detail with some broken code:
String FirstData = "1";
String SecondData = "2" ;
String ThirdData = "3" ;
String FourthData = null;
FourthData = AddDelimiter(FirstData,SecondData,ThirdData);
public String AddDelimiter(String[] sData)
{
// foreach ","
String OriginalData = null;
// So, here ... I want to somehow split 'sData' by a ",".
// I know I can use the split function - which I'm having
// some trouble with - but I also believe there is some way
// to use the 'foreach' function? I wish i could put together
// some more code here but I'm a VB6 guy, and the syntax here
// is killing me. Errors everywhere.
return OriginalData;
}
Syntax doesn't matter much here, you need to get to know the Base Class Library. Also, you want to join strings apparently, not split it:
var s = string.Join(",", arrayOFStrings);
Also, if you want to pass n string to a method like that, you need the params keyword:
public string Join( params string[] data) {
return string.Join(",", data);
}
To split:
string[] splitString = sData.Split(new char[] {','});
To join in new delimiter, pass in the array of strings to String.Join:
string colonString = String.Join(":", splitString);
I think you are better off using Replace, since all you want to do is replace one delimiter with another:
string differentDelimiter = sData.Replace(",", ":");
If you have several objects and you want to put them in an array, you can write:
string[] allData = new string[] { FirstData, SecondData, ThirdData };
you can then simply give that to the function:
FourthData = AddDelimiter(allData);
C# has a nice trick, if you add a params keyword to the function definition, you can treat it as if it's a function with any number of parameters:
public String AddDelimiter(params String[] sData) { … }
…
FourthData = AddDelimiter(FirstData, SecondData, ThirdData);
As for the actual implementation, the easiest way is to use string.Join():
public String AddDelimiter(String[] sData)
{
// you can use any other string instead of ":"
return string.Join(":", sData);
}
But if you wanted to build the result yourself (for example if you wanted to learn how to do it), you could do it using string concatenation (oneString + anotherString), or even better, using StringBuilder:
public String AddDelimiter(String[] sData)
{
StringBuilder result = new StringBuilder();
bool first = true;
foreach (string s in sData)
{
if (!first)
result.Append(':');
result.Append(s);
first = false;
}
return result.ToString();
}
One version of the Split function takes an array of characters. Here is an example:
string splitstuff = string.Split(sData[0],new char [] {','});
If you don't need to perform any processing on the parts in between and just need to replace the delimiter, you could easily do so with the Replace method on the String class:
string newlyDelimited = oldString.Replace(',', ':');
For large strings, this will give you better performance, as you won't have to do a full pass through the string to break it apart and then do a pass through the parts to join them back together.
However, if you need to work with the individual parts (to recompose them into another form that does not resemble a simple replacement of the delimiter), then you would use the Split method on the String class to get an array of the delimited items and then plug those into the format you wish.
Of course, this means you have to have some sort of explicit knowledge about what each part of the delimited string means.
I am trying to create a generic formatter/parser combination.
Example scenario:
I have a string for string.Format(), e.g. var format = "{0}-{1}"
I have an array of object (string) for the input, e.g. var arr = new[] { "asdf", "qwer" }
I am formatting the array using the format string, e.g. var res = string.Format(format, arr)
What I am trying to do is to revert back the formatted string back into the array of object (string). Something like (pseudo code):
var arr2 = string.Unformat(format, res)
// when: res = "asdf-qwer"
// arr2 should be equal to arr
Anyone have experience doing something like this? I'm thinking about using regular expressions (modify the original format string, and then pass it to Regex.Matches to get the array) and run it for each placeholder in the format string. Is this feasible or is there any other more efficient solution?
While the comments about lost information are valid, sometimes you just want to get the string values of of a string with known formatting.
One method is this blog post written by a friend of mine. He implemented an extension method called string[] ParseExact(), akin to DateTime.ParseExact(). Data is returned as an array of strings, but if you can live with that, it is terribly handy.
public static class StringExtensions
{
public static string[] ParseExact(
this string data,
string format)
{
return ParseExact(data, format, false);
}
public static string[] ParseExact(
this string data,
string format,
bool ignoreCase)
{
string[] values;
if (TryParseExact(data, format, out values, ignoreCase))
return values;
else
throw new ArgumentException("Format not compatible with value.");
}
public static bool TryExtract(
this string data,
string format,
out string[] values)
{
return TryParseExact(data, format, out values, false);
}
public static bool TryParseExact(
this string data,
string format,
out string[] values,
bool ignoreCase)
{
int tokenCount = 0;
format = Regex.Escape(format).Replace("\\{", "{");
for (tokenCount = 0; ; tokenCount++)
{
string token = string.Format("{{{0}}}", tokenCount);
if (!format.Contains(token)) break;
format = format.Replace(token,
string.Format("(?'group{0}'.*)", tokenCount));
}
RegexOptions options =
ignoreCase ? RegexOptions.IgnoreCase : RegexOptions.None;
Match match = new Regex(format, options).Match(data);
if (tokenCount != (match.Groups.Count - 1))
{
values = new string[] { };
return false;
}
else
{
values = new string[tokenCount];
for (int index = 0; index < tokenCount; index++)
values[index] =
match.Groups[string.Format("group{0}", index)].Value;
return true;
}
}
}
You can't unformat because information is lost. String.Format is a "destructive" algorithm, which means you can't (always) go back.
Create a new class inheriting from string, where you add a member that keeps track of the "{0}-{1}" and the { "asdf", "qwer" }, override ToString(), and modify a little your code.
If it becomes too tricky, just create the same class, but not inheriting from string and modify a little more your code.
IMO, that's the best way to do this.
It's simply not possible in the generic case. Some information will be "lost" (string boundaries) in the Format method. Assume:
String.Format("{0}-{1}", "hello-world", "stack-overflow");
How would you "Unformat" it?
Assuming "-" is not in the original strings, can you not just use Split?
var arr2 = formattedString.Split('-');
Note that this only applies to the presented example with an assumption. Any reverse algorithm is dependent on the kind of formatting employed; an inverse operation may not even be possible, as noted by the other answers.
A simple solution might be to
replace all format tokens with (.*)
escape all other special charaters in format
make the regex match non-greedy
This would resolve the ambiguities to the shortest possible match.
(I'm not good at RegEx, so please correct me, folks :))
After formatting, you can put the resulting string and the array of objects into a dictionary with the string as key:
Dictionary<string,string []> unFormatLookup = new Dictionary<string,string []>
...
var arr = new string [] {"asdf", "qwer" };
var res = string.Format(format, arr);
unFormatLookup.Add(res,arr);
and in Unformat method, you can simply pass a string and look up that string and return the array used:
string [] Unformat(string res)
{
string [] arr;
unFormatLoopup.TryGetValue(res,out arr); //you can also check the return value of TryGetValue and throw an exception if the input string is not in.
return arr;
}