Cadenas

Actualización: noviembre 2007

Una cadena de C# es un grupo de uno o más caracteres declarados mediante la palabra clave string, que es un método abreviado del lenguaje C# para la clase System.String. Las cadenas de C# son mucho más fáciles de utilizar y mucho menos propensas a errores de programación que las matrices de caracteres de C o C++.

Un literal de cadena se declara utilizando las comillas, como se muestra en el siguiente ejemplo:

string greeting = "Hello, World!";

Puede extraer subcadenas y concatenar cadenas de la siguiente manera:

string s1 = "A string is more ";
string s2 = "than the sum of its chars.";

// Concatenate s1 and s2. This actually creates a new
// string object and stores it in s1, releasing the
// reference to the original object.
s1 += s2;

System.Console.WriteLine(s1);
// Output: A string is more than the sum of its chars.

Los objetos String son inmutables y, una vez creados, no se pueden cambiar. Los métodos que actúan sobre las cadenas, devuelven los nuevos objetos de cadena. De esta forma, por motivos de rendimiento, las grandes cantidades de concatenación o de manipulación de cadenas implicadas se deben llevar a cabo con la clase StringBuilder, como se muestra en los siguientes ejemplos de código.

Trabajar con cadenas

Carácter de escape

Los caracteres de escape como "\n" y (nueva línea) y "\t" (tabulador) se pueden incluir en cadenas. La línea:

string columns = "Column 1\tColumn 2\tColumn 3";
//Output: Column 1        Column 2        Column 3

string rows = "Row 1\r\nRow 2\r\nRow 3";
/* Output:
  Row 1
  Row 2
  Row 3
*/

string title = "\"The \u00C6olean Harp\", by Samuel Taylor Coleridge";
//Output: "The Æolean Harp", by Samuel Taylor Coleridge

equivale a:

Hello

World!

Si desea incluir una barra diagonal inversa, ésta debe estar precedida de otra barra diagonal inversa. La cadena siguiente:

         string filePath = @"C:\Users\scoleridge\Documents\";
         //Output: C:\Users\scoleridge\Documents\

         string text = @"My pensive SARA ! thy soft cheek reclined
Thus on mine arm, most soothing sweet it is
To sit beside our Cot,...";
         /* Output:
         My pensive SARA ! thy soft cheek reclined
            Thus on mine arm, most soothing sweet it is
            To sit beside our Cot,... 
         */

         string quote = @"Her name was ""Sara.""";
         //Output: Her name was "Sara."

equivale a:

\\My Documents\

El símbolo @

El símbolo @ especifica que se deben omitir los caracteres de escape y saltos de línea cuando se crea la cadena. Las dos cadenas siguientes son, por consiguiente, idénticas:

string p1 = "\\\\My Documents\\My Files\\";
string p2 = @"\\My Documents\My Files\";

ToString()

Todos los tipos de datos integrados de C# ofrecen el método ToString, que convierte un valor en una cadena. Este método se puede utilizar para convertir valores numéricos en cadenas de la siguiente manera:

int year = 1999;
string msg = "Eve was born in " + year.ToString();
System.Console.WriteLine(msg);  // outputs "Eve was born in 1999"

Tener acceso a los caracteres individuales

Se obtiene acceso a los caracteres individuales de una cadena mediante los métodos Substring, Replace, Split y Trim.

string s3 = "Visual C# Express";
System.Console.WriteLine(s3.Substring(7, 2));
// Output: "C#"

System.Console.WriteLine(s3.Replace("C#", "Basic"));
// Output: "Visual Basic Express"

// Index values are zero-based
int index = s3.IndexOf("C");
// index = 7

También es posible copiar los caracteres en una matriz de caracteres, tal como se muestra a continuación:

string question = "hOW DOES mICROSOFT wORD DEAL WITH THE cAPS lOCK KEY?";
System.Text.StringBuilder sb = new System.Text.StringBuilder(question);

for (int j = 0; j < sb.Length; j++)
{
    if (System.Char.IsLower(sb[j]) == true)
        sb[j] = System.Char.ToUpper(sb[j]);
    else if (System.Char.IsUpper(sb[j]) == true)
        sb[j] = System.Char.ToLower(sb[j]);
}
// Store the new string.
string corrected = sb.ToString();
System.Console.WriteLine(corrected);
// Output: How does Microsoft Word deal with the Caps Lock key?            

Puede obtener acceso a los caracteres individuales de una cadena con un índice:

string s5 = "Printing backwards";

for (int i = 0; i < s5.Length; i++)
{
    System.Console.Write(s5[s5.Length - i - 1]);
}
// Output: "sdrawkcab gnitnirP"

Cambiar mayúsculas y minúsculas

Para cambiar las letras en una cadena a mayúsculas o minúsculas, se utiliza ToUpper() o ToLower(), de la siguiente forma:

string s6 = "Battle of Hastings, 1066";

System.Console.WriteLine(s6.ToUpper());
// outputs "BATTLE OF HASTINGS 1066"
System.Console.WriteLine(s6.ToLower());
// outputs "battle of hastings 1066"

Comparaciones

La mejor forma de comparar dos cadenas no traducidas es utilizar el método Equals con StringComparison.Ordinal y StringComparison.OrdinalIgnoreCase.

// Internal strings that will never be localized.
string root = @"C:\users";
string root2 = @"C:\Users";

// Use the overload of the Equals method that specifies a StringComparison.
// Ordinal is the fastest way to compare two strings.
bool result = root.Equals(root2, StringComparison.Ordinal);

Console.WriteLine("Ordinal comparison: {0} and {1} are {2}", root, root2,
                    result ? "equal." : "not equal.");

// To ignore case means "user" equals "User". This is the same as using
// String.ToUpperInvariant on each string and then performing an ordinal comparison.
result = root.Equals(root2, StringComparison.OrdinalIgnoreCase);
Console.WriteLine("Ordinal ignore case: {0} and {1} are {2}", root, root2,
                     result ? "equal." : "not equal.");

// A static method is also available.
bool areEqual = String.Equals(root, root2, StringComparison.Ordinal);


// String interning. Are these really two distinct objects?
string a = "The computer ate my source code.";
string b = "The computer ate my source code.";

// ReferenceEquals returns true if both objects
// point to the same location in memory.
if (String.ReferenceEquals(a, b))
    Console.WriteLine("a and b are interned.");
else
    Console.WriteLine("a and b are not interned.");

// Use String.Copy method to avoid interning.
string c = String.Copy(a);

if (String.ReferenceEquals(a, c))
    Console.WriteLine("a and c are interned.");
else
    Console.WriteLine("a and c are not interned.");

Los objetos String también tienen un método CompareTo() que devuelve un valor entero, basado en si una cadena es menor < o mayor > que otra. Al comparar las cadenas, se utiliza el valor Unicode, y las minúsculas tienen un valor menor que las mayúsculas.

// Enter different values for string1 and string2 to
// experiement with behavior of CompareTo
string string1 = "ABC";
string string2 = "abc";

int result2 = string1.CompareTo(string2);

if (result2 > 0)
{
    System.Console.WriteLine("{0} is greater than {1}", string1, string2);
}
else if (result2 == 0)
{
    System.Console.WriteLine("{0} is equal to {1}", string1, string2);
}
else if (result2 < 0)
{
    System.Console.WriteLine("{0} is less than {1}", string1, string2);
}
// Output: ABC is less than abc

Para buscar una cadena dentro de otra, utilice IndexOf(). IndexOf() devuelve -1 si la cadena de búsqueda no se encuentra; en caso contrario devuelve el índice de la primera posición de la cadena, con base cero.

// Date strings are interpreted according to the current culture.
// If the culture is en-US, this is interpreted as "January 8, 2008",
// but if the user's computer is fr-FR, this is interpreted as "August 1, 2008"
string date = "01/08/2008";
DateTime dt = Convert.ToDateTime(date);            
Console.WriteLine("Year: {0}, Month: {1}, Day: {2}", dt.Year, dt.Month, dt.Day);

// Specify exactly how to interpret the string.
IFormatProvider culture = new System.Globalization.CultureInfo("fr-FR", true);

// Alternate choice: If the string has been input by an end user, you might 
// want to format it according to the current culture:
// IFormatProvider culture = System.Threading.Thread.CurrentThread.CurrentCulture;
DateTime dt2 = DateTime.Parse(date, culture, System.Globalization.DateTimeStyles.AssumeLocal);
Console.WriteLine("Year: {0}, Month: {1}, Day {2}", dt2.Year, dt2.Month, dt2.Day);

/* Output (assuming first culture is en-US and second is fr-FR):
    Year: 2008, Month: 1, Day: 8
    Year: 2008, Month: 8, Day 1
 */

Dividir una cadena en subcadenas

Dividir una cadena en subcadenas es una tarea de programación común, semejante a dividir una frase en sus respectivas palabras. El método Split() toma una matriz de char de delimitadores (por ejemplo, un carácter de espacio) y devuelve una matriz de subcadenas. Para obtener acceso a esta matriz con foreach:

string numString = "1287543"; //"1287543.0" will return false for a long
long number1 = 0;
bool canConvert = long.TryParse(numString, out number1);
if (canConvert == true)
  Console.WriteLine("number1 now = {0}", number1);
else
  Console.WriteLine("numString is not a valid long");

byte number2 = 0;
numString = "255"; // A value of 256 will return false
canConvert = byte.TryParse(numString, out number2);
if (canConvert == true)
  Console.WriteLine("number2 now = {0}", number2);
else
  Console.WriteLine("numString is not a valid byte");

decimal number3 = 0;
numString = "27.3"; //"27" is also a valid decimal
canConvert = decimal.TryParse(numString, out number3);
if (canConvert == true)
  Console.WriteLine("number3 now = {0}", number3);
else
  Console.WriteLine("number3 is not a valid decimal");            

Este código genera cada palabra en una línea separada de la siguiente forma:

The

cat

sat

on

the

mat.

Utilizar StringBuilder

La clase StringBuilder crea un búfer de cadena que proporciona el mejor rendimiento si el programa realiza una gran manipulación de cadenas. La clase StringBuilder también permite reasignar caracteres individuales, algo que el tipo de datos de cadena integrado no admite.

En este ejemplo, se crea un objeto StringBuilder y el contenido se agrega poco a poco utilizando el método Append.

class TestStringBuilder
{
    static void Main()
    {
        System.Text.StringBuilder sb = new System.Text.StringBuilder();

        // Create a string composed of numbers 0 - 9
        for (int i = 0; i < 10; i++)
        {
            sb.Append(i.ToString());
        }
        System.Console.WriteLine(sb);  // displays 0123456789

        // Copy one character of the string (not possible with a System.String)
        sb[0] = sb[9];

        System.Console.WriteLine(sb);  // displays 9123456789
    }
}

Vea también

Tareas

Cómo: Generar literales de cadena multilínea (Visual C#)

Cómo: Buscar una cadena en una matriz de cadenas

Cómo: Buscar en una cadena

Conceptos

Manual del lenguaje C#

Tipos de datos integrados (Visual C# Express)

Referencia

string (Referencia de C#)