固定長データ
Posted feedbacks - C#
投稿速さ重視で
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | using System;
using System.Collections.Generic;
using System.IO;
struct MenuList
{
public string Day;
public string Firstbread;
public string Lunch;
public string Dinner;
}
struct Record
{
public string FirstName;
public string SecondName;
public string Sex;
public string Age;
public string Year;
public string Month;
public List<MenuList> Menu;
}
class Program
{
static void Main(string[] args)
{
List<Record> meibo = new List<Record>();
//テストデータ作成
using (StreamWriter sw = new StreamWriter(@"C:\testdata.txt"))
{
for (int i = 0; i < 500; i++)
{
sw.Write("{0, -12}", "Yamada");
sw.Write("{0, -12}", "Tarou");
sw.Write("{0, 1}", "M");
sw.Write("{0, 3}", "26");
sw.Write("{0, 4}", "2008");
sw.Write("{0, 2}", "03");
for (int j = 1; j <= 31; j++)
{
sw.Write("{0:00}", j);
sw.Write("{0,-500}", "Yamada");
sw.Write("{0,-500}", "Yamada");
sw.Write("{0,-500}", "Yamada");
}
}
sw.Dispose();
}
using (StreamReader sr = new StreamReader(@"C:\testdata.txt"))
{
Record temp;
while (!sr.EndOfStream)
{
temp = new Record();
char[] buffer;
//性
buffer = new char[12];
sr.Read(buffer, 0, buffer.Length);
temp.FirstName = string.Format("{0:s12}", new string(buffer));
//名
buffer = new char[12];
sr.Read(buffer, 0, buffer.Length);
temp.SecondName = string.Format("{0:s12}", new string(buffer));
//性別
buffer = new char[1];
sr.Read(buffer, 0, buffer.Length);
temp.Sex = string.Format("{0:s1}", new string(buffer));
//年齢
buffer = new char[3];
sr.Read(buffer, 0, buffer.Length);
temp.Age = string.Format("{0,3:s3}", new string(buffer));
//年
buffer = new char[4];
sr.Read(buffer, 0, buffer.Length);
temp.Year = string.Format("{0:s4}", new string(buffer));
//月
buffer = new char[2];
sr.Read(buffer, 0, buffer.Length);
temp.Month = string.Format("{0:s2}", new string(buffer));
//ループ
temp.Menu = new List<MenuList>();
for (int i = 1; i <= 31; i++)
{
MenuList temp2 = new MenuList();
//日
buffer = new char[2];
sr.Read(buffer, 0, buffer.Length);
temp2.Day = string.Format("{0:s2}", new string(buffer));
//朝食
buffer = new char[500];
sr.Read(buffer, 0, buffer.Length);
temp2.Firstbread = string.Format("{0:s500}", new string(buffer));
//昼食
buffer = new char[500];
sr.Read(buffer, 0, buffer.Length);
temp2.Lunch = string.Format("{0:s500}", new string(buffer));
//夕食
buffer = new char[500];
sr.Read(buffer, 0, buffer.Length);
temp2.Dinner = string.Format("{0:s500}", new string(buffer));
temp.Menu.Add(temp2);
}
meibo.Add(temp);
}
foreach (Record result in meibo)
{
Console.WriteLine("FirstName : {0}", result.FirstName);
Console.WriteLine("SecondName : {0}", result.SecondName);
Console.WriteLine("Sex : {0}", result.Sex);
Console.WriteLine("Age : {0}", result.Age);
Console.WriteLine("Year : {0}", result.Year);
Console.WriteLine("Month : {0}", result.Month);
foreach (MenuList result2 in result.Menu)
{
Console.WriteLine("Day : {0}", result2.Day);
Console.WriteLine("Firstbread : {0}", result2.Firstbread);
Console.WriteLine("Lunch : {0}", result2.Lunch);
Console.WriteLine("Dinner : {0}", result2.Dinner);
}
}
sr.Dispose();
}
}
}
|
Microsoft.VisualBasic.FileIO.TextFieldParserってとっても便利なんですよ~、と書いてみたら、 TextFieldParserはレコードの区切りに改行がないと駄目なようです。 てことで、とても無理やりなコードになりました。 テストデータの生成にtenkaさんの#6079のコードの一部を頂きました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | //http://ja.doukaku.org/170/ 投稿用
using System.Collections.Generic;
using System.IO;
using System.Text;
using Microsoft.VisualBasic.FileIO;
namespace どう書く_org固定長データ {
class Program {
static void Main(string[] args) {
////テストデータ作成
//using(StreamWriter sw = new StreamWriter(@"C:\testdata.txt")) {
// for(int i = 0; i < 500; i++) {
// sw.Write("{0, -12}", "Yamada");
// sw.Write("{0, -12}", "Tarou");
// sw.Write("{0, 1}", "M");
// sw.Write("{0, 3}", "26");
// sw.Write("{0, 4}", "2008");
// sw.Write("{0, 2}", "03");
// for(int j = 1; j <= 31; j++) {
// sw.Write("{0:00}", j);
// sw.Write("{0,-500}", "Yamada");
// sw.Write("{0,-500}", "Yamada");
// sw.Write("{0,-500}", "Yamada");
// }
// }
// sw.Dispose();
//}
//ファイル読み込み
StreamReader sr = new StreamReader(@"C:\testdata.txt");
StringBuilder sb = new StringBuilder(sr.ReadToEnd());
//フィールドの幅の配列を作成
int recordLength = 0;
List<int> fieldWidths = new List<int>();
fieldWidths.AddRange(new int[] { 12, 12, 1, 3, 4, 2 });
for(int i = 0; i < 31; i++) {
fieldWidths.AddRange(new int[] { 2, 500, 500, 500 });
}
foreach(int i in fieldWidths) {
recordLength += i;
}
TextFieldParser tfp = getTfp(fieldWidths.ToArray(), sb.ToString().Substring(0, recordLength));
List<Record> Table = new List<Record>();
while(!tfp.EndOfData) {
string[] fields = tfp.ReadFields();
Record record = new Record() {
LastName = fields[0],
FirstName = fields[1],
Sex = fields[2],
Age = fields[3],
Year = fields[4],
Month = fields[5],
MenuList = new List<DayMenu>()
};
for(int i = 6; i < fields.Length; i = i + 4) {
record.MenuList.Add(new DayMenu() {
Day = fields[i],
Firstbread = fields[i + 1],
Lunch = fields[i + 2],
Dinner = fields[i + 3],
});
}
Table.Add(record);
sb.Remove(0, recordLength);
if(sb.Length == 0) break;
tfp = getTfp(fieldWidths.ToArray(), sb.ToString(0, recordLength));
}
tfp.Close();
}
static TextFieldParser getTfp(int[] fieldWidths,string value) {
TextFieldParser tfp = new TextFieldParser(new StringReader(value));
tfp.TextFieldType = FieldType.FixedWidth;
tfp.FieldWidths = fieldWidths;
return tfp;
}
}
class Record {
public string LastName { set; get; }
public string FirstName { set; get; }
public string Sex { set; get; }
public string Age { set; get; }
public string Year { set; get; }
public string Month { set; get; }
public List<DayMenu> MenuList { set; get; }
}
class DayMenu {
public string Day { set; get; }
public string Firstbread { set; get; }
public string Lunch { set; get; }
public string Dinner { set; get; }
}
}
|


Mymelo #6060() Rating5/7=0.71
固定長のデータが記載されたファイルを読み込むプログラムを作成してください。読み込んだデータは、複数の値を格納できるデータ型に格納してください。
ファイルには、すべて ascii 文字で以下のデータが格納されています。デリミタはなく、固定長で格納されています。レコードとレコードのあいだも改行はありません。
以上の形式のデータ500人分を読みこんで、データを複数の値を格納できるデータ型に格納してください。データに大して何か処理を行う必要はなく、すぐに破棄してかまいません。
この問題は、このようなファイルをどのように扱うかを知りたくて作成しました。
[ reply ]