Для случая, когда вы знаете, сколько столбцов данных будет в вашем CSV-файле, одним простым вызовом textscan
подобно Амро предполагает, что будет вашим лучшим решением.
Однако, если вы не знаете априори , сколько столбцов в вашем файле, вы можете использовать более общий подход, как я сделал в следующей функции.Сначала я использовал функцию fgetl
, чтобы прочитать каждую строку файла в массив ячеек.Затем я использовал функцию textscan
, чтобы проанализировать каждую строку в отдельные строки, используя предопределенный разделитель полей и пока что целочисленные поля считались строками (они могут быть позже преобразованы в числовые значения).Вот результирующий код, помещенный в функцию read_mixed_csv
:
function lineArray = read_mixed_csv(fileName, delimiter)
fid = fopen(fileName, 'r'); % Open the file
lineArray = cell(100, 1); % Preallocate a cell array (ideally slightly
% larger than is needed)
lineIndex = 1; % Index of cell to place the next line in
nextLine = fgetl(fid); % Read the first line from the file
while ~isequal(nextLine, -1) % Loop while not at the end of the file
lineArray{lineIndex} = nextLine; % Add the line to the cell array
lineIndex = lineIndex+1; % Increment the line index
nextLine = fgetl(fid); % Read the next line from the file
end
fclose(fid); % Close the file
lineArray = lineArray(1:lineIndex-1); % Remove empty cells, if needed
for iLine = 1:lineIndex-1 % Loop over lines
lineData = textscan(lineArray{iLine}, '%s', ... % Read strings
'Delimiter', delimiter);
lineData = lineData{1}; % Remove cell encapsulation
if strcmp(lineArray{iLine}(end), delimiter) % Account for when the line
lineData{end+1} = ''; % ends with a delimiter
end
lineArray(iLine, 1:numel(lineData)) = lineData; % Overwrite line data
end
end
Запуск этой функции для содержимого файла примера из вопроса дает следующий результат:
>> data = read_mixed_csv('myfile.csv', ';')
data =
Columns 1 through 7
'04' 'abc' 'def' 'ghj' 'klm' '' ''
'' '' '' '' '' 'Test' 'text'
'' '' '' '' '' 'asdfhsdf' 'dsafdsag'
Columns 8 through 10
'' '' ''
'0xFF' '' ''
'0x0F0F' '' ''
Результатмассив ячеек 3 на 10 с одним полем на ячейку, где пропущенные поля представлены пустой строкой ''
.Теперь вы можете получить доступ к каждой ячейке или комбинации ячеек, чтобы отформатировать их, как вам нравится.Например, если вы хотите изменить поля в первом столбце со строк на целочисленные значения, вы можете использовать функцию str2double
следующим образом:
>> data(:, 1) = cellfun(@(s) {str2double(s)}, data(:, 1))
data =
Columns 1 through 7
[ 4] 'abc' 'def' 'ghj' 'klm' '' ''
[NaN] '' '' '' '' 'Test' 'text'
[NaN] '' '' '' '' 'asdfhsdf' 'dsafdsag'
Columns 8 through 10
'' '' ''
'0xFF' '' ''
'0x0F0F' '' ''
Обратите внимание, что пустойрезультаты полей в NaN
значениях.