grBIN |
Отправлено: 05 Марта, 2018 - 21:59:22
|
Наблюдатель
Покинул форум
Сообщений всего: 41
Дата рег-ции: Нояб. 2017
Откуда: Псков
Репутация: 2
|
В общем пол дня сегодня мучился с этой функцией, в итоге все закомментировал, но где ошибка точно не могу понять, может вы подскажите.
Я подозреваю что такой скрипт сильно кривой для этой задачи, но как его написать по другому не додумался.
Итак Т3, у нас есть файл таблиц в csv формате, нужно его вывести в массив two[][],
для дальнейшей работы с ним.
Сам скрипт выкладываю здесь и архивом вместе с самим файлом.(для просмотра ссылки Вам необходимо авторизоваться) P.S. В киборе скрипт видно лучше чем на форуме T_T
P.S.S. И еще 2 вопроса.
1.Как мне обнулить массив полностью? Или дать всем ячейкам в массиве значение x?
2.Как выбросить из памяти ненужный массив?
CODE:external(INT, "MoveFile", "MoveFileA", "kernel32.dll");
MoveFile("C:\data.csv", "C:\data.txt");//База в csv формате, поэтому просто меняем на txt
string path="C:\data.txt"; // Вписываем путь к файлу
string one[52]; //Первый массив, должен быть n+1 кол-ва строк.
int i=0;//счетчик для первого цикла
if(fopen(path, "r")!=0) // Если открыл
{
while (freadline(one[i])!=0) // Читает строку, и закидывает в массив one[]
{
i++;//увеличиваем счетчик
}
fclose(); // закрывает файл
}
//Для проверки работы раскомментировать.
//messagebox(one[0]);
//messagebox(one[1]);
//messagebox(one[50]);
//messagebox(one[51]);
/*
По итогу получаем массив one[], заполненный строками вида
"Name","Rarity","Faction","Category","Type","Popularity","Sell Price","Sell Offers","Buy Price","Buy Orders","Margin","Last Update"
Всего 51 строка и последняя ячейка пустая
Дальше нам нужно, создать массив two[][], и закинуть в него содержимое этих строк, в итоге должен получиться массив вида:
"Name" "Rarity" "Faction" "Category"
"AC43 Rapier" "Rare" "Engineers" "Weapons"
"Synthesis" "Rare" "Dawn's Children" "Weapons"
"AT Wasp" "Rare" "Lunatics" "Weapons"
есть разделитель ","
*/
char a[500]; /* Обьявляем массив char а[], для того что бы, затем посимвольно записать в него строку из массива one[]
Так как мы не знаем сколько будет символов в строке, зарезервируем 500 ячеек*/
char b[30]; /*Вспомогательный массив char, в него будем записывать все что было до разделителя, а потом из него
закидывать строку в 2 массив в нужную ячейку.
Так же берем с запасом так как мы не знаем сколько будет символов с слове */
int n=0; //Счетчик строки и кол-ва итераций пройденых основным циклом.
int j=0; //Счетчик столбца для 2 массива two[][]
int k=0; //Счетчик символа в строке
string two[53][13];//2 окончательный массив, по идее должен иметь 52, строки и 12 столбцов, но на всякий случай добавим +1
//Первый цикл, каждую строку из массива one[], перебирает посимвольно и закидывает во временный массив a[]
while (#one[n]!="") //пока массив one[] не закончился
{
strcpy(#a[0], one[0]);//закидвыаем строку в массив a[]
//в конце цикла после всех операций, должен увеличить счетчик строки, и обнулить счетчик столбца
/*
Теперь в char массиве a[], у нас та же строка вида
"Name","Rarity","Faction","Category","Type","Popularity","Sell Price","Sell Offers","Buy Price","Buy Orders","Margin","Last Update"
Но теперь в каждой ячейке массива, отдельный символ, и теперь эту строку мы можем разделить.
*/
/*
2 цикл, должен посимвольно перебирать char массив a[], и копировать каждый сивмвол во вспомогательный char массив b[],
Как только наткнеться на разделитель должен брать char масиив b[] и перекидывать получившуюся строку
в наш массив two[n][j], где n это номер строки, а j номер столбца.
*/
while (#a[k]!="") //пока char массив a[] не закончился
{
if a[k]!="," // Если в ячейке НЕ разделитель
{
b[k]=a[k]; // То мы копируем этот символ во второй char массив b[]
k++; // И идем к следующему символу
}
else // Иначе, если мы наткнулись на разделитель
{
two[n][j]=format(#b[0]); //Записываем в наш окончательный массив two[][], строку из char массива b[]
k++; /*Увеличиваем счетчик символа, потому что сам разделитель нам не нужен,
и переходим к следующему символу в массиве a[] */
j++; //увеличиваем счетчик, столбца в массиве two[][]
/*По идее в этом участке кода, нужно так же обнулить все значения char массива b[],
Потому что иначе, если предыдущая позиция была больше чем новая, вылезет такой баг:
Например: "Category" запишеться нормально, а вместо "Type", мы получим - "Type"ory"
*/
} //Закрываем условие if
} //Закрываем 2 цикл
n++; //увеличиваем счетчик строки
j=0; //обнуляем счетчик столбаца после 1 цикла
} //конец 1 цикла
/*
Теперь по идее должны получить массив two[][], вида:
"Name" "Rarity" "Faction" "Category"
"AC43 Rapier" "Rare" "Engineers" "Weapons"
"Synthesis" "Rare" "Dawn's Children" "Weapons"
"AT Wasp" "Rare" "Lunatics" "Weapons"
*/
messagebox(two[1][1]); // должен вывести строку "Rare"
messagebox(two[2][2]); // "Dawn's Children"
/// Но не выводит :D, где ошибся нифига не понимаю
|
|
|
Zireael |
Отправлено: 06 Марта, 2018 - 01:37:45
|
Эксперт
Покинул форум
Сообщений всего: 4456
Дата рег-ции: Нояб. 2017
Репутация: 585
|
Ваш код особо не смотрел. В таких случаях мне быстрее свой написать.
код (Отобразить)CODE:external(INT, "MoveFile", "MoveFileA", "kernel32.dll");
MoveFile("C:\data.csv", "C:\data.txt");//База в csv формате, поэтому просто меняем на txt
sleep(500);
string path="C:\data.txt"; // Вписываем путь к файлу
string one[52];
int i=0;//счетчик для первого цикла
if(fopen(path, "r")!=0) // Если открыл
{
while (freadline(one[i])!=0) // Читает строку, и закидывает в массив one[]
{
i++;//увеличиваем счетчик
}
fclose(); // закрывает файл
}
//Для проверки работы раскомментировать.
//messagebox(one[0]);
//messagebox(one[1]);
//messagebox(one[50]);
//messagebox(one[51]);
string two[53][13];
char a[500];
char b[50];;
int j, k, l, m;
for(j=0;j<51;j++) // цикл для 51 строки
{
strcpy(#a[0], one[j]); // копируем строку в массив char
l=0; // текущая позиция для сравнения символа
for(k=0;k<12;k++) // цикл для 12 столбцов
{
m=0; // переменная для массива b
while(l<size(one[j]) && formatic(44) != a[l]) // пока не конец строки и не запятая
{
b[m]=a[l];
l++; m++;
}
two[j][k]=format(#b[0], m); // пишем в массив текст из массива b
l++;
}
}
messagebox(two[1][1]); // должен вывести строку "Rare"
messagebox(two[2][2]); // "Dawn's Children"
messagebox(two[50][11]); // "2018-03-05 00:17:18"
Цитата: Как мне обнулить массив полностью? Или дать всем ячейкам в массиве значение x?
Записать значение циклом или циклами, если массив многомерный.
P.S. Появятся ли в кибор когда-нибудь регулярки... |
|
|
grBIN |
Отправлено: 06 Марта, 2018 - 03:04:06
|
Наблюдатель
Покинул форум
Сообщений всего: 41
Дата рег-ции: Нояб. 2017
Откуда: Псков
Репутация: 2
|
Zireael пишет: Ваш код особо не смотрел. В таких случаях мне быстрее свой написать.
код (Отобразить)CODE:external(INT, "MoveFile", "MoveFileA", "kernel32.dll");
MoveFile("C:\data.csv", "C:\data.txt");//База в csv формате, поэтому просто меняем на txt
sleep(500);
string path="C:\data.txt"; // Вписываем путь к файлу
string one[52];
int i=0;//счетчик для первого цикла
if(fopen(path, "r")!=0) // Если открыл
{
while (freadline(one[i])!=0) // Читает строку, и закидывает в массив one[]
{
i++;//увеличиваем счетчик
}
fclose(); // закрывает файл
}
//Для проверки работы раскомментировать.
//messagebox(one[0]);
//messagebox(one[1]);
//messagebox(one[50]);
//messagebox(one[51]);
string two[53][13];
char a[500];
char b[50];;
int j, k, l, m;
for(j=0;j<51;j++) // цикл для 51 строки
{
strcpy(#a[0], one[j]); // копируем строку в массив char
l=0; // текущая позиция для сравнения символа
for(k=0;k<12;k++) // цикл для 12 столбцов
{
m=0; // переменная для массива b
while(l<size(one[j]) && formatic(44) != a[l]) // пока не конец строки и не запятая
{
b[m]=a[l];
l++; m++;
}
two[j][k]=format(#b[0], m); // пишем в массив текст из массива b
l++;
}
}
messagebox(two[1][1]); // должен вывести строку "Rare"
messagebox(two[2][2]); // "Dawn's Children"
messagebox(two[50][11]); // "2018-03-05 00:17:18"
Цитата: Как мне обнулить массив полностью? Или дать всем ячейкам в массиве значение x?
Записать значение циклом или циклами, если массив многомерный.
P.S. Появятся ли в кибор когда-нибудь регулярки...
Спасибо, ваш код работает отлично. Пока смотрел исправил свой местами, там где понял что работает не верно. Но основной проблемы это не решило.
Ну главное что думал вроде бы в правильном направлении и код работает примерно как у вас (только не работает :S)
Завтра попробую еще раз, скорее всего проблема с char массивами.
P.S. Можно с вами как то связаться, что бы периодически консультироваться по мелким вопросам? По типу почему вот так работает, а так не хочет
Все же хочется понимать как оно работает, а не тупо получать готовый код. |
|
|
Zireael |
Отправлено: 06 Марта, 2018 - 10:25:14
|
Эксперт
Покинул форум
Сообщений всего: 4456
Дата рег-ции: Нояб. 2017
Репутация: 585
|
Из явных проблем это:
Цитата: while (#one[n]!="") //пока массив one[] не закончился
while (#a[k]!="") //пока char массив a[] не закончился
CODE:while (one[n]!="") //убрать #
while (a[k]!="") //убрать #
Цитата: if a[k]!="," // Если в ячейке НЕ разделитель
Нет скобок, сравнивать лучше с formatic(44), причём, есть баг
CODE:if (formatic(44) != a[k]) // так будет работать
if (a[k] != formatic(44)) // а так нет
Цитата: /*По идее в этом участке кода, нужно так же обнулить все значения char массива b[],
Потому что иначе, если предыдущая позиция была больше чем новая, вылезет такой баг:
Например: "Category" запишеться нормально, а вместо "Type", мы получим - "Type"ory"
Для этого в format(#b[0]) надо указывать количество символов для копирования, т. е. даже если в массиве остались символы от предыдущего слова, то они не будут скопированы.
Переменная k не обнуляется на входе во второй цикл, а это значит что на второй строке она будет равна длине первой строки.
Выводите переменные в messagebox тогда будет понятно на каком этапе скрипт не работает.
Цитата: Можно с вами как то связаться, что бы периодически консультироваться по мелким вопросам?
Такие же вопросы как у вас могут возникнуть ещё у кого-то, поэтому ответ на форуме, а не лично, может помочь кому-то. Да и ответ можно получить быстрее, т. к. может ещё кто-то ответить. |
|
|
|