I am trying to read a text file and store the data inside into structs and I am interested in finding out how to ignore the first 4 lines (text header) in the text file.
This is the text file:
text file
I am only going to need the numeric values from it (year int, month int, max double, etc.) and ignore the four text lines above them.
This is the code I use to store the values as a collection of structs:
code
You can use func dropFirst(_ n: Int) to skip initial lines:
let lines = contents.components(separatedBy: "\n")
for line in lines.dropFirst(4) {
// ...
}
dropFirst(4) returns an “array slice” with all but the first 4
elements in the lines array, which means that the element storage
is not duplicated.
If it's always 4 lines then #Martin R has a good answer, otherwise you could see if the first word can be converted to an int like
for line in filtered {
let x = line.components(separatedBy: " ")
guard let year = Int(x[0] else {
continue
}
....
Related
I have a .csv file holding scores. This is what it looks like:
"name",10
The .csv is parsed with this function:
func _ready():
var file = File.new()
file.open("user://scores.csv", file.READ)
while !file.eof_reached():
line = file.get_csv_line()
text = text + "%s: %s" % [line[0], line[1]] + "\n" ## Invalid get index: '1' (on base: PoolStringArray)
The file must be ending in a new line. As a result, you get two lines while reading it. The first one has what you expect ([name, 10]), the second one is empty, causing an error when you try to index it.
When I tested this, the last line does not come as an empty array, but as an array with a single empty string. Looking around, this behavior has been there for a while. However, I found no bug reports or proposals, I wonder if there is a reason, or this was just overlooked.
You can check the number of columns you got. For example, the code below would skip any lines with not enough fields for your case:
if line.size() < 2:
continue
And this code will specifically target the extra line:
if file.eof_reached() and line.size() == 1 and line[0] == "":
break
My friends,
As a matter of fact, I am new to AS3. What I want is to read an external text file and then load it into three arrays. The text file has 3 columns, for example, something like this
Freq Mag Phase
2000 10 56
2200 8.2 -140
2600 14 -120
... ... ...
I want three arrays, each of which contains values from each column, for example, "freqArray" should be [2000 2200 2400] I would really appreciate your help.
There are some useful pieces of code out there. I use the code below, for example, but the problem is that 1) it does not separate spaces between columns, it just separates lines 2) I guess that entries in the array are characters, not numbers.
var myLoader:URLLoader = new URLLoader(new URLRequest("myText.txt");
var myArray:Array = new Array();
myLoader.addEventListener(Event.COMPLETE, loadComplete, false, 0, true);
function loadComplete(e:Event):void{
myArray = myLoader.data.split("\n");
for(var i:int = 0; i < myArray.length; ++i){
trace(myArray[i]); // To check if it works at this point
}
//now move on with the rest of your program/code
}
I use the code below, for example, but the problem is that...
(1) It does not separate spaces between columns, it just separates lines
(2) I guess that entries in the array are characters, not numbers.
(1)
It separates by new line because of your "\n". See example reference.
If you want SPACE instead then just put a space between the quote marks.
myArray = myLoader.data.split(" ");
(2) You can convert text (written as digits) into actual Numbers by data casting.
Set int If you want whole numbers eg: myVar = int( myArray[x] ); //x holds the 2200.
Set Number If you have fraction numbers eg: myVar = Number( myArray[x] ); //x hold 8.2.
where: x is the position, inside Array, that has the value you want to cast.
A faster trick to avoid creating some new variable (myVar) might be something like...
myArray[x] = int( myArray[x] ); //just overwrite the current text chars with actual integer
I have an array called temp containing double-precision values with dimensions 240×20×10428 . I would like to write it to a text file. I tried the following:
dlmwrite(['e:\temp\', str, '.txt'], temp, 'precision', 10);
now the problem is how to add \r\n\r\n string(two enter pressed key) after each first dimension (we have 240th of this dimension) in the text file? what should I have done? I want to have this format after all:
0.324235,...(20*10428 numbers),0.4363423,\r\n\r\n,
0.5467354,...(20*10428 numbers),0.346564,...
NOTE: this array come from .nc files and I want to convert them into .txt file using this way
The handy-dandy canned routines that ship with MATLAB are actually quite limited when it comes to customizability. Whenever you have some file writing to do with a custom format, it comes in handy to know how to do it yourself:
% Open file for writing, safely
fid = fopen(fullfile('e:\temp\', str, '.txt'), 'w');
OC = onCleanup(#() any(fopen('all')==fid) && fclose(fid));
% Simply loop through all rows
for ii = 1:size(temp,1)
% Format the numbers, with comma as separator
line = sprintf('%.10f,', temp(ii,:)); % (trick to concatenate last dimension into second one)
line(end) = []; %(remove last comma)
% Print this line, adding two PC-type newlines
fprintf(fid, '%s\r\n\r\n', line);
end
% Clean up
fclose(fid);
In general I'm defining a matlab fnction which takes the name of a file containing some numbers, one per line, reads the data in, and then returns the data in an array.
function x = readdata(filename)
This function takes the name of a file contained in the
% character array "filename", read in the data from it, and then
% return the resulting numbers in the 1-dimensional array x. The
% array x can be n x 1 or 1 x n, where n is the number of numbers
% in the data file.
%
% If the data file cannot be found, this function should print a
% warning (using the disp() function) and return x as an empty
% array. If the data file can be found but is empty or contains
% only comments (lines starting with the Matlab comment indicator %),
% this function should return an empty array x with no warning
% message.
%
%
%I'm not sure how to check if a file exist (while they are in same folder).
%I tried if exist(filename,'file') but this is not working
This is what I have now:
function x = readdata(file)
fid = fopen(file);
tline = fgets(fid);
while isnumeric(tline)
disp(tline)
tline = fgets(fid)
Thanks
I would start by taking a look at the documentation that you could find here for reading in line-by-line. It even gives a sample code that you could start with:
Reading Data Line-by-Line
MATLAB provides two functions that read lines from files and store them in
string vectors: fgetl and fgets. The fgets function copies the newline
character to the output string, but fgetl does not.
The following example uses fgetl to read an entire file one line at a time.
The function litcount determines whether an input literal string (literal)
appears in each line. If it does, the function prints the entire line preceded
by the number of times the literal string appears on the line.
function y = litcount(filename, literal)
% Search for number of string matches per line.
fid = fopen(filename);
y = 0;
tline = fgetl(fid);
while ischar(tline)
matches = strfind(tline, literal);
num = length(matches);
if num > 0
y = y + num;
fprintf(1,'%d:%s\n',num,tline);
end
tline = fgetl(fid);
end
fclose(fid);
You should be able to replace what is inside the while loop with what you are looking to do.
Of note is that the fgets and fgetl functions return character arrays (strings). Thus, you'll need to first check whether the line is a comment, and then, if not, convert the string to a numeric value using something along the lines of str2double.
As for checking existence of a file, exist(filename,'file') is definitely what you want. Its documentation is found here.
You should be able to do something like:
if ~exist(filename,'file')
% Do something... I suggest the warning function, disp could be used too...
warning('The file cannot be found!')
return
end
I am trying to extract every two consecutive columns from an array, writing a .dat with every pair. The problem is that, when using write.table() it overwrites the files. When I use print() instead of write.table() it shows the correct subsets, though.
I also need the file names to show the number of the pair of columns selected (a total of 6 pairs), as well as the number of the dimension (from 1 to 5). For this I have used an easier solution such as tagging 1:30.
for(i in 0:5) {
for (j in 1:5) {
for (k in 1:30) {
filename <- paste("Component",k, ".dat", sep="")
write.table(data[,c(2*i+1,2*i+2),j],col.names=F, row.names=F, sep= " ")
}
}
}
Any hints why it does not work?
I hope my goal is understandable. Thanks a lot for your time!
Set the argument append to TRUE:
write.table(data[,c(2*i+1,2*i+2),j],
file=filename,
append=TRUE,
col.names=F,
row.names=F,
sep= " ")
also, as correctly pointed out by #Roland, you have forgotten to pass the file argument (already added in my example above).