FAQ C#Consultez toutes les FAQ

Nombre d'auteurs : 41, nombre de questions : 272, dernière mise à jour : 1er novembre 2017  Ajouter une question

 

Cette FAQ a été réalisée pour répondre aux questions les plus fréquemment posées concernant C# sur le forum Développement DotNET

Je tiens à souligner qu'elle ne garantit en aucun cas que les informations qu'elle contient sont correctes ; les auteurs font le maximum, mais l'erreur est humaine. Si vous trouvez une erreur, ou que vous souhaitez devenir rédacteur, lisez ceci .

Sur ce, je vous souhaite une bonne lecture.

Commentez cette FAQ : Commentez


Sommaire.NET FrameworkChaines de caractères et formatage des objets (17)
précédent sommaire suivant
 

Il suffit d'utiliser la propriété Environment.NewLine :

Code c# : Sélectionner tout
string monTexte = "blablabla" + Environment.NewLine + "blablabla ...";
Il vaut mieux utiliser cette propriété que d'écrire explicitement les caractères "\n" ou "\r\n", car le retour à la ligne « standard » est différent selon les systèmes d'exploitation. Environment.NewLine renvoie toujours le retour à la ligne standard du système d'exploitation actuel.

Mis à jour le 31 octobre 2006 dev01 tomlev

Code c# : Sélectionner tout
char monCaractère = '\0';
C'est aussi simple que cela

Mis à jour le 2 novembre 2004 Louis-Guillaume Morand

Lorsqu'on souhaite construire une chaine de caractères à partir d'un nombre variable d'objets, on utilise fréquemment l'opérateur de concaténation « + » :

Code c# : Sélectionner tout
1
2
3
4
5
6
7
8
byte[] data = new byte[] { 4, 8, 15, 16, 23, 42 }; 
string s = string.Empty; 
foreach (var item in data) 
{ 
    s += item; 
    s += ","; 
} 
Console.WriteLine (s);
Cependant, si cette méthode est acceptable pour un petit nombre d'objets, elle devient très inefficace dès lors que le nombre d'objets est important : en effet, les chaines étant immuable en .NET, chaque concaténation crée une nouvelle instance de String, et ces instances sont de plus en plus grandes, ce qui cause une forte augmentation de la consommation de mémoire. Puisque ces chaines sont temporaires, elles sont ramassées par le garbage collector quand la mémoire utilisée devient trop importante, mais cette opération est coûteuse en temps processeur.

Pour pallier ce problème, le .NET Framework fournit une classe StringBuilder qui sert, comme son nom l'indique, à construire des chaines de caractères. Son utilisation est très simple : on crée une instance de StringBuilder, et on y ajoute du texte à l'aide de la méthode Append ou de ses variantes. Une fois la construction terminée, on récupère la chaine construite à l'aide de la méthode ToString :

Code c# : Sélectionner tout
1
2
3
4
5
6
7
8
9
byte[] data = new byte[] { 4, 8, 15, 16, 23, 42 }; 
StringBuilder sb = new StringBuilder(); 
foreach (var item in data) 
{ 
    sb.Append(item); 
    sb.Append(","); 
} 
string s = sb.ToString(); 
Console.WriteLine (s);
Contrairement aux chaines de caractères, le StringBuilder est modifiable : chaque appel à Append ajoute du texte dans un buffer existant, au lieu de réallouer de la mémoire à chaque fois. Le buffer est automatiquement réalloué quand sa limite de capacité est atteinte.

La classe StringBuilder fournit aussi d'autres méthodes utiles :

  • AppendLine : ajoute un saut de ligne, ou du texte suivi d'un saut de ligne
  • AppendFormat : ajoute du texte en formatant les objets passés en paramètre, à la façon de String.Format
  • Insert : insère du texte à la position spécifiée
  • Remove : supprime un ou des caractères à la position spécifiée
  • Replace : remplace toutes les occurrences d'une chaine par une autre chaine

Enfin, il est intéressant de noter que toutes les méthodes qui modifient le StringBuilder renvoie l'instance courante de StringBuilder, ce qui permet de chainer les appels :

Code c# : Sélectionner tout
1
2
3
4
sb.AppendFormat(" Hello {0} !", name) 
  .AppendLine() 
  .Replace("Hello", "Bonjour") 
  .Remove(0, 1);

Mis à jour le 11 août 2010 tomlev

Code c# : Sélectionner tout
1
2
3
4
5
6
7
  
public string Strstr(string haystack, string needle) 
{ 
    int firstIndex = haystack.IndexOf(needle); 
  
    return haystack.Substring(firstIndex);  
}

Mis à jour le 10 juin 2008 Philippe Vialatte

Code c# : Sélectionner tout
1
2
3
4
5
6
public static string Strstr(this string haystack, string needle) 
{ 
    int firstIndex = haystack.IndexOf(needle); 
  
    return haystack.Substring(firstIndex); 	 
}

Mis à jour le 10 juin 2008 SaumonAgile

Code c# : Sélectionner tout
1
2
3
4
5
public static string StrstrRev(string haystack, string needle) 
{ 
    int firstIndex = haystack.LastIndexOf(needle); 
    return haystack.Substring(firstIndex);  
}

Mis à jour le 10 juin 2008 Philippe Vialatte

Code c# : Sélectionner tout
1
2
3
4
5
public static string StrstrRev(this string haystack, string needle) 
{	 
    int firstIndex = haystack.LastIndexOf(needle); 
    return haystack.Substring(firstIndex); 	 
}

Mis à jour le 10 juin 2008 SaumonAgile

Code c# : Sélectionner tout
1
2
3
4
5
public string Reverse(string input) 
{ 
    char[] inputArray = input.ToCharArray(); 
    Array.Reverse(inputArray); 
    return new string(inputArray);

Mis à jour le 10 juin 2008 Philippe Vialatte

Code c# : Sélectionner tout
1
2
3
4
5
6
public static void Reverse(this string input) 
{ 
    char[] inputArray = input.ToCharArray(); 
    Array.Reverse(inputArray); 
    return new string(inputArray);  
}

Mis à jour le 10 juin 2008 SaumonAgile

Code c# : Sélectionner tout
string chaine = new string('c', 10);

Mis à jour le 10 juin 2008 Philippe Vialatte

On utilise pour cela le caractère de contrôle "\b", qui indique une limite de mot, et l'option IgnoreCase.

Un exemple vaut mieux qu'un long discours :

Code c# : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
using System.Text.RegularExpressions; 
...           
  
	string monTexte = "Une astuce de dvp.com ! Une astuce de DVP.com !"; 
  
	// Paramétrage de notre expression régulière : 
	// Ici on spécifie que l'on ne veut pas tenir compte dela casse du 
	// texte dans nos remplacements. 
	Regex maRegEx = new Regex("\bdvp.com\b", RegexOptions.IgnoreCase); 
  
	// Remplacement des occurrences de "dvp.com" par "Developpez.com" 
	monTexte = maRegEx.Replace(monTexte, "Developpez.com");

Mis à jour le 10 avril 2006 Ditch tomlev

Il faut pour cela utiliser les propriétés de l'encodage Unicode (qui est la représentation interne des chaines en .NET). En Unicode un caractère accentué est en fait composé de deux caractères : le caractère de base et l'accent. En normalisant la chaine de caractères, on peut séparer ces caractères de façon à pouvoir enlever l'accent :

Code c# : Sélectionner tout
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
using System.Globalization; 
  
class Program 
{ 
    static void Main(string[] args) 
    { 
        System.Console.Write("Entrez votre chaine de caractères : "); 
        string strResultat = RemoveDiacritics(System.Console.ReadLine()); 
        System.Console.WriteLine("Résultat : " + strResultat); 
  
        System.Console.Read(); 
    } 
  
    public static string RemoveDiacritics(string input) 
    { 
        string formD = input.Normalize(NormalizationForm.FormD); 
		StringBuilder sbNoDiacritics = new StringBuilder(); 
		foreach (char c in formD) 
		{ 
			if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark) 
				sbNoDiacritics.Append(c); 
		} 
        string noDiacritics = sbNoDiacritics.ToString().Normalize(NormalizationForm.FormC); 
        return noDiacritics; 
    } 
}

Mis à jour le 10 juin 2008 Jérôme Lambert tomlev

Il suffit de le préfixer par « 0x » pour indiquer au compilateur qu'il s'agit d'un nombre hexadécimal.

Code c# : Sélectionner tout
1
2
// maValeurHexa contient 64 
int maValeurHexa = 0x40;

Mis à jour le 2 janvier 2007 Jérôme Lambert tomlev

Il faut utiliser la version de Convert.ToString qui prend en second paramètre la base de destination :

Code c# : Sélectionner tout
1
2
3
4
5
6
7
8
int dec = 510; 
string bin = Convert.ToString(val, 2); 
string oct = Convert.ToString(val, 8); 
string hex = Convert.ToString(val, 16); 
Console.WriteLine("Décimal     : {0}", dec); 
Console.WriteLine("Binaire     : {0}", bin); 
Console.WriteLine("Octal       : {0}", oct); 
Console.WriteLine("Hexadécimal : {0}", hex);
Pour l'hexadécimal, il est également possible d'utiliser le spécificateur de format X, suivi d'un spécificateur de précision pour indiquer le nombre minimum de chiffres (le nombre sera préfixé par des 0 s'il n'est pas assez long) :

Code c# : Sélectionner tout
Console.WriteLine("Hexadécimal : {0:X4}", dec);

Mis à jour le 10 juin 2008 Merlin tomlev

Il est souvent nécessaire de générer des chaines de caractères avec des parties fixes et des parties variables. Pour y arriver, la méthode naïve est d'utiliser la concaténation :

Code c# : Sélectionner tout
1
2
3
4
Console.Write("Votre nom : "); 
string name = Console.ReadLine(); 
string message = "Bonjour " + name + "!"; 
Console.WriteLine(message);
Si cette approche est parfaitement fonctionnelle, et tout à fait adéquate dans les cas simples, elle peut rapidement rendre le code illisible et difficile à maintenir si la chaine contient beaucoup de parties variables... Exemple typique :

Code c# : Sélectionner tout
string sqlQuery = "INSERT INTO Contacts(Id, FirstName, LastName, City, Age) VALUES (" + id + ", '" + firstName + "', '" + lastName + "', '" + city + "', " + age + ")";
La méthode String.Format permet d'obtenir le même résultat avec un code beaucoup plus clair :

Code c# : Sélectionner tout
string sqlQuery = String.Format("INSERT INTO Contacts(Id, FirstName, LastName, City, Age) VALUES ({0}, '{1}', '{2}', '{3}', {4})", id, firstName, lastName, city, age);
Chaque emplacement de variable est matérialisé par un numéro entouré d'accolades. Les valeurs à insérer dans ces emplacements sont à la suite de la chaine de format, dans l'ordre correspondant à leur numéro (il est donc important de faire attention à l'ordre)

J'ai choisi cet exemple car il illustre une pratique très répandue. Cependant, sachez qu'il vaut mieux éviter de construire une requête SQL de cette manière (que ce soit par concaténation ou avec String.Format) ; il est recommandé d'utiliser des requêtes paramétrées, qui sont plus sûres (elles évitent le risque d'injection SQL) et permettent de faire abstraction des problèmes de format des données. Pour plus d'informations, consultez cet article.
La méthode String.Format a aussi un avantage non négligeable : elle permet de spécifier le format à utiliser pour chaque objet qui implémente l'interface IFormattable (ce qui est le cas notamment de tous les types numériques et des dates). Pour cela, il suffit de faire suivre le numéro de l'objet par un spécificateur de format :

Code c# : Sélectionner tout
1
2
3
double temperature = 28.5789147; 
string text = String.Format("Nous sommes le {0:D} et il est {0:t}. La température est de {1:N1}°", DateTime.Now, temperature); 
string hex = String.Format("La valeur hexadécimale de {0} est {0:X4}", 42);
Voici le sens des spécificateurs dans cet exemple :

  • "D" signifie « date au format long » (par exemple « mardi 6 juillet 2010 »)
  • "t" signifie « heure au format court » (« 20:35 »)
  • "N2" signifie « nombre avec 1 chiffre après la virgule » (« 28.6 »)
  • "X4" signifie « nombre hexadécimal avec au moins 4 chiffres » (« 002A »)

Tous ces formats sont prédéfinis, vous pouvez en trouver la liste sur MSDN (pour les dates, pour les nombres).

Notez dans l'exemple précédent que le même numéro a été utilisé deux fois dans la chaine de format. Si le même objet doit apparaitre plusieurs fois dans la chaine, il est donc inutile de le passer plusieurs fois en paramètre : il suffit d'utiliser le même numéro.
En plus des formats prédéfinis, il est possible d'utiliser des formats personnalisés :

Code c# : Sélectionner tout
string text = String.Format("Nous sommes aujourd'hui {0:dddd d MMMM yyyy}", DateTime.Now);
"ddd" représente le jour de la semaine en abbrégé ("mar."), "d" le numéro du jour dans le mois ("6"), "MMMM" le nom du mois en toutes lettres ("juillet"), et "yyyy" l'année sur 4 chiffres ("2010"). Les formats personnalisés sont documentés sur MSDN (pour les dates, pour les nombres).

Dernière remarque importante : tous les formats de date et de nombre tiennent compte de la culture (langue) courante. Ainsi, selon la langue actuelle de l'application, une même date pourra être formatée en « mardi 6 juillet 2010 » ou en « Tuesday, 06 July 2010 ». De la même façon, les nombres ne sont pas représentés de la même façon dans toutes les langues : le séparateur décimal peut être un point ou une virgule, les séparateurs de milliers peuvent être une virgule ou un espace (ou rien du tout)… String.Format prend automatiquement en compte tous ces paramètres. Pensez-y lorsque vous développez une application multilingue .

Mis à jour le 5 juillet 2010 tomlev

Il est parfois nécessaire d'encoder des données binaires sous forme de texte, par exemple pour les enregistrer dans un fichier XML. A cet effet, on utilise le plus souvent le format base64, qui est plus compact que l'hexadécimal. La méthode Convert.ToBase64String permet de convertir un tableau d'octets en base 64 :

Code c# : Sélectionner tout
1
2
3
byte[] binaryData = new byte[] { 4, 8, 15, 16, 23, 42 }; 
string base64Data = Convert.ToBase64String(binaryData); 
Console.WriteLine(base64Data); // Écrit "BAgPEBcq"

Mis à jour le 11 août 2010 tomlev

En utilisant un bloc itérateur :

Code c# : Sélectionner tout
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
 // interface publique (contrôle immédiat des arguments) 
public IEnumerable<string> SplitEvery (string str, int chunkSize) 
{ 
    if (str == null) 
        throw new ArgumentNullException ("str"); 
    if (chunkSize <= 0) 
        throw new ArgumentOutOfRangeException ("chunkSize"); 
  
     // appel au bloc itérateur 
     return SplitEveryIterator (str, chunkSize); 
} 
  
// bloc itérateur privé (permet l'évaluation tardive) 
private IEnumerable<string> SplitEveryIterator (string str, int chunkSize) 
{ 
    if (str.Length <= chunkSize) 
        // si le texte est plus court que la taille demandée ; le renvoyer directement 
        yield return str; 
    else 
    { 
        var chunkCount = str.Length / chunkSize; // nombre de morceaux 
        var remainingSize = str.Length % chunkSize; // taille du morceau final 
  
        for (var offset = 0; offset < chunkCount; ++offset) 
            yield return str.Substring (offset * chunkSize, chunkSize); 
  
        // renvoyer le morceau final s'il existe 
        if (remainingSize != 0) 
            yield return str.Substring (chunkCount * chunkSize, remainingSize); 
    } 
} 
  
// exemple d'utilisation 
foreach (var str in SplitEvery ("hello", 2)) 
    Console.WriteLine (str); 
  
//affichera : 
  
// he 
// ll 
// o

Mis à jour le 24 mai 2015 Sehnsucht

Proposer une nouvelle réponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2017 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

 
Responsable bénévole de la rubrique Microsoft DotNET : Hinault Romaric -