316

Is there a reason for this? I am asking because if you needed to use lots of empty chars then you get into the same situation as you would when you use lots of empty strings.

Edit: The reason for this usage was this:

myString.Replace ('c', '')

So remove all instances of 'c's from myString.

Joan Venge
  • 315,713
  • 212
  • 479
  • 689
  • 1
    Yeah I used that word for lack of a better word. i.e. the recommended way of using String.Empty instead of "". – Joan Venge Sep 08 '10 at 17:51
  • Thanks, do you know why it's not recommended anymore? Is it because of the compiler does it for you? – Joan Venge Sep 08 '10 at 18:02
  • 3
    If you're concerned about accidentally mistyping '' sometimes, why not just simply **wrap the functionality in an extension method** along the lines of `RemoveAll(this string s, params char[] toRemove)`? The intent will be clearly communicated and you will not risk mistyping anything. – bzlm Oct 05 '10 at 11:38
  • 12
    @Henk - The only reason I use string.Empty is because I find the null object provided by Empty expresses intent better than empty quotes. Empty quotes could result from a merge problem, or a bungled thought, or it could be the actual intent of that code, whereas Empty explicitly tells me that the developer intended for that string not to have data. – Ritch Melton May 21 '11 at 00:33
  • 3
    There is a difference between "" and the string.Empty. Not that anyone care, really, but "" creates an object, whereas string.Empty makes use of one already made. But again, it is so small, that only special situations it would make a diference – marcelo-ferraz Nov 30 '11 at 12:35
  • 4
    @marcelo-ferrazm, about _`""` creates an object_ : No, it does not. – H H Apr 22 '19 at 17:43
  • Related post - [How does one represent the empty char?](https://stackoverflow.com/q/18410234/465053) – RBT Sep 24 '21 at 06:22

23 Answers23

319

There's no such thing as an empty char. The closest you can get is '\0', the Unicode "null" character. Given that you can embed that within string literals or express it on its own very easily, why would you want a separate field for it? Equally, the "it's easy to confuse "" and " "" arguments don't apply for '\0'.

If you could give an example of where you'd want to use it and why you think it would be better, that might help...

samus
  • 6,102
  • 6
  • 31
  • 69
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 2
    Isn't the \0 the 'end of the byte array'-character? Or am I confusing with something else? – Bertvan Sep 08 '10 at 17:47
  • 5
    @Bertvan: Why would there be a *character* at the end of a *byte* array? It's used for "null terminated" strings though, yes. – Jon Skeet Sep 08 '10 at 17:48
  • @Bertvan That is true for C strings not for C# strings – Carlos Muñoz Sep 08 '10 at 17:48
  • 1
    Thanks, didn't realize you couldn't have an empty char. I ran into this when I was trying to replace all instances of say 'c' with '', so essentially getting rid of all 'c's in a string. Had to use the string overload of string.Replace. – Joan Venge Sep 08 '10 at 17:49
  • 46
    Char.MinValue is better than '\0' – Aliostad Sep 08 '10 at 17:50
  • @Aliostad: In what way? It's a heck of a lot uglier to ember in a string literal. Mind you, I don't use string.Empty either. – Jon Skeet Sep 08 '10 at 17:53
  • @Jon: Hi Jon. A big fan of yours, listened to your podcast it was great. On the subject, you get intellisence on Char.MinValue which I prefer. That is what constants (or static readonly)s are for - IMHO. – Aliostad Sep 08 '10 at 17:57
  • 10
    @Aliostad: Out of interest, if there was a similar field for `Int32.Zero`, would you use that instead of the literal 0? If not, what's the difference here? – Jon Skeet Sep 08 '10 at 18:17
  • 1
    @Aliostad: I disagree; constants are for values that have meaning. An empty string, dividing by 2, etc. have meaning that is fully evident by their usage. I don't need a constant for a null character or empty string any more than I need `const double ONE_HALF = .5`. – Adam Robinson Sep 08 '10 at 18:19
  • 8
    @Adam, @Jon -- what is the code for bell? Or backspace better, think think... Or maybe instead of thinking it is just better to write Char.Backspace? Another reason -- you say it is better to write '0' for terminator, instead, say Char.Terminator, however it is not -- it is too easy to make a typo (fully compiled, see above), but try to write Char.Termnator. There are enough reasons for me to avoid non-checkable, raw values (space missions failed because of stupid typos like that). – greenoldman Sep 09 '10 at 06:19
  • @Macias: Except of course `Char.Backspace` doesn't exist, nor does `Char.Terminator`. For backspace I'd write `\b` - I'd forgotten about `\a` for bell, but I knew it was Unicode U+0007, so I'd write `\u0007`. If you know the number and want to make that obvious, the `\uxxxx` format is pretty clear IMO. Note that in this case using `Char.MinValue` requires you to a) know that you want character 0, b) know that `Char.MinValue` is 0. I'd argue that if you know the first point, then `\u0000` is a clear way of writing it, even if you don't know about `\0`. – Jon Skeet Sep 09 '10 at 06:56
  • @macias: Out of interest, have you introduced your own constant for backslash, or do you just write `\\` like everyone else? If not, what's the difference here? (One minor point to note: I *do* recommend that folks avoid the `\x....` escape sequence... that's horribly context-sensitive due to the length being variable.) I should point out that I can't remember the last time I needed to use `\0`, bell *or* backspace... – Jon Skeet Sep 09 '10 at 06:58
  • 1
    @Jon, as comment to you (disclaimer: sorry for obscenity, if any) -- \4758\7732\8575\47582\4757\1235\4857\4576... ;-) (btw. I didn't vote for MinChar, but for **constants**, and introducing new constants is not rocket-science). – greenoldman Sep 09 '10 at 07:13
  • @macias: Constants in general, yes. I was never arguing against them. Constants in this case - no, IMO. Using literals and escaping in moderation is absolutely fine. – Jon Skeet Sep 09 '10 at 08:10
  • 1
    @Jon, of course I write "hello", not Char.H+Char.E+...but despise I sin (\*) writing "\n" it is bad (IMHO). If you put the software maintaince in perspective of decades (!), every tiny hole can cause serious damage. It is better to be precise and write +Char.Terminator every time, then once make a typo '0' and be very sorry later. Or I put it this way -- is there a purpose for producing code that is less manageable and weaker that it **could** be for almost free? (*) Seriously, after this discussion I will type constant for every \n from now on, howgh! ;-) – greenoldman Sep 09 '10 at 08:50
  • The closest analogy of `String.Empty` is `Char.MinValue`, so I think this latter field ought to be _mentioned_ in the answer (not just in these comments), given the question header. But I agree it is easier and better to use `'\0'`, and that is what I would do in any case. Note that `Char.MinValue` is a **`const`** field, and therefore the two options lead to the same IL. That's different from the `String.Empty`-versus-`""` question because `String.Empty` is _not_ constant. – Jeppe Stig Nielsen May 10 '13 at 21:07
  • The place I just wanted to use it was when trying `myStringWtihSpaces.Replace(' ', '');` – StingyJack Jan 03 '19 at 04:02
  • @StingyJack: You'd do that using strings instead of characters: `myStringWithSpaces.Repace(" ", "")` – Jon Skeet Jan 03 '19 at 07:01
  • Yeah, but that's not the first overload suggested by autocomplete. – StingyJack Jan 03 '19 at 13:42
  • @StingyJack: I'm not quite sure what your point is. `string.Replace(char, char)` is fine to replace one character with another, but it won't work when trying to replace one character with zero characters... there's simply no `char` value which is "not a character". – Jon Skeet Jan 03 '19 at 13:46
  • @ChiddoLuna: Please do not use editing to completely replace an existing answer. Editing is for tweaking, fixing formatting etc - not for completely changing, leaving no trace of the original answer. (And no, replacing a character with U+0000 does not *remove* the character from the string - you end up with U+0000 in the string, which in many cases would be disastrous.) – Jon Skeet Mar 27 '20 at 22:05
  • @AnjanKumarGJ: Please provide *information* rather than multiple exclamation marks. You probably actually want to ask a new question, following my suggestions here: https://codeblog.jonskeet.uk/2010/08/29/writing-the-perfect-question/ – Jon Skeet Nov 06 '20 at 14:24
  • @AnjanKumarGJ: Nope, that isn't *nearly* enough context. We don't know what you're trying to do, or really what you've tried, or what happens. I don't understand the last two sentences of your comment either. To repeat my previous suggestion, please ask a new question, with *much* more clarity than that. – Jon Skeet Nov 06 '20 at 18:08
  • Because I need trim the empty char like: `"abc; ".Trim(';', '')`. – huang May 17 '22 at 18:45
  • @JoeHuang: There's no such thing as "the empty char", just as my answer says. (That code won't compile, precisely *because* there's no such thing as "the empty char".) If you can specify your requirements without referring to a non-existent concept, please ask a new question with all the details. – Jon Skeet May 17 '22 at 19:09
  • I found `' '` works. – huang May 17 '22 at 20:53
  • @JoeHuang: Well that's a space, which is a very different thing. There are plenty of other whitespace characters, too... – Jon Skeet May 17 '22 at 21:19
220

The reason for this usage was this: myString.Replace ('c', '') So remove all instances of 'c' from myString.

To remove a specific char from a string you can use the string overload:

 myString = myString.Replace ("c", String.Empty);

Your statement

 myString.Replace ('c', '\0')

Won't remove any characters. It will just replace them with '\0' (End-Of-String, EOS), with varying consequences. Some string operations might stop when encountering an EOS but in .NET most actions will treat it like any other char. Best to avoid '\0' as much as possible.

H H
  • 263,252
  • 30
  • 330
  • 514
100

A char, unlike a string, is a discrete thing with a fixed size. A string is really a container of chars.

So, Char.Empty doesn't really make sense in that context. If you have a char, it's not empty.

Joe
  • 41,484
  • 20
  • 104
  • 125
  • 5
    Exactly right. It makes sense to ask if a container is empty or not. It makes no sense to ask of a int or float or char is empty. – T.E.D. Sep 08 '10 at 18:10
  • 1
    @Joe: Then how can a string be empty if a string is a collection of (non-empty) chars? Probably stupid, sorry... – user1477388 Jan 29 '13 at 16:32
  • 17
    Because a string isn't the individual objects, it's the collection. Think of a bucket of rocks. I can't have an empty rock. But I can have an empty bucket. – Joe Jan 29 '13 at 17:42
  • 2
    I would phrase it as "a char is a primitive, value type, and a string is non-primitive, reference type". – samus Aug 26 '13 at 14:26
37

There's no such thing as an empty character. It always contains something. Even '\0' is a character.

Philippe Leybaert
  • 168,566
  • 31
  • 210
  • 223
33

Use Char.MinValue which works the same as '\0'. But be careful it is not the same as String.Empty.

Aliostad
  • 80,612
  • 21
  • 160
  • 208
  • 1
    Thanks, haven't seen that before. Do you know if it work in myString.Replace('c', Char.MinValue)? I should give it a try. – Joan Venge Sep 08 '10 at 17:50
20

You could use nullable chars.

char? c
paquetp
  • 1,639
  • 11
  • 19
13

If you don't need the entire string, you can take advantage of the delayed execution:

public static class StringExtensions
{
    public static IEnumerable<char> RemoveChar(this IEnumerable<char> originalString, char removingChar)
    {
        return originalString.Where(@char => @char != removingChar);
    }
}

You can even combine multiple characters...

string veryLongText = "abcdefghijk...";

IEnumerable<char> firstFiveCharsWithoutCsAndDs = veryLongText
            .RemoveChar('c')
            .RemoveChar('d')
            .Take(5);

... and only the first 7 characters will be evaluated :)

EDIT: or, even better:

public static class StringExtensions
{
    public static IEnumerable<char> RemoveChars(this IEnumerable<char> originalString,
        params char[] removingChars)
    {
        return originalString.Except(removingChars);
    }
}

and its usage:

        var veryLongText = "abcdefghijk...";
        IEnumerable<char> firstFiveCharsWithoutCsAndDs = veryLongText
            .RemoveChars('c', 'd')
            .Take(5)
            .ToArray(); //to prevent multiple execution of "RemoveChars"
Notoriousxl
  • 1,540
  • 1
  • 16
  • 27
  • @Joan: thanks... even if "Genius" it's a bit exaggerated :P (I don't know about its performances when removingChars will become a big array...) – Notoriousxl Sep 08 '10 at 19:59
  • 1
    Yesterday I forgot: pay attention on how you are using the result variable "firstFiveCharsWithoutCsAndDs". If you don't want to pass it to another "yield" method (like those of LINQ), call immediately a ".ToArray()" after the "Take(5)"... otherwise, the "RemoveChars + Take" chain will be executed every time you access the variable in a "traditional" fashion (for example, every you call a "Count()" on it, or when you traverse it in a foreach without "yield return") – Notoriousxl Sep 09 '10 at 19:07
  • +1 nice thinking. but this can't get as maintainable or efficient as the basic approach :) – nawfal Feb 05 '13 at 09:51
  • 1
    @nawfal efficiency-wise you're right, but I think that myString.Except("c") is more declarative than myString.Replace('c', '') :P (and it scales pretty well: myString.Except("aeiou")) – Notoriousxl Feb 05 '13 at 18:28
13
myString = myString.Replace('c'.ToString(), "");

OK, this is not particularly elegant for removing letters, since the .Replace method has an overload that takes string parameters. But this works for removing carriage returns, line feeds, tabs, etc. This example removes tab characters:

myString = myString.Replace('\t'.ToString(), "");
Mike Taverne
  • 9,156
  • 2
  • 42
  • 58
12

Not an answer to your question, but to denote a default char you can use just

default(char)

which is same as char.MinValue which in turn is same as \0. One shouldn't use it for something like an empty string though.

nawfal
  • 70,104
  • 56
  • 326
  • 368
8

The same reason there isn't an int.Empty. Containers can be empty, scalar values cannot. If you mean 0 (which is not empty), then use '\0'. If you mean null, then use null :)

Pang
  • 9,564
  • 146
  • 81
  • 122
tenfour
  • 36,141
  • 15
  • 83
  • 142
6

A char is a value type, so its value cannot be null. (Unless it is wrapped in a Nullable container).

Since it can't be null, in contains some numeric code and each code is mapped to some character.

epotter
  • 7,631
  • 7
  • 63
  • 88
3

Doesn't answer your first question - but for the specific problem you had, you can just use strings instead of chars, right?:

myString.Replace("c", "")

There a reason you wouldn't want to do that?

Ian Grainger
  • 5,148
  • 3
  • 46
  • 72
3

If you look at the documentation for Replace(String, String) overload for String.Replace you can see in the remarks section that if the second argument is a null then it will remove all instances of what you specified. Therefore if you just use myString = myString.Replace("c", null); it will delete every c in the string.

ElasticEel
  • 31
  • 2
2

You can also rebuild your string character by character, excluding the characters that you want to get rid of.

Here's an extension method to do this:

    static public string RemoveAny(this string s, string charsToRemove)
    {
        var result = "";
        foreach (var c in s)
            if (charsToRemove.Contains(c))
                continue;
            else
                result += c;

        return result;
    }

It's not slick or fancy, but it works well.

Use like this:

string newString = "My_String".RemoveAny("_"); //yields "MyString"
C. Tewalt
  • 2,271
  • 2
  • 30
  • 49
1

If you want to eliminate the empty char in string, the following will work. Just convert to any datatype representation you want.

private void button1_Click(object sender, EventArgs e)
{

    Int32 i;

    String name;

    Int32[] array_number = new int[100];

    name = "1 3  5  17   8    9    6";

    name = name.Replace(' ', 'x');

    char[] chr = name.ToCharArray();


    for (i = 0; i < name.Length; i++)
    {
        if ((chr[i] != 'x'))
        {
            array_number[i] = Convert.ToInt32(chr[i].ToString());
            MessageBox.Show(array_number[i].ToString());
        }
    }
}
Pang
  • 9,564
  • 146
  • 81
  • 122
Alexander Zaldostanov
  • 2,907
  • 4
  • 30
  • 39
1

In terms of C# language, the following may not make much sense. And this is not a direct answer to the question. But following is what I did in one of my business scenarios.

char? myCharFromUI = Convert.ToChar(" ");
string myStringForDatabaseInsert = myCharFromUI.ToString().Trim();
if (String.IsNullOrEmpty(myStringForDatabaseInsert.Trim()))
{
    Console.Write("Success");
}

The null and white space had different business flows in my project. While inserting into database, I need to insert empty string to the database if it is white space.

Pang
  • 9,564
  • 146
  • 81
  • 122
LCJ
  • 22,196
  • 67
  • 260
  • 418
1

I know this one is pretty old, but I encountered an issue recently with having to do multiple replacements to make a file name safe. First, in the latest .NET string.Replace function null is the equivalent to empty character. Having said that, what is missing from .Net is a simple replace all that will replace any character in an array with the desired character. Please feel free to reference the code below (runs in LinqPad for testing).

// LinqPad .ReplaceAll and SafeFileName
void Main()
{

    ("a:B:C").Replace(":", "_").Dump();                     // can only replace 1 character for one character => a_B_C
    ("a:B:C").Replace(":", null).Dump();                    // null replaces with empty => aBC
    ("a:B*C").Replace(":", null).Replace("*",null).Dump();  // Have to chain for multiples 

    // Need a ReplaceAll, so I don't have to chain calls


    ("abc/123.txt").SafeFileName().Dump();
    ("abc/1/2/3.txt").SafeFileName().Dump();
    ("a:bc/1/2/3.txt").SafeFileName().Dump();
    ("a:bc/1/2/3.txt").SafeFileName('_').Dump();
    //("abc/123").SafeFileName(':').Dump(); // Throws exception as expected

}


static class StringExtensions
{

    public static string SafeFileName(this string value, char? replacement = null)
    {
        return value.ReplaceAll(replacement, ':','*','?','"','<','>', '|', '/', '\\');
    }

    public static string ReplaceAll(this string value, char? replacement, params char[] charsToGo){

        if(replacement.HasValue == false){
                return string.Join("", value.AsEnumerable().Where(x => charsToGo.Contains(x) == false));
        }
        else{

            if(charsToGo.Contains(replacement.Value)){
                throw new ArgumentException(string.Format("Replacement '{0}' is invalid.  ", replacement), "replacement");
            }

            return string.Join("", value.AsEnumerable().Select(x => charsToGo.Contains(x) == true ? replacement : x));
        }

    }

}
Jim
  • 864
  • 1
  • 8
  • 16
1

If you want to remove characters that satisfy a specific condition, you may use this:

string s = "SoMEthInG";
s = new string(s.Where(c => char.IsUpper(c)).ToArray());

(This will leave only the uppercase characters in the string.)

In other words, you may "use" the string as an IEnumerable<char>, make changes on it and then convert it back to a string as shown above.

Again, this enables to not only remove a specific char because of the lambda expression, although you can do so if you change the lambda expression like this: c => c != 't'.

florien
  • 487
  • 5
  • 16
1

here is how we do it : myString.Replace ('''.ToString(), "");

-1

How about BOM, the magical character Microsoft adds to start of files (at least XML)?

  • The wording on Wikipedia here is quite unfortunate; the BOM is not a character in this context. And what is your question exactly? :) – bzlm Oct 05 '10 at 11:36
  • @onemach, so, whether `myString.Replace ('c', '')` could be achieved by `myString.Replace ('c', UTF_BOM)`. Then I'd say the answer is "how *not* about...". – bzlm Feb 21 '12 at 09:38
-1
public static string QuitEscChars(this string s) 
{
    return s.Replace(((char)27).ToString(), "");
}
BDL
  • 21,052
  • 22
  • 49
  • 55
Ángel Ibáñez
  • 329
  • 1
  • 6
  • 1
    Hello! While this code may solve the question, [including an explanation](https://meta.stackexchange.com/q/114762) of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please [edit] your answer to add explanations and give an indication of what limitations and assumptions apply. – Brian61354270 Jul 30 '20 at 13:56
-3

use

myString.Replace ("c", "")
Chintan
  • 126
  • 1
  • 3
-4

Easiest way to blanket remove a character from string is to Trim it

cl = cl.Trim(' ');

Removes all of the spaces in a string

MrSmudge
  • 46
  • 3
  • This is helpful if one wants to use use .Replace('c', ' ') with the downside of removing other whitespaces. But its more helpful than lots of other answers given. – Jan Feb 27 '18 at 09:30
  • 1
    No this is wrong! Trim only remove chars from the start and end of a string not in the middle – userSteve Jan 10 '19 at 15:39