2015-02-07 4 views
0

У меня есть задание для моего класса Software Engineering, который заставляет меня бананы. Мне было предложено создать счетчик строк, который учитывает только логические строки кода для любого заданного файла. Он должен опускать пустые строки и комментарии.Пропуск строк комментариев, начиная с // в C++

У меня код очень много работает, за исключением того, что он перечитывает номера строк на 2 строки независимо от того, какой файл я передаю в него. Я не могу для жизни меня видеть, где моя проблема, и было интересно, может ли кто-нибудь помочь мне.

Вот мой код:

#include <iostream> 
#include <fstream> 
#include <string> 
#include <cstring> 
#include <stdio.h> 

using namespace std; 

int main() { 

    // Initialize variables 
    ifstream infile; 
    string filename; 
    int line = 0; 

    // Get file input 
    cout << "Enter the filename" << endl; 
    cin >> filename; 

    // open the file 
    infile.open(filename.c_str()); 

    // read the lines and skip blank lines and comments 
    while(getline(infile, filename)) { 
     if(filename.empty() || filename.find("//") == true) { 
      continue; 
     } 

     // increment the line number 
     ++line; 
    } 

    // close the file 
    infile.close(); 

    // display results 
    cout << "There are " << line << " lines of code in this file." << endl; 
} 

Счетчик гласит в терминале: «Есть 24 строк кода в этом файле.»

Согласно моим расчетам, должно быть только 22 строки логического кода. Помощь была бы оценена.

+0

Вам не нужно делать 'infile.open (filename.c_str())'. Просто 'infile.open (filename) 'будет делать. – emlai

+0

@zenith: зависит от версии стандартной библиотеки. Перегрузка 'std :: string' была добавлена ​​долго после того, как она должна была быть. –

+2

Также вы не должны использовать функции, если не знаете, как их использовать. 'string :: find' возвращает позицию аргумента, если она была найдена в строке и' npos', если она не была найдена, а не логическое значение. – emlai

ответ

1

Почему вы не добавляете инструкцию печати, такую ​​как cout << filename << '\n';, чтобы идентифицировать линии, которые она идентифицирует? Я подозреваю, что вы увидите несколько пустых строк.

Я подозреваю, что вам нужно обрезать пробелы из ваших строк. Вероятно, у вас есть пустые строки, содержащие пробелы или вкладки. Следовательно, они не являются технически пустыми до значения str :: empty.

Кроме того, выполняя обрезку и исправляя другую ошибку, которую я вижу в вашем коде, рассматривая комментарий «//» в качестве комментария.

Следовательно, это становится простым исправлением с обрезками.

while(getline(infile, filename)) { 

    filename = ltrim(filename); // remove leading whitespace 
    filename = rtrim(filename); // remove trailing whitespace 

    if(filename.empty() || (filename.find("//") == 0)) { 
     continue; 
    } 

    // increment the line number 
    ++line; 
} 

Вы можете найти реализацию RTRIM и LTrim on this other SO answer here.

+0

Это возвращает массу ошибок для меня. Прежде всего, ltrim и rtrim возвращаются как недействительные, потому что они не объявлены в рамках моей программы. Я приписываю это не декларированию библиотек, к которым они принадлежат. –

+0

@ n_alvarez2007 - Я не собираюсь делать домашнее задание для вас. Stack Overflow не является вашим личным механическим турком. Функции 'ltrim' и' rtrim' вам нужно будет скопировать из ссылки, которую я дал вам в нижней части моего ответа. – selbie

0

Заменить filename.find("//") == true с filename.find("//") == 0, чтобы найти строки, которые начинаются с //, так что он не будет думать, что линии, как int i = 0; // comment не являются строки кода.

+0

Это не работает. Я попробовал ваше предложение, и мой результат прошел от 24 строк кода до 30 строк кода, что означает, что он стал еще менее точным. –

+0

@ n_alvarez2007 Я не говорил, что это единственная модификация, которую вам нужно будет сделать. – emlai

0
  1. empty() означает «никакого персонажа вообще», в то время как вы также хотите отфильтровать строки, содержащие только пробелы ant tabs.
  2. вы можете иметь код в строках, которые содержат // (например int i; // loop index, поэтому фильтрация их получите неправильные результаты

верный способ делать вещи будет:.

  1. стрип комментарии
  2. полоса
  3. пробельные символы

, а затем увидеть, если оставшаяся строка пуста или нет.

Обработка строк в C/C++ является жалкой, поэтому вы будете 1.000.000 бедным парнем, вынужденным писать (или копировать) код, необходимый для выравнивания пространств на обоих концах строки.

кстати. вызывающий filename переменная, которая должна удерживать текущую строку, не является ярлыком из банановой рощи.

Смежные вопросы