fentg.com

ФОРУМЪТ на ФЕНОВЕТЕ на НТГ
Дата и час: Нед Апр 11, 2021 6:09 am

Часовете са според зоната UTC + 2 часа [ DST ]


Правила на форума


Натиснете за да видите правилата



Напиши нова тема Отговори на тема  [ 16 мнения ]  Отиди на страница 1, 2  Следваща
Автор Съобщение
 Заглавие: C - четене на числа от текстов файл
МнениеПубликувано на: Съб Яну 18, 2014 10:27 pm 
Offline
Администратор
Аватар

Регистриран на: Нед Ное 02, 2008 5:30 pm
Мнения: 3550
Преди да решим задачата за "спиралата" решихме да взимаме данните за работа с масиви от текстов файл, писан примерно с Notepad...

Решихме още и да си "усложним живота", като данните в текстовия файл не са строго разделени.

Идеята на задачата е да прочете и да "вкара" в целочислен масив само тези части от текста, които "приличат" на цели числа... Приличат, т.е. такива са... В целочисления масив не трябва да влизат никакви други данни. Редът на вкарване е по реда на срещане от началото към края на текстовия файл...

И понеже създателите на файла с данни били небрежни, ползвали съвсем произволно различни разделители за данните:
интервали, табулатори, нови редове, запетаи, точки-запетаи, като тук-там се повтаряли и по няколко от вид...

Ето как изглеждат примерно нещата:
Прикачени файлове:
txt.png
Прикачени файлове:
cons.png


Минахме варианти със fscanf, който работи само с разделители - интервали.

При строги разделители - например само запетаи това също би следвало да работи...

Въпросът е в сложната мешеница разделители...

Нека не се ползват сложни указателни решения... Търсим простота и елегантност.

Задачата за "спиралата" има такова решение, докато тази ми се струва по-малко алгоритмична и без да познавам особено функциите в C, пробвах с някои и се получи нещо, което работи, но не много сигурно. На мен не ми дава грешки, но обикновено този, който пише програмата, като я тества я пази от грешки...


Вие нямате нужните права за да сваляте прикачени файлове.

_________________
Изображение


Върнете се в началото
 Профил  
 
 Заглавие: Re: C - четене на числа от текстов файл
МнениеПубликувано на: Нед Яну 19, 2014 12:21 am 
Offline

Регистриран на: Чет Авг 06, 2009 3:11 am
Мнения: 21
Така само да питам за да знам, че условието е така както го разбирам прочитам файла и вадя само цислата от него така ли, а и ограничение някакво има ли, от гредна точка на материята с която трябва да се прави ...


Върнете се в началото
 Профил  
 
 Заглавие: Re: C - четене на числа от текстов файл
МнениеПубликувано на: Нед Яну 19, 2014 12:27 am 
Offline
Администратор
Аватар

Регистриран на: Нед Ное 02, 2008 5:30 pm
Мнения: 3550
Материята е чисто C и негови библиотечни /стандартни библиотеки/ и/или собственоръчно написани функции...

/ Не C++ ;-) /

Боря се да оптимизирам решението си - това е много по-късо и сигурно от предишно /2009/, но ми се иска още по-...

_________________
Изображение


Върнете се в началото
 Профил  
 
 Заглавие: Re: C - четене на числа от текстов файл
МнениеПубликувано на: Нед Яну 19, 2014 2:00 am 
Offline

Регистриран на: Чет Авг 06, 2009 3:11 am
Мнения: 21
За улеснение, има ли функция която която слага съдържанието в масив или да си пиша такава, че имам алгоритмично решение на листче.
Нека обесня в какво се съдържа то, понеже табличата на кодиране е ASCII числата се намират от 48 до 57, предложението е следно пълнат се всички символи в този масив съотно от тип char. Завърта се масива и се проверя предния елемент от къв тип е цисло или не, ако е цисло и това е цисло се пише на същия ред, ако е цисло а този елемент не е приминава на нов ред, и последния вариянт предишния елемент да не е цисло и този да не е число и да не се прави нищо.

P.S това е за положителни цели числа, трябват леки козметични забележки на алгоритама, за другите.


Върнете се в началото
 Профил  
 
 Заглавие: Re: C - четене на числа от текстов файл
МнениеПубликувано на: Нед Яну 19, 2014 2:31 am 
Offline

Регистриран на: Чет Авг 06, 2009 3:11 am
Мнения: 21
Май не съм допроцел от условието на БАТКО.. Но алгорита които предложих може и да се представи и с това условие на задачата...
Разликата е ,че просто ще проверява всяко следващ елемент до като несрещне цисло съответно интервала които казах, и алгоритама пак ще работи, разликата е че аз бих използвал двумерен масив... Утре като съм на работа ще предложа и код на алгоритама...
БАТКО ако имаш забележки слушам... :nazdrave: :nazdrave: :nazdrave:


Върнете се в началото
 Профил  
 
 Заглавие: Re: C - четене на числа от текстов файл
МнениеПубликувано на: Нед Яну 19, 2014 9:59 am 
Offline
Администратор
Аватар

Регистриран на: Нед Ное 02, 2008 5:30 pm
Мнения: 3550
ЧИСЛАТА от текста отиват в масив...

т.е. - първото срещнато в текста число (не цифра), което стои отделено (отделено - разбирай оградено от разделители, писал съм какви примерно) от останалия текст отива в първия елемент на масива - примерно a[0], следващото съществуващо отделно - в следващия - a[1] и т.н...

Ако става въпрос за знаци и цифри - има си функции - например прочети за atoi - може да се ползва наготово, а тук и тук може да се види как тя работи - може би по подобен начин е написана... И понеже е мощна и стандартна - може да бъде ползвана...

Защото, предполагам Pulse (виж го само къде и какво учи и може да се запознаете и да сте си полезни, по-скоро той на тебе... :smile: ) мисли за решение от по-ниско ниво - примерно обхождане на текста по знаци и отделяне на числата, както в самото atoi е направено...

При положение, че има вече написана такава функция - в стандартната библиотека защо да не я ползваме...

Една идея, която аз оптимизирам е - текста се разбива на думи - т.е. всичко между разделителите и се прекарват една по една - ако е число съответната дума - бам в масива...

Това може да се абстрахира/обобщи с една функцийка за валидация - в нашия случай - думата дали е число (цяло - по условие) а в общия - думата дали е "данни" или боклук. Ако са данни - влизат в масива...

Примерно - повреден файл с ЕГН-та - замърсен - да се изкарат колкото могат... тогава ф-цията ще търси и в думата а не просто да проверява думата...

В общия случай - функцията поема дума и я проверява дали е данни от нашия вид и/или в нея дали се съдържат такива - но не разкъсани...

15а, 15, а15 биха били данни - 15, но в нашето условие искам да уточня - данни са чисти думи - оградени само от разделители като " ,;\t\n" - интервалът е първи в списъка...

В php има explode, но то директно вкарва думите в масива, а пък аз искам само числата...

Да не забравим откъде идва целта - искаме при решаване на задачи с масиви, за вход да използваме данни от текстов файл, а не от потребителски вход, което е досадно, и също масивът да не е инициализиран в кода... Това е за да може тестерите да нямат достъп до кода, но да може да тестват изпълнимия файл, като подават по-лесно различни данни... Т.е. данните да се взимат от текстовия файл, дори и замърсени, но разделени...

В горния пример - изхода на програмата ми е масив:
Код:
for(c=0;c<i;c++)
  printf("%d\n",a[c]);
"напълнен" от текстовия файл...

Боря един прост вариант, но нещо това atoi ме бъгва... Би трябвало да връща 0 ако аргументът не е число, но също и 0 ако аргументът е "0"... Но нещо тази проверка не ми излиза... И съм го разработил с функция... Кой знае как и/или откъде ми хрумна (може и да съм чувал някога някъде) как гарантирано да разбирам чрез аtoi дали нещо е "чисто" число...

И е спорно - според как ще определим условието - примерно в горния пример ( :bop: ) колко 15-ки има? 2 или 3?

15a дали е числото 15 или не е число? atoi го връща като числото 15, но се разбираме нашата задача да връща само "чисти" числа... Незамърсени и отдясно... atoi ще върне 15 и на 15abcdef...

ПП @Чефо/Cefothe - няма компилатори за твоя правопис - Цефо... Имаш хубав сайт - прекарай го през валидатор за цистота... Иначе жвуцис като прехапан /прекалил с хапенето/... :thumbsup:

_________________
Изображение


Върнете се в началото
 Профил  
 
 Заглавие: Re: C - четене на числа от текстов файл
МнениеПубликувано на: Нед Яну 19, 2014 8:53 pm 
Offline
Администратор
Аватар

Регистриран на: Нед Ное 02, 2008 5:30 pm
Мнения: 3550
Прикачени файлове:
2.png

Не пействам кода за да се сравнява паралелно и се открият тънките разлики.
Дава и леко различни резултати... Ако искате думи като "15a", "15abcdef" да влезнат в масива като 15 - по-късият вариант работи. В противен случай - по-дългия...


Вие нямате нужните права за да сваляте прикачени файлове.

_________________
Изображение


Върнете се в началото
 Профил  
 
 Заглавие: Re: C - четене на числа от текстов файл
МнениеПубликувано на: Нед Яну 19, 2014 10:48 pm 
Offline
Аватар

Регистриран на: Чет Ное 27, 2008 12:06 am
Мнения: 111
Нека и аз се включа. Нямам време , че имам контролни да седна и да пиша , но малко за релакс от четенето ще се опитам да дам някой идеи.

Първо трябва да се помисли за правилната и безопасна работа на програмата. Иначе казано трябва да има ограничение на големината на числото, което се чете, защото ако се прочете числото 42384309284309243829438297439284, което е доста по-голямо от long int, първо ще се получи грешен резултат в масива, второ ще почне да драска по паметта, която може да е извън границата на масива и да стане краш. Как бих процедирал аз:
- Чети символ по символ докато не срещнеш цифра или знака '-'. В тази задача ASCII е препоръчително, така че го ползвайте за сравняването на символи. Само да подскажа тъй като char e 8-битова стойност то може да се сравнява с число. :)
- Като стигнеш до такъв символ, почни да го записваш в масив от чарове (не забравяй , че ако имаш '-', трябва да провериш дали следващото е цифра. На всяка етерация от цикъла проверявай дали не си надвишил максималния брой символи и ако си - спри.
- тъй като long int може да побере 32 бита информация , обхвата от валидни стойности е от −2147483648 до 2147483647. Редно е да се проверява дали прочетеният стринг влиза в този интервал. Ако влиза сте ок, ако не влиза- махате последния символ от низа и връщате пойнтъра на файла с 1-ца назад (f_seek() мисля, че беше функцията за манипулиране на файловия указател) и вече със сигурност имате валидно число.
- остава да се добави числото в масива. Ползваш atoi() и добавяш в масива и си готов.

Това е начина, по който бих решил задачата на първо време. Може и в случая да не е най-удачния , но ако се сетя за нещо друго ще пиша :)

_________________
Ако нямаш приятели в живота, все едно да живееш в къща върху пясък!
Изображение
http://www.vergov.com


Върнете се в началото
 Профил  
 
 Заглавие: Re: C - четене на числа от текстов файл
МнениеПубликувано на: Нед Яну 19, 2014 11:12 pm 
Offline
Администратор
Аватар

Регистриран на: Нед Ное 02, 2008 5:30 pm
Мнения: 3550
Много си прав за ограничението на числото...

В двата примера има разлика и в този случай - 42384309284309243829438297439284

В единия - di.c -това число просто не влиза (пропуска се) - ограниченията са от 10 знака...

В did.c се получава MIN_INT или MAX_INT ако се излезе извън обхвата на типа...

Та може да се има предвид - цели числа - това си е ограничително условие - в смисъл int...

Ти предлагаш ниски нива - нещо като да си напишем atoi - в примерите, които линкнах по-горе може да се видят дискусии в код по темата...

За целта, която е поставена - да се четат експериментални данни от текст - вариант - високи нива - стига да е работещ - върши работа...

От примерите в линковете може да се види как се работи на ниско ниво (ниво знак) и се анализира за определено съдържание... Подхода е полезен, когато се правят валидиращи функции за определени видове данни - примерно кодове с определена дължина, в които участват определени символи - например само някои букви и цифри...

Иначе при много случаи di.c си се справя с разделителите и трудно минават числа извън обхват... А за драскане в паметта - в тези случаи няма как да стане - не можеш да вкараш в цялочислен масив нещо повече, отколкото типа може да поеме... Дано така стоят нещата и с масивите... Целият текст не го прекарвам символ по символ а със strtok го разбивам, махайки разделителите и взимайки това, което остава между тях - думите...

_________________
Изображение


Върнете се в началото
 Профил  
 
 Заглавие: Re: C - четене на числа от текстов файл
МнениеПубликувано на: Нед Яну 19, 2014 11:24 pm 
Offline
Аватар

Регистриран на: Чет Ное 27, 2008 12:06 am
Мнения: 111
emilang написа:
Иначе при много случаи di.c си се справя с разделителите и трудно минават числа извън обхват... А за драскане в паметта - в тези случаи няма как да стане - не можеш да вкараш в цялочислен масив нещо повече, отколкото типа може да поеме...


С масивите не стоят така нещата. Масивите всъщност са указатели. Даже да се задели масив с един елемент това не пречи да пишеш в същия масив с елемент 2. Пример:

Код:
#include <stdio.h>

void main() {
     int a[1];
     
    a[0] = 0xAAAABBBB;
    a[1] = 0xCCCCDDDD;
    a[2] = 0xEEEEFFFF;
     
    printf("%x, %x, %x", a[0], a[1], a[2]); 
}


Тук е заделен масив с 1 елемент , но това не ни пречи да пишем стойност в следващия адрес. А това винаги може да доведе до краш, защото не знаеш къде в паметта пишеш ;)

EDIT: В нашия случай това, което съм написал няма значение, защото при предаване на данни към променлива, тя взима само толкова данни , колкото може да поеме (като започне от най-младшите битове) и останалото се игнорира. Така, че в случая няма да има краш на програмата при много голямо число, а просто ще има грешни данни.

_________________
Ако нямаш приятели в живота, все едно да живееш в къща върху пясък!
Изображение
http://www.vergov.com


Последна промяна Pulse на Нед Яну 19, 2014 11:36 pm, променена общо 1 път

Върнете се в началото
 Профил  
 
Покажи мненията от миналия:  Сортирай по  
Напиши нова тема Отговори на тема  [ 16 мнения ]  Отиди на страница 1, 2  Следваща

Часовете са според зоната UTC + 2 часа [ DST ]


Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 1 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Иди на:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Превод: Ioan Filipov