Я пытаюсь написать код, который будет анализировать текстовый файл с разделителями табуляции, назначив каждую строку между вкладками заданному элементу структуры образца, которую я определил. Во входном файле первая строка будет иметь все идентификаторы классов (c_name), вторая строка будет иметь все идентификаторы образца (s_name), а остальные строки будут содержать данные.Анализ текстового файла с разделителями с табуляцией
Я знаю, что это будет немного сложнее, потому что первый столбец на самом деле просто содержит ярлыки, но я решил, что начну с попытки выяснить общую схему синтаксического анализа.
Я могу собрать, что, например, для идентификаторов классов, вероятно, я должен использовать fscanf в цикле for, чтобы добавить каждый идентификатор в поле класса данного образца, но я теряюсь в фактической реализации. Основываясь на одном сообщении, которое я видел, я думал, что могу что-то сделать в соответствии с использованием %[^\t]\t
в fscanf, чтобы читать в массив все, что не является вкладкой до вкладки, но я не думаю, что у меня это совершенно правильно.
Любые предложения были бы весьма полезными.
#define LENGTH 30
#define MAX_OBS 80000
typedef struct
{
char c_name[LENGTH];
char s_name[LENGTH];
double value[MAX_OBS];
}
sample;
// I've already calculated the number of columns in the file
sample sample[total_columns];
for (int i = 0; i < total_columns; i++)
{
fscanf(input, "%[^\t]\t", sample[i].s_name);
}
Edit: Я пробовал несколько различных вариантов кода ниже ("% [^ \ т \ п \ г] \ т \ п \ г" или «% [^ \ т \ п \ r]% * 1 [\ t \ n \ r] "или"% [^ \ t \ n \ r] "), и все они, как правило, работают, за исключением того, что в зависимости от размера, который я выделяю для данных и как долго я повторяюсь, в какой-то момент он дает ошибку сегментации. В приведенном ниже коде немедленно возникает ошибка сегментации, но если я произвольно изменю total_columns в обоих местах на 3, он напечатает Case Case Case. Кажется, что это работает до 14, после чего вся сегрегация программная. Я довольно запутался в этом вопросе. Я также попробовал mallocing memory для массива выборочных данных, чтобы убедиться, что это проблема стека и кучи, но это, похоже, не помогает. Большое спасибо за Вашу помощь!
sample data[total_columns];
fseek(input, 0, SEEK_SET);
for (int i = 0; i < total_columns; i++)
{
fscanf(input, "%[^\t\n\r]\t\n\r", data[i].s_name);
printf("%s\n", data[i].s_name);
}
Пример входного файла будет выглядеть следующим образом:
Class Case Case Case Case Case Case Case Case Case Case Case Case Case Case Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control
Subject G038 G144 G135 G161 G116 G165 G133 G069 G002 G059 G039 G026 G125 G149 G108 G121 G060 G140 G127 G113 G023 G147 G011 G019 G148 G132 G010 G142 G020 G021
Data1 0.000741628 0.00308607 0.000267431 0.001418697 0.0.000761145 0.0008281 0.002426075 0.000236698 0.004924871 0.000722752 0.003758006 0.000104813 0.000986619 0.000121803 0.000666854 0 0.000171394 0.000877993 0.002717391 0.001336501 0.000812089 0.001448743 5.28E-05 0.001944298 0.000292529 0.000469631 0.001674047 0.000651526 0.000336615
Data2 0.102002396 0.108035127 0.015052531 0.079923731 0.020643362 0.086480609 0.017907667 0.016279315 0.076263965 0.034876124 0.187481931 0.090615572 0.037460171 0.143326961 0.029628502 0.049487575 0.020175439 0.122975405 0.019754837 0.006702899 0.014033264 0.040024363 0.076610375 0.069287599 0.098896479 0.011813681 0.293331246 0.037558052 0.303052867 0.137591517
Data2 0.218495065 0.242891829 0.23747851 0.101306336 0.309040188 0.237477347 0.293837554 0.34351816 0.217572429 0.168651691 0.179387106 0.166516699 0.099970652 0.181003474 0.076126675 0.10244981 0.449561404 0.139257863 0.127579104 0.355797101 0.354544105 0.262855651 0.10167146 0.186068602 0.316763006 0.187466247 0.05701315 0.123825467 0.064780343 0.069847682
Data4 0.141137543 0.090948286 0.102502388 0.013063365 0.162060849 0.166292135 0.070215996 0.063535037 0.333743609 0.131011609 0.140936687 0.150108506 0.07812762 0.230704405 0.069792935 0.120770743 0.164473684 0.448110378 0.42599534 0.074094203 0.096525097 0.157661185 0.036737518 0.213931398 0.091119285 0.438073807 0.224921728 0.187034237 0.06611442 0.086005218
Data5 0.003594044 0.003948354 0.008137536 0.001327901 0.002161974 0.003552012 0.002760334 0.001898667 0.001420186 0.003165988 0.001011853 0.001217382 0.000314439 0.004254794 0.000213155 0.003650147 0 0.002742309 0.002633978 0 0.002524503 0.002146234 0.001751465 0.006543536 0.003941146 0.00049505 0.00435191 0.001944054 0.001303053 0.004207692
Data6 0.000285242 2.27E-05 0 1.13E-05 0.0002964 3.62E-05 0.000138017 0.000210963 0.000662753 0 0 0 0 4.11E-05 0 0 0 0 0.000101307 0 0 0 0 5.28E-05 0.00152391 0 0 0 0 0
Data7 0.002624223 0.001134584 0.00095511 0.000419934 0.000401011 0.001739761 0.00272583 0.002566717 0.000520735 0.002311674 0.006287944 0 6.29E-05 0.000143882 3.05E-05 0.000491366 0 0 3.38E-05 0 0.001782002 0.000957104 0.002594763 0.000527704 0.000105097 0.001192619 3.13E-05 0 0.000744602 0.000252461
Data8 0.392777683 0.383875286 0.451499522 0.684663315 0.387394299 0.357992026 0.488406597 0.423473155 0.27267563 0.47454646 0.331020526 0.484041709 0.735955056 0.338841956 0.781699147 0.625403622 0.313596491 0.270545891 0.379259109 0.498913043 0.372438372 0.446271644 0.606698813 0.305593668 0.360535996 0.29889739 0.328710081 0.521222594 0.419924299 0.584111756
Edit: Я, кажется, установил ее, изменив определение MAX_OBS - довольно уверен, что у меня есть фундаментальное непонимание того, что это на самом деле означает. Я должен буду изучить это. Спасибо еще раз за помощь!
ли компилировать? Использование 'sample' как имени типа, так и имени переменной приведет к путанице, даже если компилятор ее примет. –
Является ли последнее поле в строке, разделенной вкладкой или новой линией? Если это новая строка, вам нужно принять это во внимание, не так ли? Вы можете рассматривать ''% [^ \ t \ n "]% * 1 [\ t \ n]" ', который ищет не-табуляции, не-новые строки, за которыми следует вкладка или новая строка (' * 'подавляет назначение) Вы должны проверить возвращаемое значение из 'fscanf()' и прекратить обработку, если результат не равен 1. Как и вы, вы не получаете никакой информации о символе разделителя, вы также можете назначить разделитель для дополнительной проверки. –
ваши данные имеют три строки.Они разделены новой строкой, а не вкладкой, правильно? – BLUEPIXY