Премини към съдържанието
Тони Желев

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

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


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

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)

 

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

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

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

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

Редактирано от flare (преглед на промените)

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


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

Благодаря по изясниха ми се нещата, но или ми брой 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'?
  • Харесва ми 1

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


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

Успях да го докарам до работещ код който брой, но ми остана да добавя проверката за " това е кода на цялата програма (курсовата) и тя е обекта на сканиране. като резултат ми изкарва 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 потребители

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

  • Горещи теми в момента

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

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

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

    • от 97joro
      Хора, трябва ми спешно да направя една лесна (според преподавателя) задача на free Pascal, но не съм се занимавал никога с програмиране и за това, ако може някой да помогне със задачата и малко обяснение към нея, ще съм много благодарен.
      Ето и задачата: Да се намери сумата от елементите в отделните стълбове на двумерен масив с m реда и n стълба.
    • от Калин Иванов
      Дадена е права греда с размери и натоварване според схемата. Да се намерят големите на опорните реакции в т. А и т. В
      съср. момент - 13 M,kN.m
        разстояние a,m -1
        Интензивност на раз.товар q,kN -2
       

      Моля за помощ :):)
    • от justdoingit
      Здравейте, за съжаление изпитвам трудности с зададената ми курсна работа, стигнах до някъде и след това просто забих. Най-вече се изгубих във въвеждането на входните данни и отпечатването им. Моля помогнете ми поне за тях. Благодаря ви.
      Ето и условието на задачата:
      Да се състави програма за обработка на масива A[N,N] където данните са цели числа в интервала [-1000;1000]. Програмата да извърши следните действия:
      -отпечатване на условието на задачата.
      -отпечатване на имената на автора.
      -въвеждане на входните данни.
      -отпечатване на входните данни
      -а) да се образува едномерен масив D|N|,който се образува от всички елементи по-големи от P (P се въвежда от клавиатурата),които лежат под главния диагонал на дадения масив;
      -б) полученият масив да се сортира по големина;
      -отпечатване на получените резултати след обработка а) и след обработка б).
      Стигнах до тук:
      #include <stdio.h> #include <stdlib.h> #include <math.h> const int N=15; int n,j,i,m=0; int A[N][N],D[N]; int main() { printf("Vladislav Nikolov Hristov\n"); printf("MTF,Grupa: 19,Potok: 3,F.Nomer: 09849323\n"); printf("Da se systavi programa za obrabotka na masiva A[N,N], kadeto dannite sa celi chisla v intervala [-1000;1000]. Programata da izvyrshi slednite deistviq:\n"); printf("-otpechatvane na uslovieto na zadachata;\n"); printf("-otpechatvane na imenata na avtora na programata;\n"); printf("-vavejdane na vhodnite danni;\n"); printf("-otpechatvane na vhodnite danni;\n"); printf("a) da se obrazuva ednomeren masiv D|N|,koito se obrazuva ot vsichki elementi po-golemi ot P (P se vavejda ot klaviaturata),koito lejat pod glavniq diagonal na dadeniq masiv;\n"); printf("b) polucheniqt masiv da se sortira po golemina;\n"); printf("-otpechatvane na poluchenite rezultati sled obrabotka a) i sled obrabotka b)\n"); scanf("%d"); system("pause"); return 0; }  
       
       
       
  • Дарение

×

Информация

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