我试图找出解析这个以逗号分隔的文本文件的最佳方法。这是一段摘录:
bldgA, fred, lunch
bldgA, sally, supper
bldgB, bob, parking lot
bldgB, frank, rooftop
...
我要做的是读“bldgA”然后我想要那个人(第2栏),“fred”例如。但是我不想解析文件寻找“fred”因为fred可能不会在那里,而bldgA总是会在那里。我想阅读文本文件,看到我在bldgA上,并阅读我的列表中的下一个项目,即fred。之后,我想测试它是否是fred,sally等,并打印出第三列。我知道使用数据库可能会更容易,但对于一个小文本文件似乎有点开销,所以我可以命名列。在我使用Access或其他小东西之前,我想我会尝试Stack Overflow。这就是我所拥有的:
string BuildingFile = Server.MapPath("buildings.txt");
StreamReader FileStreamReader;
FileStreamReader = File.OpenText(BuildingFile);
while (FileStreamReader.Peek() != -1)
{
string[] words;
words = FileStreamReader.ReadLine().Split(',');
foreach (string word in words)
{
if (word == "bldgA")
{
//but since word is only on "bldgA"
//how can I get the next item in the list which
//is on the same line?
//print out the name of the person and then the duty
}
if (word == "bldgB")
{
//same as A
}
}
}
FileStreamReader.Close();
我的最终输出是
“你在bldgA,你的名字是弗雷德,你的职责是午餐”
答案 0 :(得分:3)
如果你知道文件的格式是否正确,你可以做一些事情(使用你的代码,假设语言是C#):
String MyLocation = System.Net.Dns.GetHostName();
string MachineFile = Server.MapPath("buildings.txt");
StreamReader FileStreamReader;
FileStreamReader = File.OpenText(MachineFile);
while (FileStreamReader.Peek() != -1)
{
string[] words;
words = FileStreamReader.ReadLine().Split(',');
if(words.Length == 3)
{
StringBuilder output = new StringBUilder;
output.Append("You are in ");
output.Append(words[0]);
output.Append(" and your name is ");
output.Append(words[1]);
output.Append(" and your duty is ");
output.AppendLine(words[2]);
}
}
FileStreamReader.Close();
答案 1 :(得分:2)
使用FileHelpers库。它允许您创建用于存储数据的类,并提供一种简单的方法来解析数据存储(包括csv)以填充这些类。
但是,正如您所建议的那样,这似乎是数据库的工作。我考虑SQLite。
答案 2 :(得分:1)
为什么不做这样的事情,而不是使用foreach循环:
words = FileStreamReader.ReadLine().Split(',', 3);
StringBuilder output = new StringBuilder();
if (words.Length >= 1)
{
output.AppendFormat("You are in {0}", words[0]);
if (words.Length >= 2)
{
output.AppendFormat(" and your name is {0}", words[1]);
if (words.Length >= 3)
{
output.AppendFormat(" and your duty is {0}", words[2]);
}
}
}
Console.WriteLine(output.ToString()); // or write wherever else you want your output to go
答案 3 :(得分:1)
答案 4 :(得分:0)
基本上使用状态机。有一个名为“building”的变量,并在遇到建筑物名称时将其存储在那里。然后是人们在该建筑物上运行的人名的案例。
你的解释不是很清楚,你的例子很奇怪。如果你可以改写,我很可能会提供更好的答案。
答案 5 :(得分:0)
我认为你的摘录是这样的:
bldgA,弗雷,午餐
bldgA,莎莉,夜宵
bldgB,bob,停车场
bldgB,frank,roof
获得所需输出的步骤:
split
函数通常是正则表达式库的一部分。
在Common Lisp中,这可以这样写:
(defun show-people-status (filename)
(with-open-file (input-stream filename)
(do ((line (read-line input-stream nil nil)
(read-line input-stream nil nil)))
((null line) t)
(apply #'format t "You are in ~a, your name is ~a, and your duty is ~a.~%"
(cl-ppcre:split "," line)))))
在Perl中,您可以使用以下内容:
#!/usr/bin/perl -w
use strict;
use Tie::File;
tie (@data, 'Tie::File', $ARGV[0]);
foreach (@data) {
(my $Building, my $Name, my $Duty) = split (/,/);
print "You are in $Building, your name is $Name, and your duty is $Duty."; };
请注意,Perl版本旨在作为独立脚本,而CL版本显示要从运行时使用的函数。两者都没有输入检查。
答案 6 :(得分:0)
在伪代码中:
#!/usr/bin/env python
import csv
with open('buildings.txt') as csvfile:
for building, name, duty in csv.reader(csvfile):
print("You are in %(building)s"
" and your name is %(name)s"
" and your duty is %(duty)s" % vars())
答案 7 :(得分:0)
原谅我用这种方式编程,但我认为它可以解决你的问题。
我做的唯一假设是在buildings.txt中的某个地方有一个名为“bldgA”的列,右边总共有2列,这些是你想要的数据。
private static int GetIndexOf(string hay, string needle, char delimiter)
{
return Array.FindIndex<string>(hay.Split(delimiter), delegate(string match)
{
if (needle.Equals(match.Trim()))
return true;
else
return false;
});
}
static void Main(string[] args)
{
StreamReader sr = new StreamReader(Server.MapPath("buildings.txt"));
using (sr)
{
for (string line; null != (line = sr.ReadLine()) && -1 != GetIndexOf(line, "bldgA", ','); )
{
Console.WriteLine("You are in bldgA and your name is {0} and your duty is {1}",
line.Split(',')[GetIndexOf(line, "bldgA", ',') + 1].Trim(),
line.Split(',')[GetIndexOf(line, "bldgA", ',') + 2].Trim());
}
}
}