2017-03-29 78 views
-1

我試圖將一個字符串(例如「0.20055」)轉換爲等價的雙精度值。輸入字符串格式不正確(雙精度)

我已經知道,由於某種原因該字符串不包含有效的雙,但我不明白爲什麼。

我真的需要能夠將此字符串轉換爲雙...任何人都可以解釋爲什麼它不是一個有效的雙?以及如何解決這個問題?

下面是我的一些代碼:

double[] values_in_double = null; 
string[] values_in_string = lines[j].Split(','); 
for(int x=0; x < numCols; x++) 
{ 
    double val; 
    bool r = double.TryParse(values_in_string[x],out val); 
    if (!r) 
     return; 
    values_in_double[x] = Convert.ToDouble(values_in_string[x]); 

} 

正如你可以看到我有線條的string[],其中一條線是這樣的:

0.20055,0.37951,0.39641,2.0472,32.351, 0.38825,0.24976,1.3305,1.1389,0.50494

我把它們分開。但是,我需要將每個轉換爲雙重值。

+0

你爲什麼'return'如果一個值不轉換?爲什麼不只是「繼續」? 'return'會退出你所在的任何方法,'continue'只會跳過這個項目並繼續下一個。至少,你可能需要調用'break',它會跳出'for'循環並繼續使用它之後的任何代碼。或者檢查我的答案,以稍微不同的方式來做到這一點。 –

+0

如果TryParse返回false,則返回false,因爲對於這種情況,如果某些值未轉換,我不感興趣,所以我不能丟失數據。 –

回答

0

我會做你的代碼的主要變化是

  1. 刪除return聲明,因爲這將退出我們的方法過早
  2. 使用List<double>來存儲你的雙打(你沒有申報這是很好的,因爲我們不知道字符串中有多少項會成功轉換爲雙精度)
  3. 在將它添加到List時使用val變量,因爲double.TryParse已分配了價值這個VAR已經可以。

我還添加了檢查,以確保變量numRows不大於字符串數組大,因爲這會在我們的循環會導致異常:

// Mock values read from file 
var input = new StringBuilder(); 
input.Append("0.20055,0.37951,0.39641,2.0472,32.351,0.38825,0.24976,1.3305‌​,"); 
input.Append("1.1389,0.50494,0.24‌​976,0.6598,0.1666,0.‌​24976,497.42,0.73378‌​,"); 
input.Append("2.6349,0.24976,0.14‌​942,43.37,1.2479,0.2‌​1402,0.11998,0.47706‌​,"); 
input.Append("‌​0.50494,0.60411,1.4‌​582,1.7615,5.9443,0.‌​11788,593.27,0.50‌​591,"); 
input.Append("0.12804,0.66295,0.14942,94.14,‌​3.8772,0.56393,0.214‌​02,1.741,"); 
input.Append("1.5‌​225,49.394,0.1853,0.‌​11085,2.042,0.051402,0.12804,114‌​.42,"); 
input.Append("71.05,1.0097,348690,0.12196,0.39‌​718,0.87804,0.37854,‌​0.25792,"); 
input.Append("2.2437,2.248‌​,0.001924‌​,8.416,5.1372,82.658‌​,4.4158,7.4277"); 

string[] values_in_string = inputString.ToString().Split(','); 

// Declare values_in_double as a List so we don't have to worry about sizing 
List<double> values_in_double = new List<double>(); 

// We will get errors if numCols is larger than our string array, so to be safe, 
// set a variable that is the smallest of either numCols or our string array length 
var numIterations = Math.Min(numCols, values_in_string.Length); 

for (int x = 0; x < numIterations; x++) 
{ 
    double val; 

    // If TryParse succeeds, 'val' will contain the double value, so add it to our List 
    if (double.TryParse(values_in_string[x], NumberStyles.Any, 
     System.Globalization.CultureInfo.InvariantCulture, out val)) 
    { 
     values_in_double.Add(val); 
    } 
} 

還有在更短的方式編寫這段代碼。該生產線基本上是說:對於values_in_string每個項目,凡double.TryParse回報true,選擇val(項目作爲一個值)和所有val項目轉換成List

string[] values_in_string = inputString.ToString().Split(','); 
double val = 0; 

List<double> values_in_double = values_in_string 
    .Where(value => double.TryParse(value, NumberStyles.Any, 
     System.Globalization.CultureInfo.InvariantCulture, out val)) 
    .Select(v => val) 
    .ToList(); 
+0

是的,我理解代碼,我不明白爲什麼字符串仍然與它的雙倍不兼容...因爲對所有其中,TryParse返回false,除非它不是雙倍... –

+0

然後它必須是您的文化設置,因爲它對我來說在我們上面工作得很好。並非所有的文化都使用句點作爲小數標記。 https://en.wikipedia.org/wiki/Decimal_mark –

+0

如何將我的文化設置設置爲en-us? –

0

嘗試此

Double.TryParse(values_in_string [X],NumberStyles.Any,CultureInfo.InvariantCulture,出VAL);

0

變化

double[] values_in_double = null; 

    string[] values_in_string = lines[j].Split(','); 

string[] values_in_string = lines[j].Split(','); 
int arraySize = values_in_string.Length; 
double[] values_in_double = new double[arraySize]; 

你用

double[] values_in_double = null; 

和價值不能被分配到空數組

+0

做了,但它仍然不能轉換字符串 –

+0

這段代碼後,我說我的機器已經嘗試過這個錯誤,並且運行良好。修正後發送您的代碼。我會幫你 –

+0

你能告訴我「values_in_string」或「lines [j]」字符串 –

0

嘗試改變行:

double[] values_in_double = null; 

double[] values_in_double = new double[numCols]; 

因爲由於陣列未被定義,否則你提供的代碼將不運行(不能爲空)。

+0

是的,我已經這樣做了,但它仍然認爲該字符串不是有效的雙重字符 –

0

您遇到的問題是您的PC或服務器上的文化定義,如果定界符是','系統解釋''。作爲字符。

使用這樣的:

 double vValue; 
     string[] vValuesString = vLines[j].Split(','); 
     double[] vValuesDouble = new double[vValuesString.Length]; 

     for (int x = 0; x < vValuesString.Length; x++) 
      if (double.TryParse(vValuesString[x], System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out vValue)) 
       return; 'or use' continue;'or use' vValuesDouble[x] = 0; 
      else vValuesDouble[x] = vValue; 

注:

  • 比如你 '雙[] vValuesDouble =新的雙[vValuesString.Length]',你不能ASING將值空數組。
  • 當你使用TryParce時,out var返回的結果是將字符串轉換爲double,你不需要再次重新轉換它。
  • 永遠不要在循環中聲明變量,它會在循環的每一次運行中獲取聲明和實例。
  • TryParce返回一個bool值,該值指示轉換的結果,您不需要聲明和實例var,只需在if中使用它。
  • 使用一些協議來定義變量的名稱。
  • 嘗試恢復您的代碼最可能你可以。
  • 我把整個使用System.Globalization,但你可以聲明使用頂部或爲你的整個應用定義你的System.Globalization。
  • 最後,對不起我的英語,不是我的第一個語言。

最好。