用c#在txt文件中搜索字符串
Search for strings in a txt file with c#
我正在执行一项任务,该任务将显示有多少国家在 2004 年加入了欧盟。
我还想收到 2004 年加入的国家的名称。我开始做我的工作,但我只收到塞浦路斯。
问题是有几个国家在 2004 年加入了。
如何获取2004年加入的所有国家名称?
我在控制台应用程序 (.NET Framework) 中完成了我的任务。
对于该任务,我使用了一个包含数据的 txt 文件。
这是我的代码:
class Program
{
static List<Country> joining = new List<Country>();
static void read()
{
string[] rows=File.ReadAllLines("EU.txt");
foreach (var item in rows)
{
joining.Add(new Country(item));
}
}
static void Main(string[] args)
{
read();
// how many countries:
Console.WriteLine($"{joining.Count(item =>item.date.Split('.')[1] == "05" )}countries joined.");
//names:
Console.WriteLine($"Country names:{joining.Find(item =>item.date.Split('.')[1] == "05" ).name}"); // !!! this code is bad
Console.ReadKey();
}
}
class Country
{
//Fields
public string date, name;
//ctor
public Country(string row)
{
name=row.Split(';')[0];
date = row.Split(';')[1];
}
}
EU.txt:
Austria;1995.01.01
Belgium;1958.01.01
Bulgaria;2007.01.01
Cyprus;2004.05.01
Czech;2004.05.01
Denmark;1973.01.01
United Kingdom;1973.01.01
Estonia;2004.05.01
Finland;1995.01.01
France;1958.01.01
Greece;1981.01.01
Netherlands;1958.01.01
Croatia;2013;07.01
Ireland;1973.01.01
Poland;2004.05.01
Latvia;2004.05.01
Lithuania;2004.05.01
Luxemburg;1958.01.01
Hungary;2004.05.01
Malta;2004.05.01
Germany;1958.01.01
Italy;1958.01.01
Portugal;1986.01.01
Romania;2007.01.01
Spain;1986.01.01
Sweden;1995.01.01
Szlovakia;2004.05.01
Szlovenia;2004.05.01
好吧,joining.Find(...)
只会找到 第一个 项(在您的情况下是 Cyprus
)。您可以改用 Linq Where
。请注意,您应该比较 "2004"
(年),而不是 "05"
(月):
using System.Linq;
...
// names:
var names = joining
.Where(item => item.date.Split('.')[0] == "2004")
.Select(item => item.name);
// let's join all the names by ", ":
Console.WriteLine($"Country names:{string.Join(", ", names)}");
编辑: 然而,像item.date.Split('.')[1] == "2004"
这样的比较看起来很难看(我为什么要在strings上查询日期?)。
让 Country
class 帮助自己(日期、姓名等):
class Country {
public string Name {get;}
public DateTime JoinedDate {get;}
public Country(string row) {
if (row == null)
throw new ArgumentNullException(nameof(row));
string[] items = row.Split(';', 2);
if (items.Length < 2)
throw new FormatException("Invalid row format");
Name = items[0];
JoinedDate = DateTime.ParseExact(items[1], "yyyy.M.d");
}
public override string ToString() => Name;
}
然后就是Linq(我们查询EU.txt
文件):
static void Main(string[] args) {
List<Country> joined2004 = File
.ReadLines("EU.txt")
.Select(line => new Country(line))
.Where(country => country.JoinedDate.Year == 2004)
.ToList();
Console.WriteLine($"{joined2004.Count} countries joined.");
Console.WriteLine($"{string.Join(", ", joined2004)}")
}
这里有很多小变化:
class Program
{
static List<Country> Countries;
// Use types and methods that avoid needing to load full sets into RAM all at once
// for as long as possible. That means IEnumerable rather than List and ReadLines()
// rather than ReadAllLines().
// It's also better for the read() function accept a value and return the result
static IEnumerable<Country> ReadCountries(string filePath)
{
// No need to allocate so much RAM via ReadAllLines()
// Better to just have one line in RAM at a time until everything is loaded
return File.ReadLines(filePath)
.Select(line => new Country(line));
}
static void Main(string[] args)
{
Countries = ReadCountries("EU.txt").ToList();
var JoinedIn2004 = Countries.Where(c => c.date.Year == 2004);
Console.WriteLine($"{JoinedIn2004.Count()} countries joined.\nCountry name:");
// need to loop through the list to get all the names
foreach(var country in JoinedIn2004)
{
Console.WriteLine(country.name);
}
// Alternatively, if you really don't want to write a loop:
// Console.WriteLine(string.Join("\n", JoinedIn2004));
Console.ReadKey(true);
}
}
class Country
{
// properties > fields
public string name {get;set;}
public DateTime date {get;set;} //Parse an actual DateTime for this!
//personally I lean towards a static builder method (Country.FromTextLine())
// for this, to decouple building the type from any specific file,
// but I also get it's overkill here.
public Country(string row)
{
var format = "yyyy.MM.dd";
var fields = row.Split(';');
name = fields[0];
date = DateTime.ParseExact(fields[1], format, null);
}
}
List<Country> result = joining.FindAll(item =>item.date.Split('.')[1] == "05");
Console.Write($"Country names:");
foreach(Country country in result)
{
Console.Write($"{country.name} ");
}
Console.WriteLine();
我正在执行一项任务,该任务将显示有多少国家在 2004 年加入了欧盟。 我还想收到 2004 年加入的国家的名称。我开始做我的工作,但我只收到塞浦路斯。 问题是有几个国家在 2004 年加入了。 如何获取2004年加入的所有国家名称? 我在控制台应用程序 (.NET Framework) 中完成了我的任务。 对于该任务,我使用了一个包含数据的 txt 文件。 这是我的代码:
class Program
{
static List<Country> joining = new List<Country>();
static void read()
{
string[] rows=File.ReadAllLines("EU.txt");
foreach (var item in rows)
{
joining.Add(new Country(item));
}
}
static void Main(string[] args)
{
read();
// how many countries:
Console.WriteLine($"{joining.Count(item =>item.date.Split('.')[1] == "05" )}countries joined.");
//names:
Console.WriteLine($"Country names:{joining.Find(item =>item.date.Split('.')[1] == "05" ).name}"); // !!! this code is bad
Console.ReadKey();
}
}
class Country
{
//Fields
public string date, name;
//ctor
public Country(string row)
{
name=row.Split(';')[0];
date = row.Split(';')[1];
}
}
EU.txt:
Austria;1995.01.01 Belgium;1958.01.01 Bulgaria;2007.01.01 Cyprus;2004.05.01 Czech;2004.05.01 Denmark;1973.01.01 United Kingdom;1973.01.01 Estonia;2004.05.01 Finland;1995.01.01 France;1958.01.01 Greece;1981.01.01 Netherlands;1958.01.01 Croatia;2013;07.01 Ireland;1973.01.01 Poland;2004.05.01 Latvia;2004.05.01 Lithuania;2004.05.01 Luxemburg;1958.01.01 Hungary;2004.05.01 Malta;2004.05.01 Germany;1958.01.01 Italy;1958.01.01 Portugal;1986.01.01 Romania;2007.01.01 Spain;1986.01.01 Sweden;1995.01.01 Szlovakia;2004.05.01 Szlovenia;2004.05.01
好吧,joining.Find(...)
只会找到 第一个 项(在您的情况下是 Cyprus
)。您可以改用 Linq Where
。请注意,您应该比较 "2004"
(年),而不是 "05"
(月):
using System.Linq;
...
// names:
var names = joining
.Where(item => item.date.Split('.')[0] == "2004")
.Select(item => item.name);
// let's join all the names by ", ":
Console.WriteLine($"Country names:{string.Join(", ", names)}");
编辑: 然而,像item.date.Split('.')[1] == "2004"
这样的比较看起来很难看(我为什么要在strings上查询日期?)。
让 Country
class 帮助自己(日期、姓名等):
class Country {
public string Name {get;}
public DateTime JoinedDate {get;}
public Country(string row) {
if (row == null)
throw new ArgumentNullException(nameof(row));
string[] items = row.Split(';', 2);
if (items.Length < 2)
throw new FormatException("Invalid row format");
Name = items[0];
JoinedDate = DateTime.ParseExact(items[1], "yyyy.M.d");
}
public override string ToString() => Name;
}
然后就是Linq(我们查询EU.txt
文件):
static void Main(string[] args) {
List<Country> joined2004 = File
.ReadLines("EU.txt")
.Select(line => new Country(line))
.Where(country => country.JoinedDate.Year == 2004)
.ToList();
Console.WriteLine($"{joined2004.Count} countries joined.");
Console.WriteLine($"{string.Join(", ", joined2004)}")
}
这里有很多小变化:
class Program
{
static List<Country> Countries;
// Use types and methods that avoid needing to load full sets into RAM all at once
// for as long as possible. That means IEnumerable rather than List and ReadLines()
// rather than ReadAllLines().
// It's also better for the read() function accept a value and return the result
static IEnumerable<Country> ReadCountries(string filePath)
{
// No need to allocate so much RAM via ReadAllLines()
// Better to just have one line in RAM at a time until everything is loaded
return File.ReadLines(filePath)
.Select(line => new Country(line));
}
static void Main(string[] args)
{
Countries = ReadCountries("EU.txt").ToList();
var JoinedIn2004 = Countries.Where(c => c.date.Year == 2004);
Console.WriteLine($"{JoinedIn2004.Count()} countries joined.\nCountry name:");
// need to loop through the list to get all the names
foreach(var country in JoinedIn2004)
{
Console.WriteLine(country.name);
}
// Alternatively, if you really don't want to write a loop:
// Console.WriteLine(string.Join("\n", JoinedIn2004));
Console.ReadKey(true);
}
}
class Country
{
// properties > fields
public string name {get;set;}
public DateTime date {get;set;} //Parse an actual DateTime for this!
//personally I lean towards a static builder method (Country.FromTextLine())
// for this, to decouple building the type from any specific file,
// but I also get it's overkill here.
public Country(string row)
{
var format = "yyyy.MM.dd";
var fields = row.Split(';');
name = fields[0];
date = DateTime.ParseExact(fields[1], format, null);
}
}
List<Country> result = joining.FindAll(item =>item.date.Split('.')[1] == "05");
Console.Write($"Country names:");
foreach(Country country in result)
{
Console.Write($"{country.name} ");
}
Console.WriteLine();