Номер строки C / C++

в целях отладки, я могу получить номер строки C/компиляторы C++? (стандартный способ или конкретные способы для определенных компиляторов)

Эл.г

if(!Logical)
    printf("Not logical value at line number %d n",LineNumber);
    // How to get LineNumber without writing it by my hand?(dynamic compilation)

7 ответов


вы должны использовать макрос __LINE__ и __FILE__. Они являются предопределенными макросами и частью стандарта C/C++. Во время предварительной обработки они заменяются соответственно постоянной строкой, содержащей целое число, представляющее текущий номер строки, и текущим именем файла.

другие переменные препроцессора :

  • __func__: имя функции (это часть C99 не все компиляторы C++ поддерживают его)
  • __DATE__: a строка формы"ммм ДД гггг"
  • __TIME__ : строка формы "hh: mm: ss"

ваш код будет :

if(!Logical)
  printf("Not logical value at line number %d in file %s\n", __LINE__, __FILE__);

в рамках стандарта C++ существует несколько предопределенных макросов, которые можно использовать. Раздел 16.8 стандарта C++ определяет, среди прочего,__LINE__ макрос.

__LINE__: номер строки текущей строки (десятичной постоянный.)
__FILE__: предполагаемое имя исходного файла (символьная строка буквальный.)
__DATE__: дата перевода исходного файла (a символьная строка буквальный...)
__TIME__: время перевода исходного файла (символьная строка буквальный...)
__STDC__: ли__STDC__ заранее
__cplusplus: имя __cplusplus определяется значением 199711L, когда компиляция единицы перевода C ++

таким образом, ваш код будет:

if(!Logical)
  printf("Not logical value at line number %d \n",__LINE__);

вы можете использовать макрос с тем же поведением, что и printf (), за исключением того, что он также включает отладочную информацию, такую как имя функции, класс и номер строки:

#include <cstdio>  //needed for printf
#define print(a, args...) printf("%s(%s:%d) " a,  __func__,__FILE__, __LINE__, ##args)
#define println(a, args...) print(a "\n", ##args)

эти макросы должны вести себя одинаково с printf (), включая информацию, подобную java stacktrace. Вот пример main:

void exampleMethod() {
    println("printf() syntax: string = %s, int = %d", "foobar", 42);
}

int main(int argc, char** argv) {
    print("Before exampleMethod()...\n");
    exampleMethod();
    println("Success!");
}

что приводит к следующему выводу:

main(main.cpp: 11) Перед exampleMethod()...
exampleMethod (main.cpp: 7) синтаксис printf (): string = foobar, int = 42
основной(main.cpp: 13) успех!


использовать __LINE__ (это двойное подчеркивание строки с двойным подчеркиванием), препроцессор заменит его номером строки, на которой он встречается.


оформить заказ __FILE__ и __LINE__ макрос


попробовать __FILE__ и __LINE__.
Вы также можете найти __DATE__ и __TIME__ полезное.
Хотя, если вам не нужно отлаживать программу на стороне клиента и, следовательно, нужно регистрировать эти сведения, вы должны использовать обычную отладку.


поскольку я также сталкиваюсь с этой проблемой сейчас, и я не могу добавить ответ на другой, но также действительный вопросздесь, я приведу пример решения проблемы: получение только номера строки, где функция была вызвана в C++ с помощью шаблонов.

Background: в C++ в качестве аргумента шаблона можно использовать целочисленные значения не-типа. Это отличается от обычного использования типов данных в качестве аргументов шаблона. Идея в том, чтобы использовать такое целое число значения вызова функции.

#include <iostream>

class Test{
    public:
        template<unsigned int L>
        int test(){
            std::cout << "the function has been called at line number: " << L << std::endl;
            return 0;
        }
        int test(){ return this->test<0>(); }
};

int main(int argc, char **argv){
    Test t;
    t.test();
    t.test<__LINE__>();
    return 0;
}

выход:

функция была вызвана по номеру строки: 0

функция была вызвана по номеру строки: 16

одна вещь, чтобы упомянуть здесь, что в стандарте C++11 можно дать значения шаблона по умолчанию для функций, использующих шаблон. В pre c++11 значения по умолчанию для аргументов не-типа, похоже, работают только для аргументов шаблона класса. Таким образом, в C++11, не было бы необходимо иметь повторяющиеся определения функций, как указано выше. В C++11 также допустимо иметь аргументы шаблона const char*, но невозможно использовать их с литералами, такими как __FILE__ или __func__ Как уже упоминалось здесь.

Итак, в конце концов, если вы используете C++ или C++11, это может быть очень интересной альтернативой, чем использование макросов для получения вызывающей строки.