2013-09-22 4 views
0

Привет, я пишу фрагмент кода, который читает в файле с вершинами ячеек и координатами вершин ячеек и выводит ячейки в центр.ошибка компилятора xcode необъявленный идентификатор C++

У меня 2 вопроса:

1: Im получить красную ошибку в Xcode при вызове Print_Values ​​подпрограммы, что говорит outfil является необъявленным идентификатором ?? Хотя я идентифицирую файл прямо в начале моей основной функции?

2: Есть ли в любом случае этот код может быть оптимизирован или векторизован как для краткости, так и для скорости, Id очень ценят любые указатели, поскольку это моя первая программа на реальном языке программирования (я пришел из Matlab) ?? (например, у меня есть 2 метода получения значений, которые используют atoi для чтения ints, а другой strtod для чтения удваивается, я не могу придумать способ превратить их в один?)

Редактировать: Использование компилятора cygwin gcc-C++ -std = C++ 11

Приветствия и Большое спасибо

код до сих пор:

#include <algorithm> 
#include <fstream> 
#include <iostream> 
#include <iterator> 
#include <sstream> 
#include <string> 
#include <vector> 
#include <cstdlib> 

std::vector<double> GetValues_n(const std::vector<std::string>& src, int start, int end) 
{ 
    std::vector<double> ret; 
    for(int i = start; i <= end; ++i) 
    { 
     ret.push_back(std::strtod(src[i].c_str(), nullptr)); 
    } 
    return ret; 
} 

std::vector<int> GetValues_c(const std::vector<std::string>& src, int start, int end) 
{ 
    std::vector<int> ret; 
    for(int i = start; i <= end; ++i) 
    { 
     ret.push_back(std::atoi(src[i].c_str())); 
    } 
    return ret; 
} 

std::vector<double> polycentre(const std::vector<double>& x,const std::vector<double>& y,size_t ID) 
{ 
    std::vector<double> C(3, 0); 
    std::vector<double> x1(x.size(),0); 
    std::vector<double> y1(y.size(),0); 
    size_t sizx = x.size(); 
    size_t sizy = y.size(); 
    if(sizy != sizx) 
    { 
     std::cerr << "polycentre inputs not equal length"; 
    } 
    double x0 = x[0]; 
    double y0 = y[0]; 
    for(int aa = 1; aa < sizx; ++aa) 
    { 
     if(x[aa] < x0){x0 = x[aa];} 
     if(y[aa] < y0){y0 = y[aa];} 
    } 
    double A = 0.0; 
    double B = 0.0; 
    for(size_t aa = 0; aa < sizx; ++aa) 
    { 
     x1[aa] = x[aa] - x0; 
     y1[aa] = y[aa] - x0; 
     if(aa != sizx-1) 
     { 
      A = A + (x1[aa]*y1[aa+1] - x1[aa+1]*y1[aa]); 
      B = B + ((x1[aa]+x1[aa+1])*(x1[aa]*y1[aa-1]-x1[aa-1]*y1[aa])); 
     } 
     else if(aa == sizx-1) 
     { 
      A = A + (x1[aa] - y1[aa]); 
      B = B + ((x1[aa]+1)*(x1[aa]*1-1*y1[aa])); 
     } 
    } 
    A = A*0.5; 
    C[0] = ID; 
    C[1] = ((1/6/A)*B)+x0; 
    C[2] = ((1/6/A)*B)+y0; 
    return C; 
} 

template <typename T> 

void PrintValues(const std::string& title, std::vector<std::vector<T>>& v, std::ofstream outfil) 
{ 
    if(outfil.is_open()) 
    { 
     outfil << "ID,X,Y,Z \n"; 
     std::cout << title << std::endl; 
     for(size_t line = 0; line < v.size(); ++line) 
     { 
      for(size_t val = 0; val < v[line].size(); ++val) 
      { 
       std::cout << v[line][val] << " "; 
       outfil << v[line][val] << ","; 
      } 
      outfil << "\n"; 
      std::cout << std::endl; 
     } 
     std::cout << std::endl; 
    } 
} 

int main(int argc, char* argv[]) 
{ 
    if (argc < 2) 
    { 
     std::cerr << argv[0] << " needs to get input file (2dm)" << std::endl; 
    } 

    else if (argc == 3) 
    { 
     std::ofstream outfil(argv[2]); 
    } 

    else 
    { 
     std::ofstream outfil(std::string(argv[1]) + ".csv"); 
    } 

    std::vector<std::vector<std::string>> values; 
    std::ifstream fin(argv[1]); 

    for (std::string line; std::getline(fin, line);) 
    { 
     std::istringstream in(line); 
     values.push_back(
         std::vector<std::string>(std::istream_iterator<std::string>(in), 
                std::istream_iterator<std::string>())); 
    } 

    std::vector<std::vector<int>> cells; 
    std::vector<std::vector<double>> nodes; 

    for (size_t i = 0; i < values.size(); ++i) 
    { 
     if(values[i][0] == "E3T") 
     { 
      cells.push_back(GetValues_c(values[i], 1, 5)); 
     } 
     else if(values[i][0] == "E4Q") 
     { 
      cells.push_back(GetValues_c(values[i], 1, 6)); 
     } 
     else if(values[i][0] == "ND") 
     { 
      nodes.push_back(GetValues_n(values[i], 1, 4)); 
     } 
    } 

    std::vector<std::vector<double>> cell_centres; 

    for (size_t aa = 0; aa < cells.size(); ++aa) 
    { 
     if(cells[aa].size() == 5) 
     { 
      std::vector<double> xs = {nodes[(cells[aa][1]) - 1][1], nodes[(cells[aa][2]) - 1][1], nodes[(cells[aa][3]) - 1][1]}; 
      std::vector<double> ys = {nodes[(cells[aa][1]) - 1][2], nodes[(cells[aa][2]) - 1][2], nodes[(cells[aa][3]) - 1][2]}; 
      cell_centres.push_back(polycentre(xs,ys,aa+1)); 
     } 
     else if(cells[aa].size() == 6) 
     { 
      std::vector<double> xs = {nodes[(cells[aa][1]) - 1][1], nodes[(cells[aa][2]) - 1][1], nodes[(cells[aa][3]) - 1][1], nodes[(cells[aa][4]) - 1][1]}; 
      std::vector<double> ys = {nodes[(cells[aa][1]) - 1][2], nodes[(cells[aa][2]) - 1][2], nodes[(cells[aa][3] - 1)][2], nodes[(cells[aa][4]) - 1][2]}; 
      cell_centres.push_back(polycentre(xs,ys,aa+1)); 
     } 
    } 

    PrintValues("Cell Centres", cell_centres, outfil); 
    //PrintValues("Cells", cells, outfil); 
    //PrintValues("Nodes", nodes, outfil); 

    return 0; 
} 

входной файл:

MESH2D 
MESHNAME "default coverage" 
NUM_MATERIALS_PER_ELEM 1 
E4Q 1 19 20 14 16 2 
E4Q 2 17 16 15 23 2 
E4Q 3 22 15 14 21 2 
E4Q 4 4 3 21 20 1 
E4Q 5 6 20 19 7 1 
E4Q 6 18 17 10 9 1 
E4Q 7 17 23 12 11 1 
E4Q 8 7 19 18 8 1 
E4Q 9 22 1 13 23 1 
E3T 10 14 20 21 2 
E3T 11 21 2 22 1 
E3T 12 21 3 2 1 
E3T 13 22 2 1 1 
E3T 14 5 20 6 1 
E3T 15 20 5 4 1 
E3T 16 16 14 15 2 
E3T 17 23 13 12 1 
E3T 18 22 23 15 2 
E3T 19 17 11 10 1 
E3T 20 17 18 16 2 
E3T 21 8 18 9 1 
E3T 22 18 19 16 2 
ND 1 -3.25811078e+002 7.70285567e+001 0.00000000e+000 
ND 2 -3.24209146e+002 7.60394871e+001 0.00000000e+000 
ND 3 -3.23012110e+002 7.44783503e+001 0.00000000e+000 
ND 4 -3.22754089e+002 7.25326647e+001 0.00000000e+000 
ND 5 -3.23617358e+002 7.08079432e+001 0.00000000e+000 
ND 6 -3.25161538e+002 6.98134116e+001 0.00000000e+000 
ND 7 -3.27128620e+002 6.98759747e+001 0.00000000e+000 
ND 8 -3.29095703e+002 6.99385378e+001 0.00000000e+000 
ND 9 -3.30301095e+002 7.14667646e+001 0.00000000e+000 
ND 10 -3.30786908e+002 7.33241555e+001 0.00000000e+000 
ND 11 -3.30835733e+002 7.52916270e+001 0.00000000e+000 
ND 12 -3.29587322e+002 7.65401204e+001 0.00000000e+000 
ND 13 -3.27743000e+002 7.72270000e+001 0.00000000e+000 
ND 14 -3.26108525e+002 7.32067724e+001 0.00000000e+000 
ND 15 -3.27041416e+002 7.42070316e+001 0.00000000e+000 
ND 16 -3.27350377e+002 7.31716751e+001 0.00000000e+000 
ND 17 -3.29153676e+002 7.40024406e+001 0.00000000e+000 
ND 18 -3.28659180e+002 7.19967464e+001 0.00000000e+000 
ND 19 -3.26845856e+002 7.14062637e+001 0.00000000e+000 
ND 20 -3.25000347e+002 7.20534611e+001 0.00000000e+000 
ND 21 -3.24701329e+002 7.39638966e+001 0.00000000e+000 
ND 22 -3.26167714e+002 7.53360591e+001 0.00000000e+000 
ND 23 -3.28060316e+002 7.54194849e+001 0.00000000e+000 
BEGPARAMDEF 
GM "Mesh" 
SI 0 
DY 0 
TU "" 
TD 0 0 
NUME 3 
BCPGC 0 
DISP_OPTS entity 0 0 0 0 1 0 0 0 
DISP_OPTS inactive 0 0 0 0 1 0 0 0 
DISP_OPTS multiple 0 0 0 0 1 0 0 0 
BEFONT 0 1 
DISP_OPTS entity 1 0 0 0 1 0 0 0 
DISP_OPTS inactive 1 0 0 0 1 0 1 0 
DISP_OPTS multiple 1 0 0 0 1 0 1 0 
BEFONT 1 1 
DISP_OPTS entity 2 0 0 0 1 0 0 0 
DISP_OPTS inactive 2 0 0 0 1 0 1 0 
DISP_OPTS multiple 2 0 0 0 1 0 1 0 
BEFONT 2 1 
MAT 1 "material 01" 
MAT 2 "material 02" 
MAT_MULTI 0 
ENDPARAMDEF 
BEG2DMBC 
END2DMBC 
BEGCURVE Version: 1 
ENDCURVE 

ответ

2

Переменные, находящиеся внутри блока, где они объявлены. То есть, вы std::ofstream в

... 
else if (argc == 3) 
{ 
    std::ofstream outfil(argv[2]); 
} 
... 

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

std::ofstream outfil; 
... 
else if (argc == 3) 
{ 
    outfil.open(argv[2]); 
} 
1

Это возможно использовать одну функцию чтения для чтения и удваивает и целые числа: всегда используйте strtod и читайте ваши цифры как double.

Тем не менее: существует огромное функциональное различие между этими двумя типами чисел относительно того, как вы находитесь , используя. Целочисленные числа - это индексы, а двойные значения - это координаты. Поскольку вы не можете использовать удвоения в качестве индексов, их нужно будет отличать до int перед каждым использованием. Это не приводит к «оптимизированному коду», а скорее наоборот!

«Дополнительные накладные расходы» - в этом случае функциональный код, который считывает, сохраняет и использует номера в наиболее подходящем типе для их функции - не автоматически равен «менее оптимизированному коду».

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

Если вам нужна одна конкретная процедура - чтение из внешнего файла и анализ результата - чтобы быть быстрым, прочитайте весь файл данных в памяти, обработайте и отбросьте. Вам все еще нужны strtod и atoi (любой код, который вы бы придумали сами, вероятно, медленнее), но вы можете написать простой строковый сканер, который циклически перебирает данные один раз. Но вы должны только подумать об этом, если , читающий, является узким местом.

Оффлайн Я не вижу никаких оптимизаций в вычислительной части. Единственное, что вы можете сделать, это сразу же сохранить минимальные значения при чтении в вашей программе Getvalue_C.

Но остерегайтесь преждевременной оптимизации! Чтобы узнать, где ваш код «медленный», используйте профилировщик.

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