[英]Converting Text File into a List <int> (C#)
我正在使用此鏈接作為起點。 我對 C# 完全陌生,但有 C/C++ 方面的經驗。 我的目標是重新創建排序算法並讓它們使用分叉相互競爭。 我已經成功地重新創建了歸並排序、冒泡和插入,並計划實施快速排序。
我創建了一個單獨的 class,它創建了一個包含 100,000 個隨機整數的文件,以正確測試排序算法的速度。
StreamWriter sw = new StreamWriter(@"C:\pathtofile\randomNumbers.txt");
int count = 0;
Random rnd = new Random();
int randomNumber;
int lines = 0;
while (count++ < 100000)
{
randomNumber = rnd.Next(1, 250);
sw.Write(randomNumber);
sw.Write(" "); // create white space
if(lines == 25) //formatting
{
sw.WriteLine("");
lines = 0;
}
lines++;
}
我從將這些整數存儲到數組列表中的主要 class 得到的錯誤此時失敗:
lists.Add(Convert.ToInt32(listInts[j]));
//錯誤:System.FormatException:'輸入字符串的格式不正確。'
據我所知,當它轉換整數時,它會獲取一個不是 integer 的值並且失敗。 但是,對我來說令人困惑的部分是當我手動輸入整數時它工作得很好。
例如:134 0 13 42 232 48 424 166 109
任何幫助將不勝感激。
C#Nooby
正如vetzascoa和Stas Ivanov所提到的,您的代碼中的異常可能是由未處理的空格和空字符串引起的。
要解決此問題,您可以修改將測試數據寫入文件的方法,如下所示:
static string Delimiter => " ";
static string LineBreak => "\r\n";
static void WriteTestFile(string fileName,
int dataLength = 100000,
int dataMinvalue = 1,
int dataMaxValue = 250,
int lineBreakPosition = 25)
{
int iterator = 0;
string delimiter;
Random rndGenerator = new Random();
int randomNumber;
using (var fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write))
using (var streamWriter = new StreamWriter(fileStream))
{
while (iterator < dataLength)
{
randomNumber = rndGenerator.Next(dataMinvalue, dataMaxValue);
delimiter = ++iterator % lineBreakPosition == 0 ? LineBreak : Delimiter;
streamWriter.Write($"{randomNumber}{delimiter}");
}
}
}
這樣,您可以避免在每行末尾出現多余的空格。 另外,請注意FileStream
、 StreamReader
和StreamWriter
是IDisposable
對象。 因此,它們應該在using(...)
或try/finally
塊中使用。
要讀取文件並將其內容轉換為List<int>
,您可以使用以下代碼:
static List<int> ReadTestFile(string fileName)
{
string fileContents;
using (var fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
using (var streamReader = new StreamReader(fileStream))
{
fileContents = streamReader.ReadToEnd();
}
var separators = string.Join("", LineBreak, Delimiter).ToCharArray();
var query = from item in fileContents
.Split(separators, StringSplitOptions.RemoveEmptyEntries)
select int.Parse(item);
return query.ToList();
}
使用StringSplitOptions.RemoveEmptyEntries
選項拆分文件內容字符串將排除由String.Split
方法生成的空條目/子字符串。 這將確保無錯誤的字符串到整數的轉換。
下面,您可以找到一個完整的最小工作解決方案來解決您的問題。
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace FileToListInt
{
class Program
{
static readonly string filePath = "randomNumbers.txt";
static string Delimiter => " ";
static string LineBreak => "\r\n";
static void WriteTestFile(string fileName,
int dataLength = 100000,
int dataMinvalue = 1,
int dataMaxValue = 250,
int lineBreakPosition = 25)
{
int iterator = 0;
string delimiter;
Random rndGenerator = new Random();
int randomNumber;
using (var fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write))
using (var streamWriter = new StreamWriter(fileStream))
{
while (iterator < dataLength)
{
randomNumber = rndGenerator.Next(dataMinvalue, dataMaxValue);
delimiter = ++iterator % lineBreakPosition == 0 ? LineBreak : Delimiter;
streamWriter.Write($"{randomNumber}{delimiter}");
}
}
}
static List<int> ReadTestFile(string fileName)
{
string fileContents;
using (var fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
using (var streamReader = new StreamReader(fileStream))
{
fileContents = streamReader.ReadToEnd();
}
var separators = string.Join("", LineBreak, Delimiter).ToCharArray();
var query = from item in fileContents
.Split(separators, StringSplitOptions.RemoveEmptyEntries)
select int.Parse(item);
return query.ToList();
}
static void Main(string[] args)
{
// Writing data to a test file
WriteTestFile(filePath);
// Reading result into a List<int>
List<int> data = ReadTestFile(filePath);
// Checking the number of readings
Console.WriteLine(data.Count);
// Deleting test file
if (File.Exists(filePath))
File.Delete(filePath);
}
}
}
查看您遇到的錯誤,在我看來您沒有考慮換行符(至少我能夠以這種方式重現它)。
這就是它對包含新行的文件的工作方式(我使用了Split的重載,它接受要拆分的字符數組,此外,由於提供了StringSplitOptions ,它會忽略空條目):
using (var reader = new StreamReader(@"c:\temp\test.txt"))
{
var text = await reader.ReadToEndAsync();
var numbers = text.Split(new [] {' ', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries).Select(word => Convert.ToInt32(word));
// do something with numbers (IEnumerable<Int32>)
}
上面的代碼將數字存儲到IEnumerable集合中。 如果你需要一個數組,你應該調用ToArray() 。
我可以給你兩個解決方案。 其中之一是修改您用來創建帶有數字的文件的代碼。 另一個是通過您告訴我們的鏈接修改您正在使用的代碼。
您的代碼中的問題出在 while 循環內,當您將空白寫入文件時:
randomNumber = rnd.Next(1, 250);
sw.Write(randomNumber);
sw.Write(" "); // create white space <------ this line
這一行總是在數字后面寫一個空格。 這意味着您的文件將以空格結尾,而不是數字。 這會導致行中的異常
lists.Add(Convert.ToInt32(listInts[j]));
因為為文件中的最后一行生成了 listInts[j] = " "。
第一個可能的解決方案
當您要在文件中寫入一個空白空間時,只有在寫入最后一個數字之后才這樣做。 您的 while 循環應類似於以下內容:
while (count++ < 100000)
{
randomNumber = rnd.Next(1, 250);
sw.Write(randomNumber);
if (count < 100000) //avoid write a white space if is last number to write
{
sw.Write(" "); // create white space
}
if(lines == 25) //formatting
{
sw.WriteLine("");
lines = 0;
}
lines++;
}
第二種可能的解決方案
在您用於讀取文件的代碼中,只需從每行中刪除空白空格,然后再使用 function.Trim() 拆分為數組
String[] listInts = listLines[i].Trim().Split(' ');
而不是當前行
String[] listInts = listLines[i].Split(' ');
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.