【问题标题】:Can maximum number of characters be defined in C# format strings like in C printf?可以像在 C printf 中那样在 C# 格式字符串中定义最大字符数吗?
【发布时间】:2010-11-05 11:18:58
【问题描述】:

没有找到如何做到这一点。我发现的或多或少是这样的(http://blog.stevex.net/string-formatting-in-csharp/):

除了对齐之外,字符串中实际上没有任何格式。对齐适用于在 String.Format 调用中打印的任何参数。 样本生成

String.Format(“->{1,10}<-”, “Hello”);  // gives "->     Hello<-" (left padded to 10)
String.Format(“->{1,-10}<-”, “Hello”); // gives "->Hello     <-" (right padded to 10)

【问题讨论】:

  • 您到底想达到什么目的?您可以发布您希望看到的示例吗?
  • 我正在尝试将 C 格式字符串转换为 C# 格式字符串。在 C 中你可以指定 %-4.4s 和类似的。
  • 为什么投反对票?这是一个基本问题!
  • 更重要的是,如果不存在 C# 格式字符串设计的缺陷。
  • 我不会称之为缺陷。更多的是您正在寻找的特定功能不可用。 String.Format 还支持 C 格式字符串中不存在的几个功能。这是否意味着 C 的格式字符串必然有缺陷?

标签: c# string string-formatting


【解决方案1】:

您想要的不是 C# 字符串格式“本机”支持的,因为字符串对象的 String.ToString 方法只返回字符串本身。

当你打电话时

string.Format("{0:xxx}",someobject);

如果某个对象实现了 IFormattable 接口,则调用重载 ToString(string format,IFormatProvider formatProvider) 方法,并将“xxx”作为 format 参数。

所以,这顶多不是 .NET 字符串格式设计的缺陷,而只是字符串类中缺少功能。

如果你真的需要这个,你可以使用任何建议的解决方法,或者创建你自己的实现 IFormattable 接口的类。

【讨论】:

  • 谢谢!你绝对是对的。它是缺少某些东西的字符串类。但是您是否使用 xxx 作为某种格式的示例,或者它真的意味着什么(例如 3 个字符)?
  • @matti,没有 xxx 只是一个例子。实际上,它的含义是由 IFormattable 接口的实现决定的。无论如何(作为一个 c++ 爱好者),c++ 中的字符串格式与 c# 中的字符串格式相比 sucks,谈论缺少这个特定功能这一事实的缺陷对我来说似乎很奇怪;)跨度>
【解决方案2】:

这不是关于如何使用 string.format 的答案,而是另一种使用扩展方法缩短字符串的方法。这种方式使您可以直接将最大长度添加到字符串,即使没有 string.format。

public static class ExtensionMethods
{
    /// <summary>
    ///  Shortens string to Max length
    /// </summary>
    /// <param name="input">String to shortent</param>
    /// <returns>shortened string</returns>
    public static string MaxLength(this string input, int length)
    {
        if (input == null) return null;
        return input.Substring(0, Math.Min(length, input.Length));
    }
}

示例用法:

string Test = "1234567890";
string.Format("Shortened String = {0}", Test.MaxLength(5));
string.Format("Shortened String = {0}", Test.MaxLength(50));

Output: 
Shortened String = 12345
Shortened String = 1234567890

【讨论】:

    【解决方案3】:

    我编写了一个自定义格式化程序,它实现了用于设置最大宽度的“L”格式说明符。当我们需要控制格式化输出的大小时,这很有用,例如当目标是数据库列或 Dynamics CRM 字段时。

    public class StringFormatEx : IFormatProvider, ICustomFormatter
    {
        /// <summary>
        /// ICustomFormatter member
        /// </summary>
        public string Format(string format, object argument, IFormatProvider formatProvider)
        {
            #region func-y town
            Func<string, object, string> handleOtherFormats = (f, a) => 
            {
                var result = String.Empty;
                if (a is IFormattable) { result = ((IFormattable)a).ToString(f, CultureInfo.CurrentCulture); }
                else if (a != null) { result = a.ToString(); }
                return result;
            };
            #endregion
    
            //reality check.
            if (format == null || argument == null) { return argument as string; }
    
            //perform default formatting if arg is not a string.
            if (argument.GetType() != typeof(string)) { return handleOtherFormats(format, argument); }
    
            //get the format specifier.
            var specifier = format.Substring(0, 1).ToUpper(CultureInfo.InvariantCulture);
    
            //perform extended formatting based on format specifier.
            switch(specifier)
            {
                case "L": 
                    return LengthFormatter(format, argument);
                default:
                    return handleOtherFormats(format, argument);
            }
        }
    
        /// <summary>
        /// IFormatProvider member
        /// </summary>
        public object GetFormat(Type formatType)
        {
            if (formatType == typeof(ICustomFormatter))
                return this;
            else
                return null;
        }
    
        /// <summary>
        /// Custom length formatter.
        /// </summary>
        private string LengthFormatter(string format, object argument)
        {
            //specifier requires length number.
            if (format.Length == 1)
            {
                throw new FormatException(String.Format("The format of '{0}' is invalid; length is in the form of Ln where n is the maximum length of the resultant string.", format));
            }
    
            //get the length from the format string.
            int length = int.MaxValue;
            int.TryParse(format.Substring(1, format.Length - 1), out length);
    
            //returned the argument with length applied.
            return argument.ToString().Substring(0, length);
        }
    }
    

    用法是

    var result = String.Format(
        new StringFormatEx(),
        "{0:L4} {1:L7}",
        "Stack",
        "Overflow");
    
    Assert.AreEqual("Stac Overflo", result);
    

    【讨论】:

    • 希望这样的东西默认包含在 c# 中,或者至少作为一个金块
    【解决方案4】:

    你不能只使用参数而不是格式来应用长度参数吗?

    String.Format("->{0}你好

    或者编写你自己的格式化程序来允许你这样做?

    【讨论】:

      【解决方案5】:

      为什么不直接使用 Substr 来限制字符串的长度?

      String s = "abcdefghijklmnopqrstuvwxyz";
      String.Format("Character limited: {0}", s.Substr(0, 10));
      

      【讨论】:

      • 我错过了一个事实,即使 Substr 也有一些与其他语言不同的尴尬实现。我按原样使用了这种解决方法,但当字符串短于 10 个字符时,它会失败......
      【解决方案6】:

      您可能希望在将来的应用程序中使用此帮助程序,它将字符串限制在给定的最大长度,如果它比给定的限制短,也会填充。

      public static class StringHelper
      {
      
          public static string ToString(this string input , int maxLength , char paddingChar = ' ', bool isPaddingLeft = true)
          {
              if (string.IsNullOrEmpty(input))
                  return new string('-', maxLength);
              else if (input.Length > maxLength)
                  return input.Substring(0, maxLength);
              else
              {
                  int padAmount = maxLength - input.Length;
                  if (isPaddingLeft)
                      return input + new string(paddingChar, padAmount);
                  else
                      return new string(paddingChar, padAmount) + input;
              }
          }
      }
      

      您可以将其用作:

       string inputStrShort = "testString";
       string inputStrLong = "mylongteststringexample";
       Console.WriteLine(inputStrShort.ToString(20, '*', true)); // Output : testString**********
       Console.WriteLine(inputStrLong.ToString(20, '*', true));  // Output : mylongteststringexam
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-19
        • 2011-04-23
        • 1970-01-01
        相关资源
        最近更新 更多