Заполнить и вернуть данные из чтения в C ++ - PullRequest
1 голос
/ 31 октября 2011

Я хотел бы знать, как лучше всего сделать следующее в c ++, пожалуйста.У меня есть классы Parser и Gather;сборщик использует синтаксический анализатор.

У меня есть метод в классе Parser для анализа моего файла с тремя параметрами: ID процесса (int), путь (string, char, char * ... ???) иформат строки (также я не знаю, что здесь лучше - строка, константная строка и т. д.)

Лучше создать данные [] в методе Parse.method и вернуть их, либо передать ссылку на метод и сохранить переменную данных в классе сбора?

char* ProcInfoParser::parseStatm(const int _processPid, std::string _path, std::string _strFormat) {

    char path[32];
    char* data[2042];
    int tps = sysconf(_SC_CLK_TCK);

    int fd = open(path, O_RDONLY);

    if (fd < 0) {
        perror("open");
        return "-1"; //wrong...
    }

    if (read(fd, data, 2048) == -1) {
        perror("read");
        return "-1"; //wrong...
    }
    close(fd);

    char name[1024];
    long unsigned int utime, virt;
    long int rss;
    sscanf(data, "%*d %s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %lu"
        " %*u %*d %*d %*d %*d %*d %*d %*u %lu %ld", name, &utime, &virt, &rss); //Iwish to use the _stringFormat variable here...

    return data;
}

Я действительно не знаю, какой выбрать между char (char * ...) или string;Я также хочу создать путь с идентификатором процесса, например string.Format ("/ proc / (0) / statm", processID);функция sprintf работает так?Может быть, я должен взглянуть на повышение ...

Заранее спасибо

Ответы [ 2 ]

1 голос
/ 31 октября 2011

(также я не знаю, что здесь лучше - строка, константная строка и т. Д.).

С помощью квалификатора "const" вы указываете аргумент как "константный": поэтому вы не будете изменять аргумент.При передаче аргументов по значению это бесполезно: в любом случае создается временная копия на время выполнения функции.

С другой стороны, передавая аргумент по ссылке, становится важным учитывать ключевое слово constправильно:

  • Является ли аргумент небольшим / быстрым для копирования (указатели, числа) - Использовать передачу по значению
  • Используется ли аргумент в качестве "вывода" (ожидается функциядля изменения аргумента) - используйте передачу по ссылке
  • Вы только смотрите на аргумент, не меняя его - используйте "const" & переход по ссылке
  • Если вы хотитеизмените аргумент, но сохраните изменения в локальной области. - Используйте передачу по значению.

Также в основном: std :: string лучше, чем символьные массивы, если только у вас нет особой причины для использованиямассив символов.Хотя это обычно подпадает под микрооптимизации.

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

Я бы позволил сигнатуре функции выглядеть, сделал бы себе одолжение и предотвратил бы проблемы с указателями:

std::string ProcInfoParser::parseStatm(int _processPid, const std::string& _path, const std::string& _strFormat);
0 голосов
/ 31 октября 2011

У вас есть несколько проблем:

char* data[2042];

Массив указателей.Я не думаю, что это то, что вы хотели, вы хотели массив char с, который будет:

char data[2042];

Кроме того, вы передаете std::strings и возвращаете char*, который недействительно соответствует.Если вы вернете std::string - у вас не будет проблем.Вы можете передать его по значению и сохранить в классе, которому он принадлежит.

Последнее, но не менее важное - вы возвращаете указатель на переменную local , которая несуществует, когда вы выходите из функции, это рецепт неприятностей.Возвращение std::string также решит эту проблему.

Итог - здесь вы смешиваете C и C ++ код.Хотя C ++ допускает это, обычно это общий источник ошибок и ошибок.Почему бы не использовать потоки и строки C ++?

...