.NET Sformatuj ciąg ze stałymi spacjami


199

Czy metoda .NET String.Format umożliwia umieszczenie ciągu znaków w ustalonej pozycji w ciągu ciągu znaków o stałej długości.

„String Goes Here”
„String Goes Here”
„String Goes Here”

Jak to się robi przy użyciu .NET?

Edycja - Próbowałem Format / PadLeft / PadRight na śmierć. Oni nie pracują. Nie wiem dlaczego. Skończyłem pisać własną funkcję, aby to zrobić.

Edycja - popełniłem błąd i użyłem dwukropka zamiast przecinka w specyfikatorze formatu. Powinien wynosić „{0,20}”.

Dzięki za wszystkie doskonałe i poprawne odpowiedzi.


48
Nigdy nie miałem pytania dotyczącego formatowania łańcucha, na które nie mogłem odpowiedzieć, wchodząc na tę stronę: blog.stevex.net/index.php/string-formatting-in-csharp
jcollum

@jcollum: Chciałbym głosować za twoją odpowiedzią, ale nie mogę nic zrobić w przypadku komentarzy
Dinah

PadLeft działa dla mnie, sprawdź, czy opuszczasz miejsce w PadLeft (20, „TUTAJ PRZESTRZEŃ”)
Mistrz Jedi Spooky

Co oznacza „pozostawienie przestrzeni w”. Jeśli masz na myśli - czy „przycinam” ciąg, to nie. To wciąż nie działa.
user72491,

Odpowiedzi:


473

To da ci dokładnie te ciągi, o które prosiłeś:

string s = "String goes here";
string lineAlignedRight  = String.Format("{0,27}", s);
string lineAlignedCenter = String.Format("{0,-27}",
    String.Format("{0," + ((27 + s.Length) / 2).ToString() +  "}", s));
string lineAlignedLeft   = String.Format("{0,-27}", s);

64
Powinno to zostać oznaczone jako poprawna odpowiedź na pytanie, ale wygląda na to, że OP opuściło przepływ stosu.
Oliver

9
Jeśli szukasz zielonego czeku w porównaniu do najwyższych głosów, nie wiesz, jak to zrobić;)
Dave Jellison

2
@DaveJellison Wydaje się, że ktoś musi napisać wtyczkę, aby to naprawić, lub SO powinno po prostu ustawić konfigurowalne preferencje użytkownika.
Walter Stabosz

1
@WalterStabosz nie mógł zgodzić się więcej.
Dave Jellison

2
dlaczego robi się to z ,zamiast :jak we wszystkich innych przypadkach formatowania?
LuckyLikey

65

Pierwszy i ostatni przynajmniej są możliwe przy użyciu następującej składni:

String.Format("{0,20}", "String goes here");
String.Format("{0,-20}", "String goes here");

49

Począwszy od programu Visual Studio 2015 można to również zrobić za pomocą interpolowanych ciągów znaków (jest to sztuczka kompilatora, więc nie ma znaczenia, którą wersję frameworku .net jest docelowa).

string value = "String goes here";
string txt1 = $"{value,20}";
string txt2 = $"{value,-20}";

9
jego funkcja ac # 6.
LuckyLikey

Używam C # 6 od lat i nie znałem tego! Upvoted :)
Avrohom Yisroel

17

Pokazano ci PadLefti PadRight. To uzupełni brakujące dane PadCenter.

public static class StringUtils
{
    public static string PadCenter(this string s, int width, char c)
    {
        if (s == null || width <= s.Length) return s;

        int padding = width - s.Length;
        return s.PadLeft(s.Length + padding / 2, c).PadRight(width, c);
    }
}

Uwaga do siebie: nie zapomnij zaktualizować własnego CV: „Pewnego dnia naprawiłem nawet kod Joela Coehoorna!” ;-D -Serge


Joel, dobry urywek - próbuję go użyć i nie do końca tak to wyśrodkowuje. Wygląda na to, że linia zwrotna powinna być podobna (nie mam wystarczającej liczby powtórzeń do edycji ...): return s.PadLeft ((padding / 2) + s.Length, c) .PadRight (width, c);
shaunmartin

11

Spróbuj tego:

"String goes here".PadLeft(20,' ');
"String goes here".PadRight(20,' ');

dla środka uzyskaj długość sznurka i wykonaj padleft i padright z niezbędnymi znakami

int len = "String goes here".Length;
int whites = len /2;
"String goes here".PadRight(len + whites,' ').PadLeft(len + whites,' ');

Wygląda na to, że wywołania String.Format () są zbędne.
Joel Coehoorn

Metody kłódek są dobre, ponieważ opcje formatu wymaga trudu, aby być stałe (czyli String.Format("{0,-length}", something)nie będzie skompilować.
Roberto

6

Dzięki za dyskusję, ta metoda również działa (VB):

Public Function StringCentering(ByVal s As String, ByVal desiredLength As Integer) As String
    If s.Length >= desiredLength Then Return s
    Dim firstpad As Integer = (s.Length + desiredLength) / 2
    Return s.PadLeft(firstpad).PadRight(desiredLength)
End Function
  1. StringCentering () przyjmuje dwie wartości wejściowe i zwraca sformatowany ciąg.
  2. Gdy długość s jest większa lub równa deisredLength , funkcja zwraca oryginalny ciąg.
  3. Gdy długość s jest mniejsza niż pożądana długość , zostanie wypełniona na obu końcach.
  4. Ponieważ odstępy między znakami są liczbami całkowitymi i nie ma półprzestrzeni, możemy mieć nierównomierny podział przestrzeni. W tej implementacji większy podział prowadzi do wiodącego celu.
  5. Ta funkcja wymaga .NET Framework ze względu na PadLeft () i PadRight () .
  6. W ostatnim wierszu funkcji wiązanie przebiega od lewej do prawej, więc pierwszy pad jest nakładany, a następnie pad pożądanej długości .

Oto wersja C #:

public string StringCentering(string s, int desiredLength)
{
    if (s.Length >= desiredLength) return s;
    int firstpad = (s.Length + desiredLength) / 2;
    return s.PadLeft(firstpad).PadRight(desiredLength);
}

Aby ułatwić zrozumienie, zastosowano pierwszy pad zmiennej całkowitej . s.PadLeft (pierwszy pad) stosuje (prawidłową liczbę) wiodących białych spacji. Najbardziej prawy PadRight (pożądana długość) ma niższe wiązanie wykończone przez zastosowanie końcowych białych spacji.


1
Witamy w SO, chi. To kolejny przykład WIELKIEGO pierwszego postu i odpowiedzi. +1
Brian,

Dzięki Brian, oryginalne pytanie na początku tego postu jest doskonałym punktem wyjścia. Inspirują mnie wszystkie posty i odpowiedzi poprzedzające moje.
chi

1

Oto stworzona przeze mnie wersja VB.NET, zainspirowana odpowiedzią Joela Coehoorna, edycją Olivera i komentarzem shaunmartina:

    <Extension()>
Public Function PadCenter(ByVal [string] As String, ByVal width As Integer, ByVal c As Char) As String

    If [string] Is Nothing Then [string] = String.Empty
    If (width <= [string].Length) Then Return [string]

    Dim padding = width - [string].Length
    Return [string].PadLeft([string].Length + (padding \ 2), c).PadRight(width, c)

End Function

<Extension()>
Public Function PadCenter(ByVal [string] As String, ByVal width As Integer) As String

    If [string] Is Nothing Then [string] = String.Empty
    If (width <= [string].Length) Then Return [string]

    Dim padding = width - [string].Length
    Return [string].PadLeft([string].Length + (padding \ 2)).PadRight(width)

End Function

Jest to skonfigurowane jako rozszerzenie łańcucha w module publicznym (sposób, w jaki robisz rozszerzenia w VB.NET, nieco inny niż C #). Moją niewielką zmianą jest to, że traktuje łańcuch zerowy jako pusty łańcuch i wypełnia pusty łańcuch wartością szerokości (spełnia moje szczególne potrzeby). Mam nadzieję, że łatwo przekonwertuje to do C # dla każdego, kto tego potrzebuje. Jeśli istnieje lepszy sposób na odniesienie się do odpowiedzi, zmian i komentarzy, o których wspomniałem powyżej, które zainspirowały mojego postu, daj mi znać, a ja to zrobię - jestem stosunkowo nowy w publikowaniu i nie mogłem wymyślić zostaw komentarz (może nie mieć jeszcze wystarczającej liczby powtórzeń).


0

Opublikowałem artykuł CodeProject, który może być tym, czego chcesz.

Zobacz: AC # sposób pośredniego formatowania szerokości i stylu.

Zasadniczo jest to metoda FormatEx, która działa jak String.Format, z wyjątkiem tego, że pozwala na wyśrodkowany modyfikator wyrównania.

FormatEx("{0,c10}", value);

Oznacza wyśrodkowanie wartości varArgs [0] w polu o szerokości 10 znaków, pochyl się w prawo, jeśli wymagane jest dodatkowe miejsce do wypełnienia.

FormatEx("{0,c-10}", value);

Oznacza wyśrodkowanie wartości varArgs [0] w polu o szerokości 10 znaków, pochyl się w lewo, jeśli wymagane jest dodatkowe miejsce do wypełnienia.

Edycja: Wewnętrznie jest to kombinacja PadCenter Joela z niektórymi analizami w celu restrukturyzacji formatu i varArgs dla wywołania String.Format, który robi to, co chcesz.

-Jesse


-1

wygląda na to, że chcesz czegoś takiego, co umieści cię w stałym punkcie w ciągu o stałej długości:

Dim totallength As Integer = 100
Dim leftbuffer as Integer = 5
Dim mystring As String = "string goes here"
Dim Formatted_String as String = mystring.PadLeft(leftbuffer + mystring.Length, "-") + String.Empty.PadRight(totallength - (mystring.Length + leftbuffer), "-")

zwróć uwagę, że będzie to miało problemy, jeśli mystring.length + lewy bufor przekroczy całkowitą długość


-7
/// <summary>
/// Returns a string With count chars Left or Right value
/// </summary>
/// <param name="val"></param>
/// <param name="count"></param>
/// <param name="space"></param>
/// <param name="right"></param>
/// <returns></returns>
 public static string Formating(object val, int count, char space = ' ', bool right = false)
{
    var value = val.ToString();
    for (int i = 0; i < count - value.Length; i++) value = right ? value + space : space + value;
    return value;
}

3
Nie używaj tego kodu - generuje on wiele niepotrzebnych przydziałów ciągów. Zamiast tego użyj wbudowanych specyfikatorów formatu i metod wypełniania.
Oskar Berggren

1
święty .. wyobraź sobie, że używasz tego w pętli :)
LuckyLikey
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.