2010-04-16 64 views
1
while (true) 
{ 
    //read in the file 
    StreamReader convert = new StreamReader("../../convert.txt"); 

    //define variables 
    string line = convert.ReadLine(); 
    double conversion; 
    int numberIn; 
    double conversionFactor; 

    //ask for the conversion information 
    Console.WriteLine("Enter the conversion in the form (Amount, Convert from, Convert to)"); 
    String inputMeasurement = Console.ReadLine(); 
    string[] inputMeasurementArray = inputMeasurement.Split(','); 


    //loop through the lines looking for a match 
    while (line != null) 
    { 
     string[] fileMeasurementArray = line.Split(','); 
     if (fileMeasurementArray[0] == inputMeasurementArray[1]) 
     { 
      if (fileMeasurementArray[1] == inputMeasurementArray[2]) 
      { 
       Console.WriteLine("The conversion factor for {0} to {1} is {2}", inputMeasurementArray[1], inputMeasurementArray[2], fileMeasurementArray[2]); 

       //convert to int 
       numberIn = Convert.ToInt32(inputMeasurementArray[0]); 
       conversionFactor = Convert.ToDouble(fileMeasurementArray[2]); 

       conversion = (numberIn * conversionFactor); 
       Console.WriteLine("{0} {1} is {2} {3} \n", inputMeasurementArray[0], inputMeasurementArray[1], conversion, inputMeasurementArray[2]); 
       break; 
      } 
     } 
     else 
     { 
      Console.WriteLine("Please enter two valid conversion types \n"); 
      break; 
     } 
     line = convert.ReadLine(); 
    } 
} 

该文件包含以下内容:在一个循环滞留

ounce,gram,28.0 
pound,ounce,16.0 
pound,kilogram,0.454 
pint,litre,0.568 
inch,centimetre,2.5 
mile,inch,63360.0 

用户将输入类似6盎司,革兰氏

的想法是,它通过检查找到正确的线如果文件中的第一个和第二个单词与用户输入的第二个和第三个单词相同。

问题是,如果它检查第一行,并且if语句失败,如果通过else语句并停止。我试图找到一种方式,在它找到正确的行后停止,但直到它停止。如果某人键入的值不在文件中,则应该显示错误。

回答

5

删除else子句中的break语句。这导致它退出循环。

通过将转换因子读入内部数据结构,可能是由“from”转换单元键入的字典,该值为可能的输出单位字典及其转换因子 - 或者a自定义键/值对,如果您只有一个可能的输出单位。这会将你的内部循环变成两阶段查找(快得多),并节省你每次都必须重新读取转换文件的麻烦。正如@Ben指出的那样,错误信息也在错误的地方。它需要在循环/查找之外,并且只有在没有找到匹配的情况下才会执行。

示例代码 - 注意,在此代码中没有输入验证:

var conversions = new Dictionary<string,Dictionary<string,double>>(); 
var convert = new StreamReader("../../convert.txt"); 
while ((var line = convert.ReadLine()) != null) 
{ 
    string components = line.Split(','); 
    Dictionary<string,double> unitConversions; 
    if (conversions.ContainsKey(components[0])) 
    { 
     unitConversions = conversions[components[0]]; 
    } 
    else 
    { 
     unitConversions = new Dictionary<string,double>(); 
     conversions.Add(components[0], unitConversions); 
    } 
    unitConversions.Add(components[1], Convert.ToDouble(components[2])); 
} 

while (true) 
{ 
    //ask for the conversion information  
    Console.WriteLine("Enter the conversion in the form (Amount, Convert from, Convert to)");  
    var inputMeasurement = Console.ReadLine();  
    var inputMeasurementArray = inputMeasurement.Split(','); 

    bool converted = false; 
    Dictionary<string,double> unitConversion; 
    if (conversions.TryGetValue( inputMeasurementArray[1], out unitConversion)) 
    { 
     double conversionFactor; 
     if (unitConversion.TryGetValue(inputMeasurementArray[2], out conversionFactor)) 
     { 
      converted = true; 
      conversion = Convert.ToDouble(inputMeasurementArray[0]) * conversionFactor; 
      Console.WriteLine("{0} {1} is {2} {3} \n", inputMeasurementArray[0], inputMeasurementArray[1], conversion, inputMeasurementArray[2]);    
     } 
    } 

    if (!converted) 
    { 
     Console.WriteLine("Please enter two valid conversion types\n"); 
    } 
} 
+0

你比我更好的轨道,但其他人仍然会在错误的水平(即在转换定义文件中每行一个错误,而不是错误的输入每个错误) – 2010-04-16 13:45:04

+0

@Ben - 我没有打扰检查接口是正确的。显然,错误信息应该在内部循环之外,在这种情况下,else子句甚至不是必需的。另外,我会考虑只获取一次转换数据并将其存储在内部,因此无需每次重新读取转换数据。如果你这样做,那么内部循环变成一个简单的查找字典。 – tvanfosson 2010-04-16 13:51:08

+0

-1,因为它仍然将每行不匹配为一个错误。它不能解决如何在失败之前检查整个文件的问题。 – Tesserex 2010-04-16 13:53:22

0

如果tvanfosson答案不工作。你可以通过继续来替换他提到的突破。这将使执行进入下一个循环

+0

这将是不好的 - 你会跳过'ReadLine()',并创建了一个无限循环.. – 2010-04-16 13:49:54

2

我猜你明白你的代码在做什么,所以我不必指出break正在导致它停止。你只需要做什么来完成你想要的。 if区块内的break是正确的,并且会在找到匹配项时停止。

继续也不起作用,它现在说,如果第一行不匹配,这是错误的。

为什么你有外环while循环?特别是,你为什么在里面读取文件?阅读一次,然后循环。

我想你想要的是在你的线条阅读循环之上设置一些像bool found = false;这样的东西。然后在成功的if块内,设置found = true;之前的break。完全摆脱else区块,因为这不是一个错误。这意味着你还没有找到它。然后,外循环,把

if (!found) Console.WriteLine("Please enter two valid conversion types \n"); 

使用found以确定是否在整个文件中循环后继续或取消,

+0

Thankyou非常这工作,我知道我不得不采取它以外的循环不知何故,但我是新来的C#和couldn没有想到做到这一点的最佳方式! – sark9012 2010-04-16 14:02:22

1

其他应完全删除。

引入布尔“成功”标志,初始化为false,并在找到值时将其设置为true

然后, while循环,

if (success == false) { 
    Console.WriteLine("Please enter two valid conversion types \n"); 
} 
1

为了解决这个问题,我提取算法的一部分结合到单独的方法,从而可以隔离流量控制。我想通过编写搜索匹配用户的输入端,转换设置文件的方法启动:

private string[] FindConversionSetting(string[] input, StreamReader reader) 
{   
    do 
    { 
     string line = reader.ReadLine(); 
     if (line != null) 
     { 
      string[] settings = line.Split(','); 
      bool sourcesMatch = string.Compare(input[1], settings[0], true) == 0; 
      bool targetsMatch = string.Compare(input[2], settings[1], true) == 0; 

      if (sourcesMatch && targetsMatch) 
      {      
       return settings; // Match found 
      } 
     } 
    } while (line != null); 

    return null; // No match 
} 

接下来,创建一个名为ConvertAndDisplayInput隔离要执行方法的代码,一旦你找到了一个匹配 - 就像你上面的成功条件,所以我不会在这里重复。

最后,我会写控制逻辑(这里单转换所示,您可能希望呼叫者遍历,直到用户点击回车或东西):

// In Program.Main (for example) 

Console.WriteLine("Enter the conversion in the form (Amount, Convert from, Convert to)"); 

string input = Console.ReadLine(); 

using (StreamReader reader = new StreamReader("../../convert.txt") 
{ 
    string[] conversionSetting = this.FindConversionSetting(input, reader); 

    if (conversionSetting != null) 
    { 
     this.ConvertAndDisplayInput(input, conversionSetting); 
    } 
    else 
    { 
     Console.WriteLine("Please enter two valid conversion types \n"); 
    } 
}