Da @jgrant notiert in a comment, ist das Problem, dass Sie die Dateipositionsanzeige an den Anfang der Datei zurücksetzen müssen, wenn Sie Teile Ihrer Datei erneut lesen möchten.
Ich kann nicht wirklich sehen, warum Sie textscan
dreimal zu nennen sind versucht, den Grund, dass die Ausgabe von textscan
ist eine Zelle genau ist, dass Sie einen einzigen Aufruf kann es tun, dann die Ausgabespalten trennen:
tmpcell = textscan(fileId,'%s%f%f','Delimiter','\t'); % column of strings
compartment_name = tmpcell{1};
compartment_length = tmpcell{2};
compartment_diameter = tmpcell{3};
% or if you want to be fancy about it:
%[compartment_name, compartment_length, compartment_diameter] = tmpcell{:};
Der Grund, warum ich diese Antwort zu schreiben up ist Ihre letzte Bemerkung:
auch - ist es eine einfache Möglichkeit für mich, die 1x1-Zellen in eine Array-Format konvertieren? zB für compartment_name, wäre es ein Array von 1x106 Strings?
Dies deutet auf eine Verwechslung von Zeichenfolgen in MATLAB hin. In MATLAB sind Strings im Wesentlichen Arrays von Ganzzahlen. Sie können selbst sehen dies an einer Schnur, jede Art von Rechenoperation durchführen:
>> tmpstring = 'asdf'
tmpstring =
asdf
>> tmpstring*1
ans =
97 115 100 102
Die Zahlen Sie die ASCII-Darstellungen der Zeichen in der Zeichenfolge sehen sind. Das funktioniert auch umgekehrt: Sie können einen String aufbauen, indem Sie Integer in ein Array einfügen. Als in der Tat für alle Absichten und Zwecke reiht sind Integer Arrays:
>> isequal([97 115 100 102],'asdf')
ans =
1
Dies impliziert auch einige Einschränkungen für Streicher in MATLAB. Was Ihre Frage betrifft, ist, dass Sie nicht einfach ein Array von Strings erstellen können. Das wäre genau String-Verkettung: Wenn sowohl string1
als auch string2
nur Integer-Arrays sind, dann ist [string1, string2]
die Verkettung der beiden Strings.
Sie können dann denken, Strings horizontal zu stapeln, mit [string1; string2]
. Nun, das funktioniert genau so, wie es für zwei Integer-Arrays funktionieren würde: Sie können dies nur tun, wenn die Strings die gleiche Länge haben (Länge bedeutet jetzt size(string1,2)
).Im allgemeinen Fall können Sie also nur Strings zusammen in einem inhomogenen Container, d. H. Zellen in MATLAB, speichern. Sobald Sie Zellen haben, können Ihre Elemente jeden Typ und jede Form haben, so dass Sie einfach Strings beliebiger Länge zusammenschieben können, vertikal oder horizontal gestapelt, wie Sie es auch mögen.
So betrachten textscan
. Sie müssen diese Funktion implementieren, die Daten zurückgibt, die aus einer Datei gelesen werden. Die Daten können sowohl numerisch als auch Zeichenfolgen sein. Wie geht's? Genau das, was textscan
tut: Rückgabe numerische Spalten als Arrays (da jede Zeile hat eine einzige skalare Daten), und geben Sie Zeichenfolgen als Zellen (da jede Zeile enthält eine Zeichenfolge, d. H. Ein Vektor an sich!). Sie könnte Stapel die Zeichenfolgen horizontal, aber das funktioniert nur, wenn jede Zeile in der angegebenen Spalte die gleiche Anzahl von Zeichen enthält, die offensichtlich nicht angenommen oder vorgeschrieben werden sollte. Sie können immer noch die Zeichenfolgen auf das längste Element auffüllen und ein gestapeltes Zeichenarray zurückgeben, aber dies würde in den meisten praktischen Anwendungen unnötigen Overhead einführen. (Randnotiz: textscan
gibt einen Zellenzeilenvektor als Ausgabe zurück, wobei jedes Zellenelement die vollständigen Daten in der angegebenen Spalte enthält. Für numerische Spalten ist diese "vollständige Daten" ein Array-Spaltenvektor und für String-Spalten eine Zellenspalte Vektor.)
So ist es sinnvoll, dass textscan
seine String-Spalten als Zellen zurückgibt. Sie können Ihre Strings trotzdem in ein 2d String-Array stapeln, wenn Sie möchten, aber in den meisten Fällen ist das nicht wirklich praktisch. Es hängt wirklich von Ihrer Anwendung ab.
Ein minimales Beispiel: bedenkt, dass tmp.inp
enthält
asf 3 4
asdg 2 3
asd 1 4
Jetzt
>> fid=fopen('tmp.inp','r'); outcell=textscan(fid,'%s%f%f'), fclose(fid);
outcell =
{3x1 cell} [3x1 double] [3x1 double]
kommt die Tatsache zeigt, dass der Ausgang der outcell
eine Zelle Zeilenvektor ist, auf eine Säule jedes Element liest entsprechende aus der Datei. Die eckigen Klammern um Spalte 2 und 3 zeigen an, dass diese Zellenelemente (nämlich outcell{2}
und outcell{3}
, nicht zu verwechseln mit outcell(2)
und outcell(3)
) numerische Arrays sind. Das erste Element ist jedoch eine Zelle Spaltenvektor:
>> outcell{1}
ans =
'asf'
'asdg'
'asd'
Die Tatsache, dass die Ausgabe mit Anführungszeichen gedruckt wird auf jede Zeile zeigt an, dass diese getrennte Zeichenfolgen in einer Zelle enthalten ist, aber Sie können dies auch sagen aus
>> whos ans
Name Size Bytes Class Attributes
ans 3x1 356 cell
Nun, wie ich schon sagte, können Sie Ihre Spalten stapeln auf dem jeweils anderen entscheiden, brauchen Sie nur char()
auf Ihrem Handy anrufen:
>> char(outcell{1})
ans =
asf
asdg
asd
>> whos ans
Name Size Bytes Class Attributes
ans 3x4 24 char
Beachten Sie das Fehlen von Anführungszeichen in der automatischen Ausgabe und die Klasse/Größe der Ausgabe. Die Größe 3x4
wurde ermöglicht, indem alle Zeilen auf die Länge der längsten Zeichenfolge aufgefüllt wurden, d. H. 4. Folglich endet die erste und dritte Zeile der Ausgabe mit einem Leerzeichen (dies ist gemeint, wenn die Zeichenfolgen erhalten).
Wenn Sie nicht über diese Polsterung durchführen, können Sie einfach Ihre Saiten lesen, wie die Zellelemente verweisen sie sind:
>> outcell{1}{3}
ans =
asd
Oder durch die Variable zu speichern, wie Sie wollten ursprünglich:
>> compartment_name=outcell{1}
compartment_name =
'asf'
'asdg'
'asd'
>> compartment_name{3}
ans =
asd
Ich denke, das Problem kann sein, dass die Dateipositionsanzeige nach dem ersten Textscan am Ende der Datei geparkt wird. Versuchen Sie 'fseek (fileId, 0, 'bof')', um den Indikator zwischen den Lesevorgängen an den Anfang der Datei zu verschieben. – jgrant