2016-04-02 2 views
1

私はC#とオブジェクトプログラミングの初心者です。文字を読み込んで単語にし、行に書かれた単語からなる出力を生成するプログラムを作成しようとしていますが、行ごとに30文字しかないかもしれません。単語が30文字より長い場合は、行の最大許容長より長くなることがあります。C#で文字列を読み取り、それを境界線の線に分ける

これまで私がこれまで持っていたことは次のとおりです。それは動作しているようですが、私は最後に2つの余分な空白を作るのが好きではありません。また、このプログラムを行うためのより効果的な方法がありますか、おそらくもっと短くて、「ちょっと」ですか?ありがとうございました。

class Program 
{ 
    public static readonly int MAX_LENGTH = 30;   // max number of characters in one line 
    public static int counter = 0;   // counts characters in line 

    public static bool OverMaxLength(string word)   // chcecks, whether the words is bigger than MAX_LENGTH 
    { 
     return (word.Length >= MAX_LENGTH); 
    } 

    public static void AddToCounter(string word, ref int counter)   // adds the length of word into the counter 
    { 

      counter += word.Length; 

    } 

    public static void CheckIfOverflow(string word, ref int counter)    
    { 
     if (counter > MAX_LENGTH)   // if counter counts more than is allowed 
     { 
      Console.WriteLine(); 
      Console.Write(word + " "); 
      counter = word.Length + 1; 

     } 
     else 
     { 
      Console.Write(word + " "); 
      counter += 1; 
     } 
    } 

    public static string ReadWord() 
    { 
     string word = ""; 
     char c; 

     // reads one character 

     c = Convert.ToChar(Console.Read()); 
     do 
     { 
      word += c; 
      c = Convert.ToChar(Console.Read()); 

     } while (c != ' ');       

     return word; 
    } 
    static void Main(string[] args) 
    { 

     string word = ""; 

     word = ReadWord(); 
     while (word != "konec") 
     { 
      if ((OverMaxLength(word)) & (counter > 0)) 
      { 
       Console.WriteLine(); 
       Console.WriteLine(word); 
       counter = 0; 
      } 
      else if ((OverMaxLength(word)) & (counter == 0)) 
      { 
       Console.Write(word); 
       counter = word.Length; 
      } 
      else 
      { 
       AddToCounter(word, ref counter); 
       CheckIfOverflow(word, ref counter); 
      } 


      word = ReadWord(); 


     } 
     Console.Read(); 

    } 
} 
+0

。私はあなたの質問に入れて努力を感謝します。 –

答えて

1

ロジックを多少分割する方がよい場合があります。

最初に、単語のIEnumerable<string>のシーケンスを返すメソッドがあります。

次に、IEnumerable<string>という一連の行を、指定に従って連結した単語で返します。

後者はそうのように、より簡潔に書くことができます。そのための

public static IEnumerable<string> ConcatWithLimit(IEnumerable<string> words, int maxLineLength) 
{ 
    var sb = new StringBuilder(); 

    foreach (string word in words) 
    { 
     if (sb.Length + word.Length > maxLineLength) 
     { 
      yield return sb.ToString().TrimEnd(); 
      sb.Clear(); 
     } 

     sb.Append(word).Append(" "); 
    } 

    if (sb.Length > 0) 
     yield return sb.ToString().TrimEnd(); 
} 

いくつかのテストコード:

string[] words = 
{ 
    "1", "22", "333", "4444", "55555", "666666", "7777777", 
    "1", "22", "333", "4444", "55555", "666666", "7777777", 
    "1", "22", "333", "4444", "55555", "666666", "7777777", 
    "1", "22", "333", "4444", "55555", "666666", "7777777", 
    "123456789", "55555", "666666", 
    "1", "22", "333", "4444", "55555", "666666", "7777777", 
    "1", "22", "333", "4444", "55555", "666666", "7777777", 
}; 

Console.WriteLine("   1   2   3"); 
Console.WriteLine("123456789"); 
Console.WriteLine(string.Join("\n", ConcatWithLimit(words, 30))); 
1

あなたがそう一覧表示しようとしてイムに向上させることができ、物事の非常にたくさんありますいくつか。
まず、この単語リーダーの実装を別のファイル/クラスに入れ、静的な乱用を取り除くことに注目してください。静的にすることはできません。クラスをインスタンス化するProgram p = new Program(); p.ReadWord();
スペースで区切られた単語を読みたい場合は、代わりに文字列全体を一度に読み取って分割する必要があります。 string[] words = Console.ReadLine().Split(' '); ブール演算を使用する場合は&&を使用してください。&はビット演算子です。

1行に30文字を出力する場合、string combinedWords = string.join(words, ' ');を入力してstring.Substringなどを使用します。 Console.WriteLine(combinedWords.Substring(0, 30));

私はあなたがdownvotedてしまった理由を推測することができますが、StackOverflowのは[CodeReview.SE]は(http://codereview.stackexchange.com)すでに書かれたコードを批判ため、よりいる間に何かをする方法を考え出すためのより多くのです
関連する問題