İçeriğe geç
KURUMSAL Kurumsal teknoloji · İşletmenize özel mühendislik Kurumsal Yazılım · Yönetilen Sunucular · Kurumsal E-posta · LiteSpeed + CloudLinux · Imunify360 Güvenlik · cPanel Yönetim · Uygun pakette 3 Gbps'ye kadar ağ profili
AIOR

MATLAB'da Workspace Verisini CSV'ye Nasıl Dışa Aktarırım?

  • Konu başlatıcısı Konu başlatıcısı Aior
  • Başlangıç tarihi Başlangıç tarihi
  • Etiketler Etiketler
    matlab

Aior

Administrator

Yetkili üye
Katıldı
2 Nis 2023
Mesajlar
929
Tepki puanı
2
Puan
18
Yaş
41
Konum
Turkey
Web sitesi
aior.com
Konu sahibi

MATLAB'da çalışma alanındaki (workspace) bir değişkeni CSV'ye yazmak çoğu zaman tek satırlık bir iştir. Sorunlar dosya başka bir yerde açılınca başlar: Türkçe Excel'de satırlar tek sütuna yığılır, ondalıklar metne ya da tarihe dönüşür, Türkçe harfler bozulur ya da eski sürüm kullanan bir iş arkadaşınız "Undefined function or variable 'writematrix'" hatası alır. Bu rehberde fonksiyonu veri tipine ve MATLAB sürümüne göre seçiyor, ardından bu sorunları tek tek çözüyoruz.

Kısa cevap​

R2019a ve sonrasında verinin tipine uyan fonksiyonu kullanın:
Kod:
writematrix(M, 'olcum.csv');   % sayısal matris
writetable(T, 'olcum.csv');    % tablo (table): değişken adları başlık olur
writecell(C, 'olcum.csv');     % hücre dizisi (cell array): metin ve sayı karışık olabilir
Daha eski bir sürümde sayısal veri için dlmwrite kullanın ve hassasiyeti mutlaka açıkça verin: dlmwrite('olcum.csv', M, 'precision', '%.6f'). Nedeni 5. bölümde. Çalışma alanındaki bütün değişkenleri tek seferde dışa aktarmak için 3. bölümdeki döngüyü kullanın.

1. Önce sürümünüzü kontrol edin​

version komutu kullandığınız sürümü gösterir. which writematrix komutu "'writematrix' not found." yanıtını veriyorsa fonksiyon o sürümde yoktur ve kodunuz o bilgisayarda çalışmaz; kodun içinde aynı kontrolü isempty(which('writematrix')) ile yapabilirsiniz. Tablo, bu yazıdaki özelliklerin hangi sürümde geldiğini MathWorks belgelerindeki sürüm geçmişine göre özetliyor.
SürümGelen özellik
R2006a öncesicsvwrite, dlmwrite, fopen/fprintf, save
R2013btable, writetable, readtable, struct2table, array2table
R2014bdatetime, round(x, n)
R2016b / R2017astring dizileri ve compose; çift tırnaklı "metin" yazımı R2017a ile geldi
R2019awritematrix, writecell, writetimetable, readmatrix; csvwrite ve dlmwrite artık önerilmiyor
R2019bTablo değişken adlarında boşluk ve Türkçe karakter kullanılabiliyor
R2020aYazma fonksiyonlarında WriteMode ('append' ile var olan dosyaya ekleme)
R2020breadtable için VariableNamingRule

2. Veri tipine göre karar tablosu​

Çalışma alanındaki veriR2019a ve sonrasıEski sürümlerdeDikkat
Sayısal matris (double, tamsayı, logical)writematrixdlmwrite + 'precision'Başlık satırı yazmaz
tablewritetablewritetable (R2013b ve sonrası)Değişken adları başlık olur
timetablewritetimetabletimetable2table + writetableSatır zamanları da yazılır
Hücre dizisi (metin ve sayı karışık)writecellfprintf döngüsüHücre içinde hücre hata verir
struct (yapı)struct2table + writetableAynısıAlanların satır sayısı eşit olmalı
datetime içeren veriTabloya koyup writetabledatestr + fprintfFormat özelliğini açıkça verin
Kod:
M = [0 21.4 1.013; 0.5 21.6 1.012; 1.0 21.9 1.011];
writematrix(M, 'matris.csv');

T = array2table(M, 'VariableNames', {'zaman_s', 'sicaklik_C', 'basinc_bar'});
writetable(T, 'tablo.csv');

C = {'Numune', 'Yuk_kN', 'Sonuc'; 'A-01', 12.4, 'kabul'; 'A-02', 11.9, 'ret'};
writecell(C, 'numune.csv');                  % ilk satır başlık

S.zaman_s = (0:0.5:1)';
S.akim_A  = [0.82; 0.85; 0.91];
writetable(struct2table(S), 'yapi.csv');     % her alan bir sütun
Yapı dizisinde (struct array) her eleman bir satır olur; alanları farklı uzunlukta olan tek elemanlı (skaler) bir yapıda ise struct2table hata verir.

3. Tüm çalışma alanını dışa aktarmak​

Bir CSV dosyası tek bir iki boyutlu tablo taşır; farklı boyutta matrisler, tablolar ve yapılar tek bir CSV'ye anlamlı biçimde sığmaz. Pratik yol, her değişkeni kendi CSV dosyasına yazmak ve kayıpsız yedek olarak bir .mat dosyası tutmaktır. İki yöntem de şu yardımcı fonksiyonu kullanıyor (degiskeniCsvYaz.m):
Kod:
function yazildi = degiskeniCsvYaz(v, dosya)
% Değişkeni tipine uygun fonksiyonla CSV'ye yazar (R2019a ve sonrası).
yazildi = true;
if isempty(v)
    yazildi = false;
elseif istable(v)
    writetable(v, dosya);
elseif istimetable(v)
    writetimetable(v, dosya);
elseif isstruct(v)
    writetable(struct2table(v), dosya);
elseif iscell(v)
    writecell(v, dosya);
elseif isnumeric(v) || islogical(v)
    writematrix(reshape(v, size(v, 1), []), dosya);  % 3 boyutlu diziyi 2 boyuta açar
else
    yazildi = false;   % char, string, nesne: bilinçli olarak atlanır
end
end

Yöntem A: who ve evalin ile döngü​

who, değişken adlarını hücre dizisi olarak döndürür. Kod bir fonksiyonda çalıştığı için değerler temel çalışma alanından (base workspace) evalin ile alınır ve döngünün kendi değişkenleri listeye karışmaz.
Kod:
function calismaAlaniniDisaAktar(klasor)
if ~exist(klasor, 'dir'), mkdir(klasor); end
adlar = evalin('base', 'who');
for k = 1:numel(adlar)
    dosya = fullfile(klasor, [adlar{k} '.csv']);
    try
        if degiskeniCsvYaz(evalin('base', adlar{k}), dosya)
            fprintf('Yazıldı: %s\n', dosya);
        else
            fprintf('Atlandı: %s\n', adlar{k});
        end
    catch hata
        fprintf('Yazılamadı: %s (%s)\n', adlar{k}, hata.message);
    end
end
end
calismaAlaniniDisaAktar('csv_cikti') ile çağırın. try/catch sayesinde sorunlu bir değişken işlemi durdurmaz; neyin neden yazılamadığı çıktıda görünür.

Yöntem B: önce .mat, sonra dönüştür​

Kod:
save('calisma_alani.mat');            % bütün değişkenler, tipleriyle
S = load('calisma_alani.mat');        % her değişken S'nin bir alanı
adlar = fieldnames(S);
for k = 1:numel(adlar)
    degiskeniCsvYaz(S.(adlar{k}), [adlar{k} '.csv']);
end
.mat dosyası tipleri ve tam hassasiyeti korur; dönüştürmeyi sonra ya da başka bir bilgisayarda yapabilirsiniz. whos('-file', 'calisma_alani.mat') içeriği yüklemeden listeler; 2 GB ve üzerindeki değişkenler için '-v7.3' ile kaydedin. Yalnızca bazı değişkenler gerekiyorsa whos çıktısını sınıfa göre süzün ya da who('-regexp', '^olcum_') ile adına göre seçin.

4. Başlıklar ve değişken adları​

writematrix başlık satırı yazmaz. Üç yol var:
  1. Tabloya çevirin: array2table ile sütunlara ad verip writetable kullanın. R2019b ve sonrasında "Sıcaklık (°C)" gibi boşluklu, Türkçe karakterli adlar geçerlidir; eski sürümlerde adlar geçerli MATLAB tanımlayıcısı olmalıdır (sicaklik_C gibi).
  2. Başlık ayrı, veri ekleme moduyla (R2020a ve sonrası): başlık writecell ile, sayılar writematrix ve 'WriteMode','append' ile.
  3. Eski sürümlerde: başlık fprintf ile, veri dlmwrite '-append' ile.
Kod:
% 1) Tablo (Türkçe başlık için R2019b ve sonrası)
T = array2table(M, 'VariableNames', {'Zaman (s)', 'Sıcaklık (°C)', 'Basınç (bar)'});
writetable(T, 'olcum1.csv', 'Encoding', 'UTF-8');

% 2) Başlık + ekleme (R2020a ve sonrası)
writecell({'zaman_s', 'sicaklik_C', 'basinc_bar'}, 'olcum2.csv');
writematrix(M, 'olcum2.csv', 'WriteMode', 'append');

% 3) Eski sürümler
fid = fopen('olcum3.csv', 'w');
fprintf(fid, 'zaman_s,sicaklik_C,basinc_bar\n');
fclose(fid);
dlmwrite('olcum3.csv', M, '-append', 'precision', '%.4f', 'newline', 'unix');
Birimleri başlığa yazın (sicaklik_C); satır adları için 'WriteRowNames', true ekleyin. Bir tabloyu writetable ile parça parça eklerken ekleme çağrılarında 'WriteVariableNames', false verin: belgelere göre 'append' modu, değişken adları yazılırken desteklenmez; başlık zaten yalnızca ilk çağrıda yazılmalıdır. Geri okurken Türkçe başlıkları korumak için R2020b ve sonrasında readtable(..., 'VariableNamingRule', 'preserve') kullanın (R2019b'de 'PreserveVariableNames', true).

5. Hassasiyet ve sayı biçimi​

writematrix, writetable ve writecell'de hassasiyet (precision) seçeneği yoktur. MathWorks belgelerine göre sayılar "long g" biçiminde, yani double için en fazla 15 anlamlı basamakla yazılır; pi dosyaya 3.14159265358979 olarak gider. Bu yüzden 0.1 + 0.2 sonucu (0.30000000000000004) dosyada 0.3 görünür ve geri okunan değer bit düzeyinde aynı olmaz. Ölçüm verisi için bu fark önemsizdir; birebir eşleşme gereken testlerde .mat kullanın ya da fprintf ile '%.17g' yazın.

Eski fonksiyonlarda durum daha ciddidir: csvwrite en fazla beş anlamlı basamak yazar, dlmwrite'ın varsayılan hassasiyeti de beş anlamlı basamaktır. 123456.789 dosyaya 1.2346e+05, yani 123460 olarak geçer; ne hata ne uyarı alırsınız. MathWorks bu iki fonksiyonu kaldırmayı planlamıyor; eski betikler çalışmaya devam eder ve kayıp fark edilmeden sürer.
Kod:
X = [pi 2.5; 1/3 123456.789];
writematrix(round(X, 3), 'yuvarlanmis.csv');   % 3.142,2.5 ve 0.333,123456.789

fid = fopen('sabit.csv', 'w');
fprintf(fid, 'a,b\n');
fprintf(fid, '%.3f,%.3f\n', X.');              % 3.142,2.500 ve 0.333,123456.789
fclose(fid);
round'dan sonra da writematrix sondaki sıfırları yazmaz (2.500 değil, 2.5); sabit sayıda ondalık için fprintf ya da compose kullanın. fprintf matrisi sütun sütun okuduğu için X yerine devriği (transpose, X.') verilir. Devriği unutursanız ilk satıra aynı sütunun değerleri (3.142,0.333) yazılır; CSV'lerde en sık gördüğümüz sessiz hatalardan biridir.

6. Türkçe Excel: noktalı virgül, ondalık virgül, UTF-8 ve tarihler​

Excel, Windows'ta CSV dosyasını çift tıklamayla açarken bölge ayarlarındaki liste ayırıcısını (list separator) kullanır. Türkçe ayarlarda liste ayırıcısı genellikle noktalı virgül, ondalık ayırıcı virgüldür; MATLAB'ın çıktısı ise virgülle ayrılmış ve noktalı ondalıklıdır. Üç ayrı sorun çıkar:
  • Ayraç: satırın tamamı A sütununda görünür.
  • Ondalık: noktalı sayılar metin kalabilir; 3.5 tarihe, 1.234 ise 1234'e dönüşebilir.
  • Kodlama: Excel'in birçok sürümü BOM (byte order mark) içermeyen UTF-8 dosyayı sistemin ANSI kod sayfasıyla (Türkçe Windows'ta Windows-1254) okur; ş, ğ, ı gibi harfler bozulur. Davranış Excel sürümüne ve Windows ayarlarına göre değişebildiği için BOM'suz UTF-8'in doğru tanınmasına güvenmeyin.
Dosyayı kim açacak?AyraçOndalıkKodlama
Türkçe Excel, çift tıklayarak;, (metne çevrilerek)UTF-8 + BOM ya da windows-1254
Python, R, veritabanı, başka yazılım,.UTF-8, BOM'suz
Excel, içe aktarma aracıyla,.UTF-8 (içe aktarırken 65001 seçilir)
Kimse yerel ayarla uğraşmak istemiyor--.xlsx yazın
İçe aktarma aracını Türkçe Excel'de kullanıyorsanız ondalık ayırıcının nokta olduğunu da belirtin: eski metin içe aktarma sihirbazında (Text Import Wizard) Gelişmiş (Advanced) düğmesinden ondalık ayırıcıyı nokta yapın; Power Query'de sütun türünü yerel ayar seçerek değiştirin (Change Type > Using Locale) ve İngilizce (ABD) seçin.

writematrix(M, 'dosya.csv', 'Delimiter', ';') yalnızca ayracı değiştirir (izin verilenler: virgül, boşluk, sekme, noktalı virgül, dikey çizgi); ondalık sorunu sürer. Türkçe Excel'de çift tıklayınca doğru açılan bir dosya şöyle yazılır:
Kod:
zaman = datetime(2026, 3, 14, 8, 30, 0) + minutes(0:2)';
T = table(zaman, [21.45; 21.60; 21.72], {'Kazan-1'; 'Kazan-1'; 'Şişirme-2'}, ...
          'VariableNames', {'Tarih', 'Sicaklik_C', 'Hat'});
T.Tarih.Format = 'dd.MM.yyyy HH:mm:ss';     % MM = ay, mm = dakika

Ttr = T;
Ttr.Sicaklik_C = replace(compose("%.2f", T.Sicaklik_C), ".", ",");   % 21,45
writetable(Ttr, 'rapor_tr.csv', 'Delimiter', ';', 'Encoding', 'UTF-8');
bomEkle('rapor_tr.csv');

% Yalnızca sayısal matris için aynı fikir:
writematrix(replace(compose("%.4f", M), ".", ","), 'matris_tr.csv', 'Delimiter', ';');
Beklenen içerik:
Kod:
Tarih;Sicaklik_C;Hat
14.03.2026 08:30:00;21,45;Kazan-1
14.03.2026 08:31:00;21,60;Kazan-1
14.03.2026 08:32:00;21,72;Şişirme-2
Ondalık virgülü yalnızca sayısal sütunlara uygulayın; dosyanın tamamında noktayı virgülle değiştirmek tarihleri de bozar. MATLAB belgelerinde yazma fonksiyonları için BOM seçeneği yer almadığından BOM'u kendiniz ekleyin (bomEkle.m):
Kod:
function bomEkle(dosya)
% UTF-8 dosyanın başına BOM (EF BB BF) ekler; zaten varsa dokunmaz.
fid = fopen(dosya, 'r');
if fid < 0, error('Okunamadı: %s', dosya); end
icerik = fread(fid, Inf, '*uint8');
fclose(fid);
bom = uint8([239; 187; 191]);
if numel(icerik) >= 3 && isequal(icerik(1:3), bom), return; end
fid = fopen(dosya, 'w');
if fid < 0, error('Yazılamadı: %s', dosya); end
fwrite(fid, [bom; icerik], 'uint8');
fclose(fid);
end
BOM bazı araçlarda ilk sütun adının başında görünmez bir karakter olarak kalır: Python'da encoding='utf-8-sig' ile okuyun, veri hattına (pipeline) giden dosyaya BOM eklemeyin. 'Encoding','windows-1254' ile yazmak, ancak dosyayı açan herkesin Windows'unda sistem yerel ayarı Türkçe olduğu sürece işe yarar; farklı yerel ayarlı bir bilgisayarda Türkçe harfler yine bozulur. Güncel MATLAB belgelerine göre fopen, writematrix, writetable ve writecell, yazarken kodlama belirtilmezse UTF-8 kullanır; eski sürümler sistem kodlamasını kullanabildiği için birden fazla sürümde çalışacak kodda kodlamayı her zaman açıkça yazın.
  • Tarihler: Format özelliğini her zaman açıkça verin. Türkçe Excel için dd.MM.yyyy HH:mm:ss, sistemler arası aktarım için ISO 8601 tarzı yyyy-MM-dd HH:mm:ss en güvenli seçimdir. Ay adı yazdırıyorsanız 'DateLocale','tr_TR' ekleyin. datetime'da MM ay, mm dakikadır; eski datestr'de tam tersi.
  • Satır sonları: writematrix, writetable ve writecell belgelerinde satır sonu seçeneği yok. Gerekirse dlmwrite 'newline' ('pc' = CRLF, 'unix' = LF) ya da fopen/fprintf kullanın.
  • sep=; satırı: yalnızca Excel tanır, diğer araçlar onu veri sanar. Önermiyoruz.
  • En az uğraş: writetable(T, 'rapor.xlsx'). Sayılar sayı kalır, datetime Excel tarihi olarak yazılır. Mevcut .xlsx üzerine yazarken varsayılan mod 'inplace' olduğundan eski satırlar kalabilir; R2020a ve sonrasında 'WriteMode','overwritesheet' kullanın.
Aynı ayraç ve ondalık sorunlarının BI tarafını Tableau'da ayraç, tarih ve ondalık sembolü yazımızda anlattık.

7. Büyük veri: ekleme modu ve parça parça yazma​

  • Veri bloklar hâlinde geliyorsa (R2020a ve sonrası): her blok için writematrix(blok, dosya, 'WriteMode', 'append'). İşlem yarıda kesilse de yazılanlar diskte kalır. Yeniden çalıştırmada yeni veri dünkü dosyanın sonuna eklenmesin diye betiğin başında eski dosyayı silin.
  • Genellikle daha hızlı: dosyayı her blokta yeniden açmak yerine fopen ile bir kez açıp blokları fprintf ile yazmak. Blok blok yazmak, fprintf'in ihtiyaç duyduğu devrik kopyayı da küçük tutar.
  • Kaynak büyük bir .mat dosyasıysa: matfile ile yalnızca gereken satırları okuyun (m.X(i:j, :)). MathWorks'e göre verimli parça okuma -v7.3 MAT dosyası gerektirir.
Kod:
function csvParcaliYaz(M, dosya, baslik, bicim, blok)
% Örnek: csvParcaliYaz(M, 'buyuk.csv', 'zaman_s,k1,k2', '%.6f,%.4f,%.4f\n', 1e5)
[fid, mesaj] = fopen(dosya, 'w', 'n', 'UTF-8');
if fid < 0, error('Dosya açılamadı: %s (%s)', dosya, mesaj); end
kapat = onCleanup(@() fclose(fid));   % hata olsa da dosya kapanır
fprintf(fid, '%s\n', baslik);
for i = 1:blok:size(M, 1)
    j = min(i + blok - 1, size(M, 1));
    fprintf(fid, bicim, M(i:j, :).');
end
end
Dosya gigabaytlarla ölçülmeye başladıysa CSV'nin doğru biçim olup olmadığını yeniden düşünün: metin dosyası çoğu zaman ikili (binary) biçimlerden büyüktür ve daha yavaş okunur. Veri MATLAB'a ya da Python'a dönecekse -v7.3 .mat veya parquetwrite (R2019a ve sonrası, table/timetable için) daha uygun olabilir.

8. Dosyayı geri okuyarak doğrulayın​

Yazma komutunun hata vermemesi dosyanın doğru olduğunu göstermez. Bir dakikalık kontrol, saatler sürecek yanlış bir analizin önüne geçer:
Kod:
A = readmatrix('olcum2.csv');                    % başlığı algılayıp atlar
assert(isequal(size(A), size(M)), 'Satır/sütun sayısı tutmuyor');
fprintf('En büyük fark: %g\n', max(abs(A(:) - M(:))));

T2 = readtable('rapor_tr.csv', 'Delimiter', ';', 'DecimalSeparator', ',', ...
               'Encoding', 'UTF-8', 'VariableNamingRule', 'preserve');
disp(T2)

fid = fopen('rapor_tr.csv', 'r'); ilk3 = fread(fid, 3, '*uint8')'; fclose(fid);
disp(ilk3)                                      % 239 187 191 ise BOM var
Tarih sütunu metin olarak gelirse T2.(1) = datetime(T2.(1), 'InputFormat', 'dd.MM.yyyy HH:mm:ss') ile çevirin; sütuna adıyla değil sıra numarasıyla erişmek, ilk başlığın önünde BOM kalmış olsa bile çalışır. R2019b'de VariableNamingRule yerine 'PreserveVariableNames', true kullanın; daha eski bir sürümde readtable bu seçeneklerden birini kabul etmezse aynı ayarları detectImportOptions nesnesine verin. Kontrol listesi: satır ve sütun sayısı, başlıklar, ondalık ayırıcı, en küçük ve en büyük değerler, NaN sayısı, Excel'de Türkçe karakterler.

Eksik değerler fonksiyona ve dosya türüne göre ya NaN yazısı ya da boş alan olarak dosyaya geçer: dlmwrite ve fprintf NaN yazar, Excel dosyasında (.xlsx) ise MATLAB hücreyi boş bırakır. Excel NaN yazısını sayı değil metin olarak görür. Hedef sistemin boş alan mı NaN mı beklediğini baştan netleştirin. Boş alan gerekiyorsa yazmadan önce sütunu metne çevirip NaN olanları boşaltın:
Kod:
s = compose("%.3f", T.Sicaklik_C);   % NaN, "NaN" metnine dönüşür
s(isnan(T.Sicaklik_C)) = "";         % ...ve boş alana çevrilir
T.Sicaklik_C = s;

Dosyayı bulamıyorsanız pwd geçerli klasörü gösterir. Dosya, Current Folder panelinde (yeni sürümlerde Files paneli) de listelenir; sağ tıklayıp Open Outside MATLAB seçeneğiyle işletim sisteminin CSV için kullandığı uygulamada, genellikle Excel'de açabilirsiniz. Windows'ta winopen(cd) klasörü Dosya Gezgini'nde açar; macOS'te system('open .'), Linux'ta system('xdg-open .') aynı işi görür.

9. GNU Octave karşılıkları​

Octave 11 kılavuzunun fonksiyon dizininde (docs.octave.org) writematrix, writecell, writetable, readmatrix ve readtable yok; çekirdekte table, datetime, string ve compose da bulunmuyor.
MATLABOctave karşılığı
writematrixdlmwrite veya csvwrite, 'precision' ile
writetableBaşlık fprintf ile, sayılar dlmwrite ile
writecellio paketindeki cell2csv
round(x, n)Yok; round(x*1000)/1000 ya da precision biçimi
save('dosya.mat')save('-v7', 'dosya.mat'); varsayılan biçim Octave'ın metin biçimidir
Kod:
M = [0 21.4 1.013; 0.5 21.6 1.012];
fid = fopen('olcum_octave.csv', 'w');           % Octave varsayılan olarak UTF-8 yazar
fprintf(fid, 'zaman_s,sicaklik_C,basinc_bar\n');
dlmwrite(fid, M, 'delimiter', ',', 'precision', '%.4f');   % dosya kimliği kabul eder
fclose(fid);

pkg load io                                      % kurulum: çoğu sistemde pkg install -forge io
cell2csv('numune.csv', {'Numune', 'Yuk_kN'; 'A-01', 12.4}, ';');
Octave'da csvwrite ek seçenekleri dlmwrite'a iletir; csvwrite('a.csv', M, 'precision', '%.6f') Octave'da çalışır, MATLAB'da çalışmaz. MATLAB ile .mat paylaşacaksanız '-v7' kullanın; Octave belgelerine göre v7.3 biçiminde kaydetme henüz yok.

10. Sık karşılaşılan hatalar ve çözümleri​

  • Undefined function or variable 'writematrix' (ya da ... for input arguments of type 'double'): sürümünüz R2019a'dan eski. dlmwrite, fprintf ya da tablolar için writetable kullanın. Octave aynı durumu 'writematrix' undefined diye bildirir.
  • Invalid parameter name: WriteMode. R2019a ve R2019b'de bu seçenek yok, R2020a gerekir. Eski sürümde fprintf ya da dlmwrite '-append' ile ekleyin.
  • Nested cell arrays are not supported. writecell, içinde başka hücre bulunan bir hücre dizisini yazmaz. Bu durum çoğu zaman diziyi C{k} = D(j) gibi kurmaktan doğar: parantezle indeksleme hücre döndürür, doğrusu C{k} = D{j} olurdu. Sorunlu elemanları find(cellfun(@iscell, C)) ile bulun.
  • cell2mat: All contents of the input cell array must be of the same data type. Karışık tipli hücre matrise çevrilemez; writecell kullanın. csvwrite hücre dizisi kabul etmez, dlmwrite de sayısal veri içindir.
  • Permission denied, dosya yazılamıyor: Windows'ta Excel'de açık dosya kilitlidir; Excel'i kapatın ya da başka adla yazın. Klasör yoksa mkdir ile oluşturun, yolları fullfile ile kurun. Gerçek sebebi [fid, mesaj] = fopen(dosya, 'w') çağrısının mesajı söyler. Standart olmayan bir uzantıda (örneğin .log) 'FileType','text' verin; uzantısız bir ada writematrix kendisi .txt ekler.
  • Türkçe karakterler betiğin kendisinde bozuk görünüyor: sorun .m dosyasının kodlamasında olabilir. Güncel MATLAB sürümleri kod dosyalarında varsayılan olarak UTF-8 kullanır; yıllar önce Windows-1254 ile kaydedilmiş bir betik bu yüzden bozuk görünebilir. Betiği, kodlama seçmenize izin veren bir metin düzenleyicide UTF-8 olarak yeniden kaydedin.

Sık sorulan sorular​

Bütün çalışma alanını tek bir CSV'ye yazabilir miyim?
Yalnızca bütün değişkenlerin satır sayısı aynıysa (örneğin eşit uzunlukta sütun vektörleri): writetable(table(a, b, c), 'hepsi.csv'). Aksi hâlde her değişkeni ayrı bir CSV'ye yazın ve tamamını save ile .mat olarak saklayın.

writematrix mi, csvwrite mı? Kaç basamak yazılır?
R2019a ve sonrasında writematrix: "long g", yani double için en fazla 15 anlamlı basamak. csvwrite en fazla beş anlamlı basamak yazar ve ölçüm verisini sessizce yuvarlar.

Excel bütün veriyi tek sütunda gösteriyor, neden?
Excel Windows'taki liste ayırıcısını kullanır; Türkçe ayarlarda bu genellikle noktalı virgüldür. 'Delimiter',';' ile yazın ya da dosyayı Excel'in Veri sekmesindeki metin/CSV içe aktarma aracıyla açıp ayracı orada seçin.

Türkçe karakterler Excel'de bozuk çıkıyor, ne yapmalıyım?
UTF-8 yazıp başına BOM ekleyin (bomEkle) ya da içe aktarma aracında dosya kaynağı olarak 65001: Unicode (UTF-8) seçin.

Octave'da writetable var mı?
Octave 11 çekirdeğinde yok. Başlığı fprintf, sayıları dlmwrite ile yazın; hücre dizileri için io paketindeki cell2csv'yi kullanın.

Sonuç ve sonraki adımlar​

Sağlam bir CSV dışa aktarımı kısa bir rutine dayanır: fonksiyonu veri tipine göre, ayracı, ondalık işaretini ve kodlamayı dosyayı kimin açacağına göre seçin, hassasiyeti bilinçli ayarlayın ve dosyayı göndermeden önce geri okuyun. Kodunuz birden fazla sürümde çalışacaksa fonksiyonların varlığını isempty(which('writematrix')) gibi bir kontrolle sınayın ve eski sürüm yolunu (dlmwrite + 'precision' ya da fprintf) hazır tutun. Veriyle analize geçecekseniz büyük veriyle korelasyon analizi yazımız iyi bir devam noktası. Ölçüm verisini MATLAB'dan rapora elle taşımak haftalık bir angaryaya dönüştüyse AIOR'un otomatik raporlama hizmeti bu akışı otomatikleştirmenin bir yolu olabilir.

Exporting a MATLAB workspace variable to CSV is usually a one-liner. The trouble starts when the file is opened somewhere else: in Excel set to a decimal-comma locale (Turkish, German, French and many others) every row lands in column A, decimals turn into text or dates, non-ASCII characters come out garbled, or a colleague on an older release gets "Undefined function or variable 'writematrix'". This guide picks the function by data type and release, then fixes each of those problems in turn.

Quick answer​

On R2019a or newer, match the function to the data type:
Kod:
writematrix(M, 'data.csv');   % numeric matrix
writetable(T, 'data.csv');    % table: variable names become the header
writecell(C, 'data.csv');     % cell array: text and numbers may be mixed
On older releases, use dlmwrite for numeric data and always pass an explicit precision, for example dlmwrite('data.csv', M, 'precision', '%.6f'). Section 5 explains why. To export every workspace variable in one go, use the loop in Section 3.

1. Check your release first​

version prints your release. If which writematrix answers "'writematrix' not found.", the function does not exist in that release and your script will fail on that machine; inside code, isempty(which('writematrix')) performs the same test. The table below follows the version history in the MathWorks documentation.
ReleaseWhat arrived
Before R2006acsvwrite, dlmwrite, fopen/fprintf, save
R2013btable, writetable, readtable, struct2table, array2table
R2014bdatetime, round(x, n)
R2016b / R2017astring arrays and compose; double-quoted "text" literals arrived in R2017a
R2019awritematrix, writecell, writetimetable, readmatrix; csvwrite and dlmwrite become "not recommended"
R2019bTable variable names may contain spaces and non-ASCII characters
R2020aWriteMode in the write functions ('append' adds to an existing file)
R2020bVariableNamingRule in readtable

2. Decision table by data type​

In the workspaceR2019a and newerOlder releasesWatch out
Numeric matrix (double, integer, logical)writematrixdlmwrite + 'precision'No header row
tablewritetablewritetable (R2013b+)Variable names become the header
timetablewritetimetabletimetable2table + writetableRow times are written too
Cell array, mixed text and numberswritecellfprintf loopNested cells raise an error
structstruct2table + writetableSameFields need equal row counts
Data with datetime valuesPut it in a table, writetabledatestr + fprintfSet Format explicitly
Kod:
M = [0 21.4 1.013; 0.5 21.6 1.012; 1.0 21.9 1.011];
writematrix(M, 'matrix.csv');

T = array2table(M, 'VariableNames', {'time_s', 'temp_C', 'pressure_bar'});
writetable(T, 'table.csv');

C = {'Sample', 'Load_kN', 'Result'; 'A-01', 12.4, 'pass'; 'A-02', 11.9, 'fail'};
writecell(C, 'samples.csv');                 % first row is the header

S.time_s    = (0:0.5:1)';
S.current_A = [0.82; 0.85; 0.91];
writetable(struct2table(S), 'struct.csv');   % one column per field
A struct array becomes one row per element; a scalar struct whose fields differ in length makes struct2table fail.

3. Exporting the whole workspace​

A CSV file holds one two-dimensional table, so a workspace of differently sized matrices, tables and structs does not fit into a single CSV in any useful way. Write one CSV per variable and keep a .mat file as a lossless backup. Both methods below use this helper (exportVariableToCsv.m):
Kod:
function written = exportVariableToCsv(v, file)
% Writes one variable with the function that matches its type (R2019a+).
written = true;
if isempty(v)
    written = false;
elseif istable(v)
    writetable(v, file);
elseif istimetable(v)
    writetimetable(v, file);
elseif isstruct(v)
    writetable(struct2table(v), file);
elseif iscell(v)
    writecell(v, file);
elseif isnumeric(v) || islogical(v)
    writematrix(reshape(v, size(v, 1), []), file);  % flattens 3-D arrays to 2-D
else
    written = false;   % char, string, objects: skipped on purpose
end
end

Method A: loop over who with evalin​

who returns the variable names as a cell array. Because the code runs inside a function, it fetches each value from the base workspace with evalin, and the loop's own variables never end up in the export.
Kod:
function exportWorkspace(folder)
if ~exist(folder, 'dir'), mkdir(folder); end
names = evalin('base', 'who');
for k = 1:numel(names)
    file = fullfile(folder, [names{k} '.csv']);
    try
        if exportVariableToCsv(evalin('base', names{k}), file)
            fprintf('Written: %s\n', file);
        else
            fprintf('Skipped: %s\n', names{k});
        end
    catch err
        fprintf('Failed: %s (%s)\n', names{k}, err.message);
    end
end
end
Run it as exportWorkspace('csv_out'). The try/catch keeps one awkward variable from stopping the run, and the log shows what failed and why.

Method B: save to .mat, then convert​

Kod:
save('workspace.mat');                % every variable, types intact
S = load('workspace.mat');            % each variable becomes a field of S
names = fieldnames(S);
for k = 1:numel(names)
    exportVariableToCsv(S.(names{k}), [names{k} '.csv']);
end
The .mat file keeps types and full precision, so you can convert later or on another machine. whos('-file', 'workspace.mat') lists the contents without loading them; variables of 2 GB or more need '-v7.3'. To export a subset, filter whos output by class or select names with who('-regexp', '^run_').

4. Headers and variable names​

writematrix never writes a header row. Three ways around that:
  1. Convert to a table: name the columns with array2table and call writetable. From R2019b, names with spaces and non-ASCII characters such as "Temperature (°C)" are allowed; older releases require valid MATLAB identifiers (temp_C).
  2. Header first, then append (R2020a+): header with writecell, numbers with writematrix and 'WriteMode','append'.
  3. Older releases: header with fprintf, data with dlmwrite '-append'.
Kod:
% 1) Table (non-ASCII names need R2019b+)
T = array2table(M, 'VariableNames', {'Time (s)', 'Temperature (°C)', 'Pressure (bar)'});
writetable(T, 'run1.csv', 'Encoding', 'UTF-8');

% 2) Header + append (R2020a+)
writecell({'time_s', 'temp_C', 'pressure_bar'}, 'run2.csv');
writematrix(M, 'run2.csv', 'WriteMode', 'append');

% 3) Older releases
fid = fopen('run3.csv', 'w');
fprintf(fid, 'time_s,temp_C,pressure_bar\n');
fclose(fid);
dlmwrite('run3.csv', M, '-append', 'precision', '%.4f', 'newline', 'unix');
Put units in the header (temp_C) and add 'WriteRowNames', true for tables with row names. When appending a table in pieces with writetable, pass 'WriteVariableNames', false on the append calls: according to the documentation, 'append' is not supported while variable names are being written, and the header belongs only in the first call anyway. On R2020b or newer, readtable(..., 'VariableNamingRule', 'preserve') keeps the original header text when you read the file back (on R2019b, use 'PreserveVariableNames', true).

5. Precision and number formatting​

writematrix, writetable and writecell have no precision option. Per the MathWorks documentation they write numbers in "long g" format, up to 15 significant digits for doubles, so pi is written as 3.14159265358979. 0.1 + 0.2 (stored as 0.30000000000000004) therefore appears as 0.3 and does not read back bit-identical. For measurement data this does not matter; for tests that need an exact round trip, keep a .mat file or use fprintf with '%.17g'.

The legacy functions are worse: csvwrite writes at most five significant digits and dlmwrite defaults to five as well. 123456.789 lands in the file as 1.2346e+05, i.e. 123460, without an error or warning. MathWorks has no plans to remove either function, so old scripts keep running and the loss goes unnoticed.
Kod:
X = [pi 2.5; 1/3 123456.789];
writematrix(round(X, 3), 'rounded.csv');   % 3.142,2.5 and 0.333,123456.789

fid = fopen('fixed.csv', 'w');
fprintf(fid, 'a,b\n');
fprintf(fid, '%.3f,%.3f\n', X.');          % 3.142,2.500 and 0.333,123456.789
fclose(fid);
Even after round, writematrix drops trailing zeros (2.5, not 2.500); for a fixed number of decimals use fprintf or compose. fprintf consumes a matrix column by column, so it gets the transpose X.'. Forget it and the first line holds two values from the same column (3.142,0.333), one of the most common silent CSV bugs we run into.

6. Excel with a decimal comma: semicolons, UTF-8 and dates​

On Windows, Excel splits a double-clicked CSV on the list separator from the regional settings. In Turkish, German, French and many other locales that is a semicolon and the decimal mark is a comma, whereas MATLAB writes commas between fields and dots inside numbers. Three problems follow:
  • Delimiter: every row ends up in column A.
  • Decimals: dotted numbers may stay as text, and values such as 3.5 or 1.234 can become a date or the number 1234.
  • Encoding: many Excel versions read a UTF-8 file without a BOM (byte order mark) in the system's ANSI code page (Windows-1254 on Turkish Windows, Windows-1252 on Western European systems), which garbles non-ASCII characters such as ş, ğ, ı or é. Behaviour varies with the Excel version and Windows settings, so do not count on BOM-less UTF-8 being detected.
Who opens the fileDelimiterDecimalEncoding
Decimal-comma Excel, by double-click;, (converted to text)UTF-8 with BOM, or the local code page
Python, R, a database, other software,.UTF-8 without BOM
Excel through its import tool,.UTF-8 (pick 65001 when importing)
Nobody wants to deal with locales--Write .xlsx
If you use the import tool in decimal-comma Excel, also tell it that the decimal mark is a dot: in the legacy Text Import Wizard set the decimal separator under Advanced, and in Power Query change the column type with Change Type > Using Locale and pick English (United States).

writematrix(M, 'file.csv', 'Delimiter', ';') changes only the delimiter (allowed: comma, space, tab, semicolon, bar); the decimal problem remains. Here is a file that opens correctly by double-click in Turkish Excel:
Kod:
t = datetime(2026, 3, 14, 8, 30, 0) + minutes(0:2)';
T = table(t, [21.45; 21.60; 21.72], {'Boiler-1'; 'Boiler-1'; 'Şişirme-2'}, ...
          'VariableNames', {'Date', 'Temp_C', 'Line'});
T.Date.Format = 'dd.MM.yyyy HH:mm:ss';     % MM = month, mm = minutes

Ttr = T;
Ttr.Temp_C = replace(compose("%.2f", T.Temp_C), ".", ",");   % 21,45
writetable(Ttr, 'report_tr.csv', 'Delimiter', ';', 'Encoding', 'UTF-8');
addBom('report_tr.csv');

% Same idea for a plain numeric matrix:
writematrix(replace(compose("%.4f", M), ".", ","), 'matrix_tr.csv', 'Delimiter', ';');
Expected content:
Kod:
Date;Temp_C;Line
14.03.2026 08:30:00;21,45;Boiler-1
14.03.2026 08:31:00;21,60;Boiler-1
14.03.2026 08:32:00;21,72;Şişirme-2
Convert numeric columns only; a global dot-to-comma replace would also break the dates. The MATLAB documentation lists no BOM option for the write functions, so add one yourself (addBom.m):
Kod:
function addBom(file)
% Prepends the UTF-8 BOM (EF BB BF) unless the file already starts with it.
fid = fopen(file, 'r');
if fid < 0, error('Cannot read %s', file); end
bytes = fread(fid, Inf, '*uint8');
fclose(fid);
bom = uint8([239; 187; 191]);
if numel(bytes) >= 3 && isequal(bytes(1:3), bom), return; end
fid = fopen(file, 'w');
if fid < 0, error('Cannot write %s', file); end
fwrite(fid, [bom; bytes], 'uint8');
fclose(fid);
end
In some tools the BOM survives as an invisible character in front of the first column name: read such files in Python with encoding='utf-8-sig', and leave the BOM out of files that feed a data pipeline. Writing in the local code page ('Encoding','windows-1254' for Turkish) works only while every reader's Windows uses that system locale; on a machine with a different locale the characters break again. The current documentation says fopen, writematrix, writetable and writecell write UTF-8 when no encoding is given; older releases may use the system encoding instead, so state the encoding explicitly in code that has to run on several releases.
  • Dates: always set Format explicitly. dd.MM.yyyy HH:mm:ss suits Turkish Excel; an ISO 8601-style yyyy-MM-dd HH:mm:ss is the safest choice between systems. Add 'DateLocale' (for example 'tr_TR') when you print month names. In datetime formats MM is the month and mm the minute; the old datestr uses the opposite convention.
  • Line endings: the writematrix, writetable and writecell pages document no line-ending option. If you need a specific one, use dlmwrite 'newline' ('pc' = CRLF, 'unix' = LF) or fopen/fprintf.
  • The sep=; trick: only Excel understands that first line; other tools read it as data. We do not recommend it.
  • Least effort: writetable(T, 'report.xlsx'). Numbers stay numbers and datetime columns become Excel dates. When overwriting an existing .xlsx, the default 'inplace' mode can leave old rows behind; on R2020a or newer use 'WriteMode','overwritesheet'.
The BI side of the same separator and decimal problems is covered in setting separators, dates and decimal symbols in Tableau.

7. Large data: append mode and chunked writes​

  • Data arriving in blocks (R2020a+): call writematrix(block, file, 'WriteMode', 'append') per block. If the run dies halfway, everything written so far stays on disk; delete the old file at the start so a rerun does not append to yesterday's output.
  • Usually faster: open the file once with fopen and write each block with fprintf instead of reopening the file for every block. Writing in blocks also keeps the transposed copy that fprintf needs small.
  • Source is a large .mat file: read only the rows you need with matfile (m.X(i:j, :)). Per MathWorks, efficient partial loading requires a -v7.3 MAT-file.
Kod:
function writeCsvChunked(M, file, header, fmt, blockRows)
% Example: writeCsvChunked(M, 'big.csv', 'time_s,ch1,ch2', '%.6f,%.4f,%.4f\n', 1e5)
[fid, msg] = fopen(file, 'w', 'n', 'UTF-8');
if fid < 0, error('Cannot open %s (%s)', file, msg); end
closer = onCleanup(@() fclose(fid));   % closes the file even on error
fprintf(fid, '%s\n', header);
for i = 1:blockRows:size(M, 1)
    j = min(i + blockRows - 1, size(M, 1));
    fprintf(fid, fmt, M(i:j, :).');
end
end
Once files reach gigabytes, ask whether CSV is the right format at all: text is usually larger than binary and slower to parse. If the data is going back into MATLAB or Python, a -v7.3 .mat file or parquetwrite (R2019a+, for tables and timetables) is often the better fit.

8. Verify the file by reading it back​

A write call that did not error proves nothing about the content. A one-minute check saves hours spent on a wrong analysis:
Kod:
A = readmatrix('run2.csv');                       % detects and skips the header
assert(isequal(size(A), size(M)), 'Row/column count differs');
fprintf('Largest difference: %g\n', max(abs(A(:) - M(:))));

T2 = readtable('report_tr.csv', 'Delimiter', ';', 'DecimalSeparator', ',', ...
               'Encoding', 'UTF-8', 'VariableNamingRule', 'preserve');
disp(T2)

fid = fopen('report_tr.csv', 'r'); first3 = fread(fid, 3, '*uint8')'; fclose(fid);
disp(first3)                                      % 239 187 191 means a BOM is present
If the date column comes back as text, convert it with T2.(1) = datetime(T2.(1), 'InputFormat', 'dd.MM.yyyy HH:mm:ss'); addressing the column by position still works if a BOM ends up in front of the first header. On R2019b use 'PreserveVariableNames', true instead of VariableNamingRule, and if an even older readtable rejects one of these options, set them on a detectImportOptions object instead. Checklist: row and column counts, header text, decimal separator, minimum and maximum, NaN count, and how non-ASCII text looks in Excel.

Depending on the function and the file type, missing values end up either as the text NaN or as empty fields: dlmwrite and fprintf write NaN, while in an Excel file (.xlsx) MATLAB leaves the cell empty. Excel treats the text NaN as text, not as a number. Agree early whether the receiver expects empty fields or NaN. If it needs empty fields, turn the column into text and blank out the NaN entries before writing:
Kod:
s = compose("%.3f", T.Temp_C);   % NaN becomes the text "NaN"
s(isnan(T.Temp_C)) = "";         % ...and then an empty field
T.Temp_C = s;

Can't find the file? pwd prints the current folder, and the file also appears in the Current Folder panel (called the Files panel in recent releases), where right-click > Open Outside MATLAB opens it in the application the operating system associates with CSV, usually Excel. On Windows winopen(cd) opens the folder in File Explorer; on macOS use system('open .'), on Linux system('xdg-open .').

9. GNU Octave equivalents​

The function index of the Octave 11 manual (docs.octave.org) has no writematrix, writecell, writetable, readmatrix or readtable, and core Octave lacks table, datetime, string and compose as well.
MATLABOctave
writematrixdlmwrite or csvwrite, with 'precision'
writetableHeader via fprintf, numbers via dlmwrite
writecellcell2csv from the io package
round(x, n)Not available; round(x*1000)/1000 or a precision format
save('file.mat')save('-v7', 'file.mat'); the default is Octave's own text format
Kod:
M = [0 21.4 1.013; 0.5 21.6 1.012];
fid = fopen('run_octave.csv', 'w');               % Octave writes UTF-8 by default
fprintf(fid, 'time_s,temp_C,pressure_bar\n');
dlmwrite(fid, M, 'delimiter', ',', 'precision', '%.4f');   % accepts a file id
fclose(fid);

pkg load io                                        % install first, usually pkg install -forge io
cell2csv('samples.csv', {'Sample', 'Load_kN'; 'A-01', 12.4}, ';');
In Octave, csvwrite forwards extra options to dlmwrite, so csvwrite('a.csv', M, 'precision', '%.6f') works there but not in MATLAB. To share .mat files with MATLAB, save with '-v7'; the Octave manual says writing the v7.3 format is not implemented yet.

10. Common errors and fixes​

  • Undefined function or variable 'writematrix' (or ... for input arguments of type 'double'): your release predates R2019a. Use dlmwrite, fprintf, or writetable for tables. Octave reports the same situation as 'writematrix' undefined.
  • Invalid parameter name: WriteMode. Not available in R2019a or R2019b; it needs R2020a. Append with fprintf or dlmwrite '-append' instead.
  • Nested cell arrays are not supported. writecell refuses a cell array that contains other cells. This usually comes from building it with C{k} = D(j): parentheses return a cell, whereas C{k} = D{j} stores the content. Find the offenders with find(cellfun(@iscell, C)).
  • cell2mat: All contents of the input cell array must be of the same data type. A mixed cell cannot become a matrix; use writecell. csvwrite rejects cell arrays and dlmwrite is meant for numeric data.
  • Permission denied, or the file cannot be written: on Windows, Excel locks a file it has open, so close it or write under a new name. Create missing folders with mkdir and build paths with fullfile. [fid, msg] = fopen(file, 'w') tells you the real reason. For a non-standard extension such as .log, pass 'FileType','text'; a name without any extension gets .txt appended by writematrix.
  • Non-ASCII text already broken in the script: the .m file's encoding may be the culprit. Current MATLAB releases use UTF-8 for code files by default, so a script saved years ago in a legacy code page such as Windows-1254 can show broken characters. Re-save it as UTF-8 in a text editor that lets you choose the encoding.

FAQ​

Can I write the whole workspace into one CSV file?
Only if all variables have the same number of rows (for example, column vectors of equal length): writetable(table(a, b, c), 'all.csv'). Otherwise write one CSV per variable and keep everything in a .mat file with save.

writematrix or csvwrite, and how many digits do I get?
writematrix on R2019a and newer; it writes "long g", up to 15 significant digits for doubles. csvwrite stops at five significant digits and silently rounds measurement data.

Why does Excel show everything in one column?
It splits on the Windows list separator, which is a semicolon in many European locales. Write with 'Delimiter',';' or open the file through Excel's Data > From Text/CSV import and choose the delimiter there.

Non-ASCII characters are garbled in Excel. What now?
Write UTF-8 and add a BOM (addBom above), or pick 65001: Unicode (UTF-8) as the file origin in the import dialog.

Does Octave have writetable?
Not in core Octave 11. Write the header with fprintf and the numbers with dlmwrite, and use cell2csv from the io package for cell arrays.

Conclusion and next steps​

A dependable CSV export is a short routine: choose the function by data type, choose delimiter, decimal mark and encoding by who will open the file, set precision on purpose, and read the file back before sending it. If your code must run on several releases, test for functions with a check such as isempty(which('writematrix')) and keep the legacy path (dlmwrite with 'precision', or fprintf) ready. If the data is headed for analysis, our step-by-step correlation analysis with big data is a good next read. And if copying measurement data from MATLAB into reports by hand has become a weekly chore, AIOR's automated report generation service is one way to automate that flow.
 

Ekler

  • 1703513017647.webp
    1703513017647.webp
    75,3 KB · Görüntülenme: 3
  • 1703513277933.webp
    1703513277933.webp
    82,6 KB · Görüntülenme: 2
Son düzenleyen:

Forum istatistikleri

Konular
925
Mesajlar
932
Üyeler
26
En son üye
Jessicawatson

Çevrimiçi üyeler

Şu anda çevrimiçi üye yok.

Öne çıkan içerik

AIOR
AIOR TEKNOLOJİ

Tüm ihtiyaçlarınız için Teklif alın

Hosting · Domain · Sunucu · Tasarım · Yazılım · Mühendislik · Sektörel Çözümler

Teklif al

7/24 Destek · Anında yanıt

Geri
Üst