Премини към съдържанието

Архивирана тема

Темата е твърде стара и е архивирана. Не можете да добавяте нови отговори в нея, но винаги можете да публикувате нова тема, в която да продължи дискусията. Регистрирайте се или влезте във вашия профил за да публикувате нова тема.

Тони Желев

Въпрос относно броенето на идентификатори

Препоръчан отговор


Имам курсова задача  в която трябва да преброя редовете и броя на идентификаторите. С редовете нямам проблем но тези идентификатори не мога и не мога да разбера как да ги следя... Нали идентификатор е всяко име(за което се заделя памет). Примерно

int a,b,c;char masiv1[30];int main();{printf("hello world");return 0;}

Тук идентификаторите са а,b,c,masiv1, но не мога да измисля как да напиша програма в която да ги преброя тези имена... Опитвах по какъв ли не начин, но не се получава. Прочетох една от по старите теми и получих малко просветление, но там беше даден линк с пояснения, но той вече не работи. За това моля за някакви насоки как да проверявам за неща.

 

Условието точно гласи: " За "идентификатор" ще се приема всяка част от текста,която започва с буква или символ за подчертаавне и съдържа букви,цифри и символ за подчертаване, при условие, че не се намира в символен низ или коментар. Да се отчита, че кавичката не винаги затваря низ("abc"def"). Да не се изключват ключовите думи в езика.

 

А и още нещо не мога да използвам парсери(phasers или както се пишеха :/) нито други библиотеки само "спартански" условия и C.

 

Всяка помощ е добре дошла дори било то само насоки или примерна извадка от някъде която върши работа. Благодаря предварително.

Сподели този отговор


Линк към този отговор
Сподели в други сайтове

Нали идентификатор е всяко име(за което се заделя памет).

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

Условието точно гласи: " За "идентификатор" ще се приема всяка част от текста,която започва с буква или символ за подчертаавне и съдържа букви,цифри и символ за подчертаване, при условие, че не се намира в символен низ или коментар. Да се отчита, че кавичката не винаги затваря низ("abc"def"). Да не се изключват ключовите думи в езика.

Дори е упоменато, че не трябва да изключваш запазените думи.

А и още нещо не мога да използва пасери(phasers или както се пишеха :/) нито други библиотеки само "спартански" условия и C.

Парсери (parsers)

 

Отваряш файла и го прочиташ символ по символ.

Отсортираш коментарите. Най-лесно става, като си направиш флаг, дали си в коментар/низ и какво точно е - вдигаш го при /*, // или " и го сваляш при */, край на ред или " съответно. Проверяваш все пак за ескейп т.е.

Правиш си брояч.

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

Сподели този отговор


Линк към този отговор
Сподели в други сайтове

Благодаря по изясниха ми се нещата, но или ми брой 0 или дава грешка (don't send..) нещо в if-овете ми куса :/.

int fIdentifierCount(char fin[]){    int i=0;    int in_coment=0;    char buff[200000];    unsigned int id_count;        FILE *fp = fopen(fin,"r");        if(fp==NULL)       return -1;    else    {     while(!feof(fp))      {       buff[i]=fgetc(fp);        i++;      }        do         {                                if(buff[i]=='/' && buff[i+1]=='/' || buff[i]=='/' && buff[i+1]=='*'  || buff[i+1]=='"')            {                                 in_coment=1;            }                      while(in_coment==0){              if(buff[i]=='n' || buff[i]=='*' && buff[i]=='/' || buff[i]== '"' )            {              in_coment=0;            }                     else  if(buff[i]>='a' && buff[i]<='z' || buff[i]>='A' && buff[i]<='Z' || buff[i]>='0' && buff[i]<='9' || buff[i]=='_')            {              if((buff[i+1]>='a') && (buff[i+1]<='z' )|| (buff[i+1]>='A') && (buff[i+1]<='Z') ||( buff[i+1]>='0') && (buff[i+1]<='9') || (buff[i+1]=='_') || buff[i]=='0')                      id_count++;            }            i++;            }            i++;         }while(buff[i]<='0');     }          return id_count;}

Това ми е функцията ако може още някоя и друга насока.

Сподели този отговор


Линк към този отговор
Сподели в други сайтове

Благодаря по изясниха ми се нещата, но или ми брой 0 или дава грешка (don't send..) нещо в if-овете ми куса :/.Това ми е функцията ако може още някоя и друга насока.

Поред:Не е необходимо да прочиташ целия файл в буфер. Старите символи не те интересуват. Чети си символ по символ и проверявай.Прочиташ символа в буфера до i, след което продължаваш нататък с проверките. Еми ясно е, че буфера ти е неинициализиран... Лоша грешка.Проверката за коментарите. Изрично посочих, че трябва да имаш флаг и за вид. Иначе програмата ти ще приема, че коментар започващ с /* може да завърши с ", примерно.Така както си направил while след това, никога няма да влезе ако си в коментар и съответно никога няма да свърши коментара.Слагай скоби на тия условия и/или ги разписвай на няколко реда или най-добре си направи функции. Да пишеш много неща на един ред в C е точно обратното на хубаво нещо.Не си инициализирал id_count. Променливите от стека в C не се инициализират автоматично.Що реши че масива ще ти завършва на '0'?

Сподели този отговор


Линк към този отговор
Сподели в други сайтове

Успях да го докарам до работещ код който брой, но ми остана да добавя проверката за " това е кода на цялата програма (курсовата) и тя е обекта на сканиране. като резултат ми изкарва 249 идентификатора.

#include <stdio.h>#include <stdlib.h>#include <windows.h>// Functions prototypes Startvoid fcase1(char *,char *,int );void fcase2(char *,int);void fcase3(char *,int);void fcase4(int);int fLinesCount(char *);int fIdentifierCount(char *);int fSearchChar(char *,char,int);// Functions prototypes Endint main(){    char exit; do {      int choise,count=0;    char fin[30];    char fout[30];// Styling StartSetConsoleOutputCP(1251);system("COLOR 0A");// Styling End// Menu Startprintf("////////////////////////////////////////////////////////////////////");printf("////////////");printf("//");printf("                         Курсова Работа по ПИК I ");printf("                           //");printf("//");printf("   Изработил Тони Христов Желев, факултет ФТК, група 54б, номер 111");printf("213205");printf("   //");printf("//");printf("                                                               ");printf("             //");printf("//");printf("Моля изберете опция от менюто.");printf("                                              //");printf("//");printf("                                                                   ");printf("         //");printf("//");printf("1. Четене програмата от файл и запис на резултата в друг. ");printf("                  //");printf("//");printf("2. Четене прогрмата от файл и извеждане на резултата на екрана.");printf("             //");printf("//");printf("3. Четене на програмата от клавиатурата и извеждане във файл.");printf("               //");printf("//");printf("4. Четене на програмата от клавиатурата и извеждане резултата на");printf(" екрана.");printf("    //");printf("//");printf("                                                  ");printf("                          //");printf("///////////////////////////////////////////////////////////////////");printf("/////////////");printf("Избор: "); fflush(stdin);  scanf("%i",&choise);// Menu End// Switch start    switch (choise)    {    case 1:  fcase1(fin,fout,count);        break;    case 2:  fcase2(fin,count);        break;    case 3:  fcase3(fout,count);        break;    case 4:  fcase4(count);        break;    default:  printf("Въведохте невалидна опция");        break;    }// Switch end// Close the program [y/n] Start fflush(stdin); printf("nИскате ли да затоврите програмата? [y/n]"); fflush(stdin); scanf("%c",&exit); system("cls"); }while(exit!='y');// Close the program [y/n] End    return 0;}// Definition of Functionsint fLinesCount(char fin[]){   unsigned int lines_count = 0;    FILE *fp = fopen(fin, "r");    int ch;    if(fp==NULL)      return -1;    else    while ((ch=fgetc(fp))!=EOF  )        if ( ch == 'n')            ++lines_count;    fclose(fp);    return lines_count;}int fIdentifierCount(char fin[]){    int i=0;    int in_str_comment=0;    int in_line_comment=0;    int in_quotes;    int in_word=0;    int in_number=0;    unsigned int id_count;    char buff[1024];       	 FILE *fp = fopen(fin,"r");   	 if(fp==NULL)	   return -1;    else    {	    do		 { 			    buff[i]= fgetc(fp);			  		    if(buff[i]=='/' && buff[i+1]=='/')			 in_line_comment=1;		   if (buff[i]='n')			 in_line_comment=0;		    		   		    if(buff[i]=='/' && buff[i+1]=='*')			 in_str_comment=1;		  		   if (buff[i]=='*' && buff[i+1]=='/')			 in_str_comment=0;		  		   if((buff[i] >= '0') && (buff[i] <= '9') && in_word==0)			 {			   in_number = 1;			 }	    		   if(in_str_comment==0 && in_line_comment==0 && in_number==0 )		  { 			 if(!(((buff[i] >= 'A') && (buff[i] <= 'Z')) || ((buff[i] >= 'a') && (buff[i] <= 'z')) || ((buff[i] >= '0') && (buff[i] <= '9')) || (buff[i] == '_')))			 in_word=1;		    			  if(in_word)			 {id_count++;}		  } 		   in_word=0;		  in_line_comment=0;		  in_quotes=0;		  in_str_comment=0;		  in_number=0;		   i++;		 }while(buff[i]!=EOF);	 }    	  return id_count;}void fcase1(char fin[],char fout[], int count){    FILE *ffout;    int v,m;        printf("Моля въведете името на файла за четене: ");         fflush(stdin);        scanf("%s",fin);        printf("Моля въведете името на файла за записване: ");          fflush(stdin);        scanf("%s",fout);          fflush(stdin);                ffout=fopen(fout,"w");                    v=fLinesCount(fin);            if(v==-1)             fprintf(ffout,"File "%s" can't be opened",fin);            else            fprintf(ffout,"Броя на редовете е - %dn",v);           m=fIdentifierCount(fin);            if(m==-1)             fprintf(ffout,"File "%s" can't be opened",fin);            else            fprintf(ffout,"Броя на идентификаторите е - %dn",m);                       fclose(ffout);}void fcase2(char fin[], int count){    int v;        printf("Моля въведете името на файла за четене: ");         fflush(stdin);        scanf("%s",fin);                            v=fLinesCount(fin);            if(v==-1)             printf("File "%s" can't be opened",fin);            else            printf("Броя на редовете е - %d",v);}void fcase3(char fout[], int count){  int v,i=0;  char buff[20000];    FILE *ffout;                 printf("Моля въведете името на файла за записване: ");          fflush(stdin);        scanf("%s",fout);          fflush(stdin);                    ffout=fopen(fout,"w");            printf("Напишете програмата и натиснете CTRL+Z за край:n");       while((buff[i]=fgetc(stdin))!=EOF)       {          i++;       }       buff[i]='0';             i=0;       while(buff[i]!='0')        {         if (buff[i]=='n')  ++count;          i++;        }      fprintf(ffout,"Броя на редовете е - %d",count);       fclose(ffout);}void fcase4(int count){  int v,i=0;  char buff[20000];        printf("Напишете програмата и натиснете CTRL+Z за край:n");       while((buff[i]=fgetc(stdin))!=EOF)        {          i++;        }       buff[i]='0';              i=0;       while(buff[i]!='0')        {         if (buff[i]=='n')  ++count;          i++;        }      printf("Броя на редовете е - %d",count);   }

a само функцията

int fIdentifierCount(char fin[]){    int i=0;    int in_str_comment=0;    int in_line_comment=0;    int in_quotes;    int in_word=0;    int in_number=0;    unsigned int id_count;    char buff[1024];       	 FILE *fp = fopen(fin,"r");   	 if(fp==NULL)	   return -1;    else    {	    do		 { 			    buff[i]= fgetc(fp);			  		    if(buff[i]=='/' && buff[i+1]=='/')			 in_line_comment=1;		   if (buff[i]='n')			 in_line_comment=0;		    		   		    if(buff[i]=='/' && buff[i+1]=='*')			 in_str_comment=1;		  		   if (buff[i]=='*' && buff[i+1]=='/')			 in_str_comment=0;		  		   if((buff[i] >= '0') && (buff[i] <= '9') && in_word==0)			 {			   in_number = 1;			 }	    		   if(in_str_comment==0 && in_line_comment==0 && in_number==0 )		  { 			 if(!(((buff[i] >= 'A') && (buff[i] <= 'Z')) || ((buff[i] >= 'a') && (buff[i] <= 'z')) || ((buff[i] >= '0') && (buff[i] <= '9')) || (buff[i] == '_')))			 in_word=1;		    			  if(in_word)			 {id_count++;}		  } 		   in_word=0;		  in_line_comment=0;		  in_quotes=0;		  in_str_comment=0;		  in_number=0;		   i++;		 }while(buff[i]!=EOF);	 }    	  return id_count;}

имам някаква идея от рода на:

if(buff[i]==''" && buff[i+1]!='"')in_quotes=1;

но не се сещам как да го сваля, мислех гo като:

buff[i-1]!='"' && buff[i]=='"'

но тогава се препокирват едно с друго.. :/


Сподели този отговор


Линк към този отговор
Сподели в други сайтове

Нямам много време сега но набързо:Какво ти казах за буфера? безсмислен е. Можеш ли да обясниш какво очакваш да има в buff[i+1] ей тук, като още не си го прочел?

buff[i]= fgetc(fp);if(buff[i]=='/' && buff[i+1]=='/')

Направи си две променливи за сегашен и предишен символ и толкова. Също не чети по 2 наведнъж, че ще изпуснеш нещо. Само първият път после преместваш сегашния в предния и четеш сегашния.

Направи си още три променливи (брой очаквани символи за край, очакван предишен и очакван следващ) като се натъкнеш на някакво начало на коментар низ си ги насетваш за съответния край, заедно с флаг, че чакаш край и след това проверяваш по брой и дали съвпадат (брой ти трябва, щото за низ чакаш един а за многоредов коментар примерно 2).

Може да има и други грешки.

Сподели този отговор


Линк към този отговор
Сподели в други сайтове

Днес ми дойде една малко странна идея, но не знам колко ще ми свърши работа... Масив(или файл и после да добавя информацията му в масив) със всички типове данни. След това да вкарвам ред по ред в програмата и да проверявам. Ще имам 2 функции за прескачане на коментари (една за // и една за /* */). И примерно имам ред:

int ImeNaFunckiq();int main();{// nqkakuv komentar   int prom1,prom2;/* drug komentar prosto za primer */... return 0;}

И така да сравнявам всеки ред дума по дума с тази от масив-а. Ако се окаже, че има съвпадение (с някоя дума), да прескочи интервала и ако следващият знак е буква ( визирам "int prom1,prom2;"  да имам един брояч който брой запетайките като накрая върне резултат от брояча +1 [нали 1 запетая разделя 2 думи] ), а ако следващият знак е скоба (  пък да увеличава някакъв друг броя. И вече най отдолу на функцията събера двата брояча, не знам дали идеята си заслужава но на мен ми се струва ок, остава само да се оправя с вкарването на файл с ключовите думи в масив...

 

файла (прим. keywords.txt) ще бъде просто списък с по 1 тип на ред. прим

charunsigned charintlong int 

и така всичките.

Сподели този отговор


Линк към този отговор
Сподели в други сайтове

...

Сложно, ненужно и мисля грешно, отделно пак ще ти трябват флагове защото може да има многоредови коментари и низове.Ненужно, защото по условие не пише да броиш само уникалните и грешно защото изрично пише да не изпускаш ключовите думи.

Сподели този отговор


Линк към този отговор
Сподели в други сайтове

така реших да започна наново и направих ето това.

int fIdentifierCount(char source[]){    int idCount=0;    int line=0;        // flags    bool fComment= false;    bool fQuotes= false;    bool fApostr= false;    bool fNumber= false;    bool fWord= false;FILE *fp;fp=fopen(source,"r");if(fp==NULL)    return -1;else if(fp!=NULL) {    char temp[1024];    while(fgets(temp,sizeof(temp),fp)!=NULL)     {        int i;        line++;         for(i=0;i<strlen(temp);i++)          {             if(temp[i]=='/' && temp[i+1]=='/' && fQuotes)              {                 break;              }             if(temp[i]=='/' && temp[i+1]=='*' && !fQuotes)              {                 fComment=true;                 continue;              }             if(temp[i]=='/' && temp[i-1]=='*' )              {                 fComment=false;                 continue;              }              if(temp[i]=='"' && !fQuotes && temp[i-1]!='')               {                  fQuotes=true;               }              else if(temp[i]=='"' && fQuotes && temp[i-1]!='')               {                  fQuotes=false;               }              if(temp[i]==''' && !fApostr && !fQuotes)               {                 fApostr=true;               }              else if(temp[i]==''' && fApostr && !fQuotes)               {                  fApostr=false;               }              if((temp[i]>='0' && temp[i]<='9') && !fWord)               {                  fNumber=true;               }              if(((temp[i]>='A') && (temp[i]<='Z')) || ((temp[i]>='a') && (temp[i]<='z')) || (temp[i]<='_'))               {                  if(!fApostr && !fQuotes && !fComment && !fNumber && !fWord)                   {                      fWord=true;                   }               }              if(!(((temp[i]>='A') &&(temp[i]<='Z')) || ((temp[i]>='a') && (temp[i]<='z')) || ((temp[i]>='0') && (temp[i]<='9')) || (temp[i]=='_')))               {                  if(fWord)                   {                      idCount++;                      fWord=false;                   }                  else if(fNumber)                   {                      fNumber=0;                   }               }            }    } }     fclose(fp);     return idCount;}

Така това сега отговаря ли на описанието за идентификатор по-горе?

Сподели този отговор


Линк към този отговор
Сподели в други сайтове

  • Разглеждащи това в момента   0 потребители

    Няма регистрирани потребители разглеждащи тази страница.

  • Подобни теми

    • от Alexandar Jelev
      Здравейте, искам  да попитам някой може ли да ми помогне за курсовата задача, ще му бъда изключително благодарен? :)
      Задачата е следната:
      Съставете програма с функции за:
      а) Въвеждане от клавиатура във файл и в масив ( чрез добавяне) данни за автобусни превози ( до 35 ) - Автогара Варна: маршрут, дата (1 до 31), номер на автобуса, фамилия на водача, брой пътници, цена на съответните билети, обща сума на билетите - през месец юли. Извеждане текущото съдържание на масива (файла) на екран;
      б) Извеждане на екран справка за всички превози през избран ден от месеца ( със запитване за нова справка);
      в) Извеждане на екран номерата на автобусите и общата сума на билетите от превозите, извършени с тях, подредени в низходящ ред по сумата.
                   Главна функция main() -с меню  за избор на функции и проврка за състоянието на данните.  Използване на функции с предаване на параметри.
       
    • от BWB. Eclipto
      Търся помощ за курсовата си работа по програмиране, защото отсъствах близо два месеца поради операция, а не се имам с колегите си.
      задачата гласи :"Съставете алгоритъм и напишете програма за въвеждане координатите на точки и извеждане на екрана координатите на онези от тях, които не лежат в защрихованата област.Въвеждането се прекратява, когато броят на въведените точки стане най-малко М и броят на лежащите в защрихованата област стане N."

      помощ!!
    • от Фердинанд Костадинов
      Здравейте, имам задача по корпоративна политика
      Да се изясни достоверността и обективността на поднесената информация в 
      следния линк:

      https://www.youtube.com/watch?v=PEfeQ2pTaK0&feature=share
      Къде ли не търсих в интернет, но не намирам почти никаква информация, която да докаже, че нещата, които този човек
      говори и споделя са истина.Трябват ми поне няколко аргумента, за да мога да изясня достоверността на поднесената информация от
      г-н Станков.
      Когато му напиша името в гугъл ми излизат съобщения, че според не знам какви закони,
      са изтрити по негово желание доста линкове, а точно те ми трябват, как бих могъл да стигна до тях и въобще
      възможно ли е да се направи от човек, който не е толкова на ти с IT сферата?
      Възможно е някои резултати да са били премахнати съгласно европейското законодателство за защита на личните данни.
      Ако някой има идея, как мога да се справя с това като цяло, моля да сподели.
       
    • от Karttela
      Здравейте! Затруднявам се много с втората ми курсова работа по програмиране на c++. Моля някой да ми помогне понеже няма как да я направя... Ще съм много благодарен ако някой успее да ми помогне понеже тези файлове са ми пълна индия... Благодаря предварително ! Условието ще го кача като снимка!

    • от 97joro
      Хора, трябва ми спешно да направя една лесна (според преподавателя) задача на free Pascal, но не съм се занимавал никога с програмиране и за това, ако може някой да помогне със задачата и малко обяснение към нея, ще съм много благодарен.
      Ето и задачата: Да се намери сумата от елементите в отделните стълбове на двумерен масив с m реда и n стълба.
  • Дарение

×

Информация

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