ошибка компилятора xcode необъявленный идентификатор переполнение стека

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

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

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

2: Есть ли в любом случае этот код может быть оптимизирован или векторизован либо для краткости или скорости, я был бы очень признателен за любые указатели, так как это моя первая программа на реальном языке программирования (я пришел из Matlab) ?? (например, у меня есть 2 подпрограммы получения значений, одна из которых использует atoi для чтения целых, а другая 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

0

Решение

Переменные живут внутри блока, где они объявлены. Это ты std::ofstream в

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

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

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

Другие решения

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

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

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

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

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

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

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

1

По вопросам рекламы [email protected]