2016-12-29 4 views
-1

Ниже мой код:Как игнорировать чтение содержимого/* комментарий */при чтении файла

string ckeywords = File.ReadAllText("E:\\ckeywords.csv"); 
string[] clines = File.ReadAllLines("E:\\cprogram\\cpro\\bubblesort.c"); 
string letters=""; 

foreach(string line in clines) 
{ 
    char[] c = line.ToCharArray(); 
    foreach(char i in c) 
    { 
     if (i == '/' || i == '"') 
     { 
      break; 
     } 
     else 
     { 
      letters = letters + i; 
     } 
    } 
} 
letters = Regex.Replace(letters, @"[^a-zA-Z ]+", " "); 

List<string> listofc = letters.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList(); 
List<string> listofcsv = ckeywords.Split(new char[] { ',', '\t', '\n', ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(p => p.Trim()).ToList(); 
List<string> Commonlist = listofcsv.Intersect(listofc).ToList(); 

С этим if состоянии, я могу игнорировать чтение содержимого одной строки комментария и содержимое между ("").

Мне нужно игнорировать чтение содержимого нескольких строк. Какое условие я должен использовать? Предположим, что мой .c-файл имеет эту строку комментария, поэтому с приведенным выше кодом я не знаю, как начать итерацию с/* на */и игнорировать содержимое между ними.

/* printf ("Отсортированный список в порядке возрастания: \ n");

для (с = 0; с < п; C++) Е ("% d \ п", массив [с]); */

+0

http://stackoverflow.com/questions/3524317/regex-to-strip-line-comments-from-c-sharp/3524689#3524689 –

+0

качестве альтернативы. Если вы читаете строку для строки, вы можете просто найти начало/* и удалить все из этой строки. Вы вытаскиваете флаг и удаляете каждую строку, пока не увидите конец * /. И не удаляйте ничего из этого. –

+0

Я знаю логику. Мне нужен код в csharp, чтобы игнорировать его проще. –

ответ

1

Я успешно решил свою задачу m теперь я могу игнорировать чтение содержимого/* */более простым способом, не используя регулярное выражение. Вот мой код:

string[] clines = File.ReadAllLines("E:\\cprogram\\cpro\\bubblesort.c"); 
List<string> list = new List<string>(); 
int startIndexofcomm, endIndexofcomm; 

for (int i = 0; i < clines.Length ; i++) 
    { 
     if (clines[i].Contains(@"/*")) 
      { 
      startIndexofcomm = clines[i].IndexOf(@"/*"); 
      list.Add(clines[i].Substring(0, startIndexofcomm)); 

      while(!(clines[i].Contains(@"*/"))) 
      { 
       i++; 
      } 

      endIndexofcomm = clines[i].IndexOf(@"*/"); 
      list.Add(clines[i].Substring(endIndexofcomm+2)); 

      continue; 
      } 
      list.Add(clines[i]); 
    } 
-2

Язык С использует "C препроцессор", чтобы лишить комментарии среди прочего, среди прочего. Это важная часть языка. Очень важно, чтобы большинство файлов C содержали macros and definitions, которые были преобразованы в C с использованием препроцессора.

#define forever for(;;) /* Define a "new keyword" for convenience */ 

forever 
{ 
    /* Eternally looping code */ 
} 

Так что ваша программа на C не имеет смысла без препроцессора.

Если вы действительно не хотите писать свои собственные, вы можете просто запустить bubblesort.c через существующий C preprocessor, чтобы отключить комментарии.

Я хочу, чтобы выбрать только C ключевые слова из файла .C

Вы находитесь на пути написания собственных C компилятор с нуля. На этот вопрос слишком большой вопрос. Вам нужен Dragon Book.

+0

Это, как правило, практический подход, но препроцессор C делает намного больше, чем требует OP. В частности, он заставляет директивы '# include' вставлять заголовок с ссылкой. Я ничего не вижу в этом вопросе, предполагая, что это приемлемо. – hvd

+0

Я читаю файл .c в программе C#, и там я хочу игнорировать чтение содержимого нескольких строк, однострочных комментариев, а также содержимого между («this»). –

+0

Что вы подразумеваете под «между (« this »)»? Вы имеете в виду текст в скобках? –

0

Вот код, который простодушно выполняет следующие действия:

  1. Он обрежет любой многострочные комментарии начиная с /* и заканчивая */, даже если есть новые строки между ними.
  2. Он удаляет любые однострочные комментарии, начинающиеся с // и заканчивается в конце строки
  3. Это делает не полосы из любых комментариев, как выше, если они в пределах строки, которая начинается с " и концами с ".

LINQPad код:

void Main() 
{ 
    var code = File.ReadAllText(@"d:\temp\test.c"); 
    code.Dump("input"); 

    bool inString = false; 
    bool inSingleLineComment = false; 
    bool inMultiLineComment = false; 

    var output = new StringBuilder(); 
    int index = 0; 

    while (index < code.Length) 
    { 
     // First deal with single line comments: // xyz 
     if (inSingleLineComment) 
     { 
      if (code[index] == '\n' || code[index] == '\r') 
      { 
       inSingleLineComment = false; 
       output.Append(code[index]); 
       index++; 
      } 
      else 
       index++; 

      continue; 
     } 

     // Then multi-line comments: /* ... */ 
     if (inMultiLineComment) 
     { 
      if (code[index] == '*' && index + 1 < code.Length && code[index + 1] == '/') 
      { 
       inMultiLineComment = false; 
       index += 2; 
      } 
      else 
       index++; 
      continue; 
     } 

     // Then deal with strings 
     if (inString) 
     { 
      output.Append(code[index]); 
      if (code[index] == '"') 
       inString = false; 
      index++; 
      continue; 
     } 

     // If we get here we're not in a string or in a comment 
     if (code[index] == '"') 
     { 
      // We found the start of a string 
      output.Append(code[index]); 
      inString = true; 
      index++; 
     } 
     else if (code[index] == '/' && index + 1 < code.Length && code[index + 1] == '/') 
     { 
      // We found the start of a single line comment 
      inSingleLineComment = true; 
      index++; 
     } 
     else if (code[index] == '/' && index + 1 < code.Length && code[index + 1] == '*') 
     { 
      // We found the start of a multi line comment 
      inMultiLineComment = true; 
      index++; 
     } 
     else 
     { 
      // Just another character 
      output.Append(code[index]); 
      index++; 
     } 
    } 

    output.ToString().Dump("output"); 
} 

Пример ввода:

This should be included // This should not 
This should also be included /* while this 
should not */ but this should again be included. 

Any comments in " /* strings */ " should be included as well. 
This goes for "// single line comments" as well. 

Пример вывода (обратите внимание, что есть некоторые пробелы в конце некоторых из приведенных ниже строк, которые не видны) :

This should be included 
This should also be included but this should again be included. 

Any comments in " /* strings */ " should be included as well. 
This goes for "// single line comments" as well. 
+0

Для полноты, по сравнению с тем, как C: это не обрабатывает символьные константы (в 'int main() {'"'; short s;} ',' short s; 'не является частью string), он не обрабатывает обратные косые черты в строках (в 'int main() {" \ ""; short s;} ',' short s; 'снова не является частью строки) или как часть линейного сращивания (в '' '\' '' ', а затем в следующей строке' * int main() {} */', две строки образуют комментарий), а при изменении для обработки обратных косых черт и символьных констант триграфы могут образовывать проблема (в 'int main() {0 ?? '" "[0]; short s;}', 'short s;' не является частью символьной константы). Это может быть хорошо. – hvd

+0

Да, но поскольку я пытался указать в своих комментариях на вопрос, если OP *** явно! *** не нужно/не нужно таких «сложных» вещей, наивное решение - лучшее, что может быть создано. Я бы даже не хотел * попробовать * написать решение для этого, которое может обрабатывать все совместимые синтаксисы Си. –

+0

Я тоже не хочу; учитывая, что это то, что спросил ОП, я решил просто не отвечать вообще. :) Я просто хотел дать понять, что бы и не сработало, чтобы ОП и другие, читающие этот ответ, могли принять обоснованное решение относительно того, достаточно ли это для их нужд. – hvd