【问题标题】:Splitting string into an array on 16th char [duplicate]在第 16 个字符上将字符串拆分为数组 [重复]
【发布时间】:2014-04-21 09:21:08
【问题描述】:

我有一个文本文件,其中包含不同的 16 个字符字符串,它们彼此附加并位于不同的行上。我已经这样做了

FileInfo f = new FileInfo("d:\\test.txt");
string FilePath = ("d:\\test.txt");
string FileText = new System.IO.StreamReader(FilePath).ReadToEnd().Replace("\r\n", "");
CharCount = FileText.Length;

删除所有新行并创建一个大量附加的字符串。我现在需要将这个庞大的字符串拆分成一个数组。我需要在连续的第 16 个字符上拆分它,直到最后。谁能指导我正确的方向?我已经查看了 String 中的各种方法,例如 SplitStreamReader,但我不知道最好的方法是什么。我敢肯定这很简单,但我想不通。

谢谢。

【问题讨论】:

  • 所以您只是想删除换行符?
  • @Herblore 所以文件中的每一行都有 16 个字符?

标签: c# arrays string split


【解决方案1】:

改编自here的答案:

你可以试试这样的:

        string longstr = "thisisaverylongstringveryveryveryveryverythisisaverylongstringveryveryveryveryvery";
        IEnumerable<string> splitString = Regex.Split(longstr, "(.{16})").Where(s => s != String.Empty);
        foreach (string str in splitString)
        {
            System.Console.WriteLine(str);
        }

产量:

thisisaverylongs    
tringveryveryver    
yveryverythisisa    
verylongstringve    
ryveryveryveryve
ry

【讨论】:

    【解决方案2】:

    一种可能的解决方案可能如下所示(提取为扩展方法并动态化,以防需要不同的令牌大小并且没有硬编码的依赖项):

    public static class ProjectExtensions
    {
        public static String[] Chunkify(this String input, int chunkSize = 16)
        {
            // result
            var output = new List<String>();
            // temp helper
            var chunk = String.Empty;
            long counter = 0;
            // tokenize to 16 chars
            input.ToCharArray().ToList().ForEach(ch => 
            {
                counter++;
                chunk += ch;
                if ((counter % chunkSize) == 0)
                {
                    output.Add(chunk);
                    chunk = String.Empty;
                }
            });
            // add the rest
            output.Add(chunk);
    
            return output.ToArray();
        }
    }
    

    标准用法(16 个字符)如下所示:

    // 3 inputs x 16 characters and 1 x 10 characters
    var input = @"1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890";
    foreach (var chunk in input.Chunkify())
    {
        Console.WriteLine(chunk);
    }
    

    输出是:

    1234567890ABCDEF
    1234567890ABCDEF
    1234567890ABCDEF
    1234567890
    

    使用不同的令牌大小

    foreach (var chunk in input.Chunkify(13))
    {
        Console.WriteLine(chunk);
    }
    

    以及相应的输出:

    1234567890ABC
    DEF1234567890
    ABCDEF1234567
    890ABCDEF1234
    567890
    

    这不是一个花哨的解决方案(并且可能会针对速度进行优化),但它确实有效并且易于理解和实施。

    【讨论】:

      【解决方案3】:

      创建一个列表来保存您的代币。然后获取后续长度为 16 的子串,并将它们添加到列表中。

      List<string> tokens = new List<string>();
      for(int i=0; i+16<=FileText.Length; i+=16) {
          tokens.Add(FileText.Substring(i,16));
      }
      

      如 cmets 中所述,如果最后一个标记少于 16 个字符,则它会忽略它。如果你想要它,你可以写:

      List<string> tokens = new List<string>();
      for(int i=0; i<FileText.Length; i+=16) {
          int len = Math.Min(16, FileText.Length-i));
          tokens.Add(FileText.Substring(i,len);
      }
      

      【讨论】:

      • 如果字符串长度不是 16 的倍数会失败。
      • @UlugbekUmirov:感谢您的发现。它现在应该可以工作了。
      • 我认为如果最后一部分的长度小于 16,我们不应该忽略它。您可以使用 Math.Min(16, FileText.Length - i) 作为长度参数。
      • @UlugbekUmirov 是的,看我的回答
      【解决方案4】:

      请试试这个方法。没试过,用过一次。

          int CharCount = FileText.Length;
          int arrayhold = (CharCount/16)+2;
          int count=0;
          string[] array = new string[arrayhold];
          for(int i=0; i<FileText.Length; i+=16)
             {
                int currentleft = FileText.Length-(16*count);
                if(currentleft>16)
                  {
                        array[count]=FileText.Substring(i,16);
                  }
                if(currentleft<16)
                  {
                        array[count]=FileText.Substring(i,currentleft);
                  }
      
                    count++;
              }
      

      这是新代码并提供 TRUE 剩菜处理。在ideone中测试

      希望有效果

      【讨论】:

      • -1 原因是here 剩下的字符呢?
      • @SriramSakthivel 现在它可以工作了,this 添加了处理剩菜的正确方法证明了这一点。并感谢 ideone。
      • @All downvoters ,请查看此内容并修复 downvotes ,现在它可以工作了! :( 最好,赞成 Xb
      【解决方案5】:

      试试这个:

      var testArray = "sdfsdfjshdfalkjsdfhalsdkfjhalsdkfjhasldkjfhasldkfjhasdflkjhasdlfkjhasdlfkjhasdlfkjhasldfkjhalsjfdkhklahjsf";
      var i = 0;
      var query = from s in testArray
                  let num = i++
                  group s by num / 16 into g
                  select new {Value = new string(g.ToArray())};
      
      var result = query.Select(x => x.Value).ToList();
      

      结果是包含所有 16 个字符字符串的列表。

      【讨论】:

      • 为什么是-1?答案有什么问题?
      猜你喜欢
      • 1970-01-01
      • 2013-08-19
      • 1970-01-01
      • 2017-01-31
      • 2016-07-23
      • 1970-01-01
      • 2011-12-20
      • 2011-08-28
      • 1970-01-01
      相关资源
      最近更新 更多