Как отобразить строку в таблице, используя Matlab
Это мой программный код:
fileID = fopen('PROBSET_102.csv','w');
a= 3;
lamda = 1.54;
fprintf(fileID, ' h, k, l ,d, theta \n');
for h = -8:8
for k = -8:8
for l = -8:8
d = sqrt((a^2)/(h^2 + k^2 + l^2));
c = (lamda/(2*d));
if c>1
theta = ('out of range');
else
theta = asind(c);
end
fprintf(fileID, ' %d, %d, %d, %d, %d\n',h,k,l,d,theta);
end
end
end
fclose(fileID);
Я пытаюсь напечатать следующие значения в таблице: h, k,l,d,theta. Но когда значение c больше 1, столбец тета должен отображать "вне диапазона" вместо вывода фактического числа. Пожалуйста помоги.
3 ответа
Решение, наиболее близкое к исходному коду:
Как и предполагал другой, ваш код ошибки, потому что вы отправляете данные другого типа в fprintf
, Вы можете указать другой format
за fprintf
и назовите его с этим конкретным форматом в условной части вашего кода (два других решения покажут вам, как это сделать).
Если вы хотите сохранить свой fprintf
вызов за пределами условной ветви, просто убедитесь, что ваш параметр theta
всегда один и тот же тип (string
в этом случае).
Так как конечным результатом будет преобразование чисел в строку в файле в любом случае, мы можем сделать это рано для этой переменной и убедиться, что fprintf
всегда получать один и тот же тип.
if c>1
theta = 'out of range' ; %// this is a string
else
theta = sprintf( '%d' , asind(c) ) ; %// this is also a string
end
fprintf(fileID, ' %d, %d, %d, %d, %s\n',h,k,l,d,theta); %// last parameter printed is a string
В качестве альтернативы:
Если вы гибки в тексте, который должен отображаться для значений " вне диапазона" (то есть если вы можете принять вместо "NaN"), тоNaN
(он обозначает Not A N number, но здесь это не важно) является допустимым числовым значением двойной точности, которое может быть легко обработано с помощью fprintf
(и семейство) функция.
Это означает, что вы можете избавиться от тройного вложенного for
цикл и векторизация вашего полного кода. На моей машине он выполняется примерно в 10 раз быстрее (вычисления + запись в файл), но ваш пробег может отличаться. Если вы планируете увеличить размер сетки, выигрыш в скорости будет еще более интересным, хотя будет размер, где память будет вашим ограничивающим фактором.
Векторизованный код выглядит следующим образом:
a= 3;
lamda = 1.54;
gridBase = -8:8 ; %// create a vector [-8 -7 -6 .... 6 7 8]
[L,K,H] = ndgrid(gridBase,gridBase,gridBase) ; %// Generate a grid
D = sqrt( (a.^2) ./ (H.^2 + K.^2 + L.^2) ); %// calculate D in one block (over the full grid)
C = lamda ./ (2.*D); %// same for C
C(C>1) = NaN ; %// make values of C>1 stand out (assign then to "Not a Number" NaN)
A = [H(:) K(:) L(:) D(:) C(:)] ; %// collate all that in a big table (equivalent to what you'll have in your file)
%// now write the array into file
fileID = fopen('PROBSET_102_alternate.csv','w');
fprintf(fileID, ' h, k, l ,d, theta \n'); %// write header line
fprintf(fileID, ' %d, %d, %d, %d, %d\n' , A.'); %'// let Matlab manage the write loop in the background (much faster)
fclose( fileID);
Если вам нужно понять код, я предлагаю вам запустить приведенную выше строку построчно (сначала с небольшого размера сетки) и посмотреть на переменные в проводнике рабочей области.
С %d
FormatSpec в fprintf
Вы можете экспортировать только целые числа, а не строки символов.
Вы должны изменить FormatSpec в fprintf
внутри вашего состояния:
% ...
if c>1
theta = ('out of range');
fprintf(fileID, ' %d, %d, %d, %d, %s\n',h,k,l,d,theta);
else
theta = asind(c);
fprintf(fileID, ' %d, %d, %d, %d, %d\n',h,k,l,d,theta);
end
% ...
или просто:
% ...
if c>1
fprintf(fileID, ' %d, %d, %d, %d, out of range\n',h,k,l,d);
else
theta = asind(c);
fprintf(fileID, ' %d, %d, %d, %d, %d\n',h,k,l,d,theta);
end
% ...
Вы должны сдвинуть fprintf
призывает в вашу логику для c
, С приведенной выше строкой формата ваш fprintf
звонок пытается распечатать theta
как двойной, когда это строка.
Это дает вам то, что вы ожидаете?
fileID = fopen('PROBSET_102.csv','w');
a= 3;
lamda = 1.54;
fprintf(fileID, ' h, k, l ,d, theta \n');
for h = -8:8
for k = -8:8
for l = -8:8
d = sqrt((a^2)/(h^2 + k^2 + l^2));
c = (lamda/(2*d));
if c>1
theta = ('out of range');
fprintf(fileID, ' %d, %d, %d, %d, %s\n',h,k,l,d,theta);
else
theta = asind(c);
fprintf(fileID, ' %d, %d, %d, %d, %d\n',h,k,l,d,theta);
end
end
end
end
fclose(fileID);