構造体の配列のサイズが2パターンある場合にうまい具合にファイル出力する方法はありませんか?
<VBFixedArray(xx)>を使って2パターンの構造体を作り、関数を完全に分けてしまえば問題なく処理できるのですが、スマートじゃないように感じてしまい悩んでいます。
やりたいことは
Public Structure FILE_LAYOUT
<VBFixedStringAttribute(10)> Dim DataType As String
Dim TransitTime() As Short
Dim y() As Short
End Structure
Public Function makeFile(ByRef InputData As String) As String
Dim FileName As String
Dim tmpArray() As String
Dim FileData As FILE_LAYOUT
Dim DataSize As Integer
Dim i As Integer
Dim fn As Integer
tmpArray = InputData.Split(",")
If tmpArray(0).Equals("SMALL") Then
DataSize = 9
FileName = "small.dat"
Else
DataSize = 19
FileName = "large.dat"
End If
ReDim FileData.TransitTime(DataSize)
ReDim FileData.y(DataSize)
FileData.DataType = tmpArray(0)
For i = 0 To DataSize
FileData.TransitTime(i) = tmpArray(2 * i + 1)
FileData.y(i) = tmpArray(2 * i + 2)
Next
fn = FreeFile()
FileOpen(fn, FileName, OpenMode.Random, , , Len(FileData))
FilePut(fn, FileData)
FileClose(fn)
Return FileName
End Function
です。
このソースでは
System.IO.IOException: レコード長が正しくありません。
になってしまいます。
あらら、構文の基礎ができてないな。
入門からはじめましょう。
とりあえずバイト配列にしてみました
Public Structure FILE_LAYOUT
<VBFixedStringAttribute(10)> Dim DataType As String
Dim TransitTime() As Short
Dim y() As Short
End Structure
Public Function makeFile(ByRef InputData As String) As String
Dim FileName As String
Dim tmpArray() As String
Dim FileData As FILE_LAYOUT
Dim DataSize As Integer
Dim i As Integer
Dim fn As Integer
Dim writeArray() As Byte
Dim binWriter As BinaryWriter
tmpArray = InputData.Split(",")
If tmpArray(0).Equals("SMALL") Then
DataSize = 9
FileName = "small.dat"
Else
DataSize = 19
FileName = "large.dat"
End If
ReDim FileData.TransitTime(DataSize)
ReDim FileData.y(DataSize)
FileData.DataType = tmpArray(0)
For i = 0 To DataSize
FileData.TransitTime(i) = tmpArray(2 * i + 1)
FileData.y(i) = tmpArray(2 * i + 2)
Next
If DataSize = 9 Then
ReDim writeArray(49)
Else
ReDim writeArray(89)
End If
binWriter = New BinaryWriter(New IO.MemoryStream(writeArray))
Try
binWriter.Write(System.Text.Encoding.GetEncoding(932).GetBytes(FileData.DataType.PadRight(10)))
For i = 0 To DataSize
binWriter.Write(FileData.TransitTime(i))
Next
For i = 0 To DataSize
binWriter.Write(FileData.y(i))
Next
Finally
binWriter.Close()
End Try
fn = FreeFile()
FileOpen(fn, FileName, OpenMode.Random, , , writeArray.Length)
FilePut(fn, writeArray)
FileClose(fn)
Return FileName
End Function
C言語だとこんな感じかな
struct FILE_LAYOUT {
char *DataType;
short *TransitTime;
short *y;
};
char *makeFile(char *InputData)
{
char *FileName;
char *p1, p2;
struct FILE_LAYOUT FileData;
int DataCount;
int i;
int FileSize;
FILE *fp;
p1 = strtok(InputData, ",");
if( strcmp(p1, "SMALL") == 0 ) {
DataCount = 10;
FileSize = 50;
FileName = "small.dat";
} else {
DataCount = 20;
FileSize = 90;
FileName = "large.dat";
}
FileData.DataType = malloc(FileSize);
FileData.TransitTime = FileData.DataType + 10;
FileData.y = FileData.TransitTime + DataCount;
strcpy(FileData.DataType, p1);
for( i = 0; i < DataCount; i++ ) {
p1 = strtok(NULL, ",");
FileData.TransitTime[i] = (short)atoi(p1);
p1 = strtok(NULL, ",");
FileData.y[i] = (short)atoi(p1);
}
fp = fopen(FileName, "wb");
fwrite(FileData.DataType, 1, FileSize, fp);
fclose(fp);
free(FileData.DataType);
return FileName;
}
VBでできないかな〜
インターフェース使ったらどうだろう?
あとでためしてみよう
Dim TransitTime() As Short
Dim y() As Short
あはは。
ムリするなよ(笑)
本を買え。
買っても理解できなきゃ、絶対にコンピュター言語攻略はムリ。
子供の頃に勉強したことがなかろう?
毒毒しい発言だが、正しい解答である。
以上。
インターフェース全然使えない
Public Interface IFileLayout
Property DataType() As String
Property TransitTime(ByVal index As Integer) As Short
Property y(ByVal index As Integer) As Short
End Interface
Public Class SmallLayout
Implements IFileLayout
<VBFixedStringAttribute(10)> Dim _DataType As String
<VBFixedArray(9)> Dim _TransitTime() As Short
<VBFixedArray(9)> Dim _y() As Short
Public Property DataType() As String Implements IFileLayout.DataType
Get
Return _DataType
End Get
Set(ByVal value As String)
_DataType = value
End Set
End Property
Public Property TransitTime(ByVal index As Integer) As Short Implements IFileLayout.TransitTime
Get
Return _TransitTime(index)
End Get
Set(ByVal value As Short)
_TransitTime(index) = value
End Set
End Property
Public Property y(ByVal index As Integer) As Short Implements IFileLayout.y
Get
Return y(index)
End Get
Set(ByVal value As Short)
y(index) = value
End Set
End Property
Public Sub New()
ReDim _TransitTime(9)
ReDim _y(9)
End Sub
End Class
Public Function makeFile(ByRef InputData As String) As String
Dim FileName As String
Dim tmpArray() As String
Dim FileData As IFileLayout
Dim DataSize As Integer
Dim i As Integer
Dim fn As Integer
tmpArray = InputData.Split(",")
If tmpArray(0).Equals("SMALL") Then
DataSize = 9
FileName = "small.dat"
FileData = New SmallLayout
Else
DataSize = 19
FileName = "large.dat"
'FileData = New LargeLayout
End If
FileData.DataType = tmpArray(0)
For i = 0 To DataSize
FileData.TransitTime(i) = tmpArray(2 * i + 1)
FileData.y(i) = tmpArray(2 * i + 2)
Next
fn = FreeFile()
FileOpen(fn, FileName, OpenMode.Random, , , Len(FileData))
FilePut(fn, FileData)
FileClose(fn)
Return FileName
End Function
Set(ByVal value As Short)のところで
System.StackOverflowExceptionが発生してしまった
なぜスタックオーバーフローなのか?
インターフェースってどういう構造なのか?
いろいろ疑問が出てしまった