Другой человек не понимает связи между main.cpp, program_name.cpp и program_name.h

Я пытался взглянуть на старые сообщения по переполнению стека по этому вопросу, но я все еще в замешательстве и был бы очень признателен, если бы кто-нибудь объяснил мне, где я здесь ошибаюсь.

Я использую Apple XCode 3, и у меня есть три файла в папке «Source» моего проекта. Это calcsteps.cpp, calcsteps.h и main.cpp.

У меня в основном есть #include "calcsteps.h", Насколько я понимаю, это буквально вставляет содержание calcsteps.h, которые являются просто кучей объявлений функций. В этом файле .h нет директив. Тем не менее, мой файл .cpp с тем же именем имеет директиву, которая также имеет директиву #include "calcsteps.h",

main.cpp:

#include "calcsteps.h"#include <string>
#include <iostream>

int main (int argc, char* const argv[]) {

// Evaluate expressions at the console
std::string eqtn;
while (std::cin >> eqtn) {
if (!valid_equation(eqtn)) {
std::cout << "Equation invalid; not evaluated" << std::endl;
} else {
std::cout << evaluate_equation(eqtn) << std::endl;
}
}

return 0;
}

calcsteps.h:

std::string evaluate_equation(std::string);
bool valid_equation(const std::string&);
int str2Int(const std::string&);
std::string int2Str(unsigned int);
bool isDigit(char);
bool isOp(char);
std::string addStrs(const std::string&, const std::string&);
std::string subtrctStrs(const std::string&, const std::string&);
std::string multStrs(const std::string&, const std::string&);
std::string divStrs(const std::string&, const std::string&);
std::string powStr(const std::string&, const std::string&);

calcsteps.cpp:

#include "calcsteps.h"
#include <iostream>
#include <string>
#include <algorithm>
#include <math.h>std::string evaluate_equation(std::string eq) {
/* By the order of operations:
(1) Evaluate the expression in the innermost set of paranthesis;
(2) Evaluation exponents;
(3) Evaluate multiplication and division expressions left-to-right;
(4) Evaluate addition and substraction expressions left-to-right;
Use recursion. Print out steps.
*/

// (1):
size_t LRFP = eq.find_last_of('('); // position of last right-facing paranthesis
if (LRFP != std::string::npos) {
// Set NLFP to be the position of the next left-facing paranthesis after the FRFPL
size_t NLFP = LRFP;
while (eq[++NLFP] != ')');
/* Replace the space between FRFP and NLFP inclusive with the evalulation of the expression
between FRFP and NLFP exclusive:
*/
std::string paranstr = eq.substr(LRFP + 1, NLFP - LRFP - 1);
std::cout << eq << " -> ";
eq.replace(LRFP, NLFP - LRFP + 1, evaluate_equation(paranstr));
std::cout << eq << std::endl;
return evaluate_equation(eq);
}
// (2):
size_t firstexp = eq.find_first_of('^');
if (firstexp != std::string::npos) {
// Set base and power equal to the respective numbers to the left and right of the '^' symbol
std::string base, power;
size_t basebegin(firstexp), powerend(firstexp);
while (basebegin > 0 && isDigit(eq[basebegin - 1]))
base.insert(0, 1, eq[--basebegin]);
int eqsz = eq.size();
while ((powerend + 1) < eqsz && isDigit(eq[powerend + 1]))
power.push_back(eq[++powerend]);
// Replace the space of the multiplication equation base^power with its evaluation:
std::cout << eq << " -> ";
eq.replace(basebegin, powerend - basebegin + 1, powStr(base, power));
std::cout << eq << std::endl;
return evaluate_equation(eq);
}

// (3):
size_t firstast(eq.find_first_of('*')), firstslash(eq.find_first_of('/')); // position of first asterisk
size_t firstMD = std::min(firstast, firstslash);
if (firstMD != std::string::npos) {
// Set num1 and num2 equal to the respective numbers to the left and right of the asterisk:
std::string num1, num2;
size_t num1begin(firstMD), num2end(firstMD);
while (num1begin > 0 && isDigit(eq[num1begin - 1]))
num1.insert(0, 1, eq[--num1begin]);
int eqsz = eq.size();
while ((num2end + 1) < eqsz && isDigit(eq[num2end + 1]))
num2.push_back(eq[++num2end]);
std::cout << eq << " -> ";
if (firstMD == firstast) {
// Replace the space of the multiplication equation num1*num2 with its evaluation:
eq.replace(num1begin, num2end - num1begin + 1, multStrs(num1, num2));
} else {
// Replace the space of the division equation num1/num2 with its evaluation:
eq.replace(num1begin, num2end - num1begin + 1, divStrs(num1, num2));
}
std::cout << eq << std::endl;
return evaluate_equation(eq);
}
// (4):
size_t firstplus(eq.find_first_of('+')), firstminus(eq.find_first_of('-'));
size_t firstAS = std::min(firstplus, firstminus);
if (firstAS != std::string::npos) {
// Set num1 and num2 equal to the respective numbers to the left and right of the asterisk:
std::string num1, num2;
size_t num1begin(firstAS), num2end(firstAS);
while (num1begin > 0 && isDigit(eq[num1begin - 1]))
num1.insert(0, 1, eq[--num1begin]);
int eqsz = eq.size();
while ((num2end + 1) < eqsz && isDigit(eq[num2end + 1]))
num2.push_back(eq[++num2end]);
std::cout << eq << " -> ";
if (firstAS == firstplus) {
// Replace the space of the addition equation num1+num2 with its evaluation:
eq.replace(num1begin, num2end - num1begin + 1, addStrs(num1, num2));
} else {
// Replace the space of the subtraction equation num1-num2 with its evaluation:
eq.replace(num1begin, num2end - num1begin + 1, subtrctStrs(num1, num2));
}
std::cout << eq << std::endl;
return evaluate_equation(eq);
}
// If we made it to this point, all that's left of the equation is a single number. Return it;
return eq;
}

bool valid_equation(const std::string& eq) {
// Equation cannot be empty:
if (eq.empty()) {
std::cout << "Equation cannot be an empty string" << std::endl;
return false;
}
std::string::const_iterator it = eq.begin();
// First character must be a right-facing parenthesis or a digit:
if (*it != '(' && !isDigit(*it)) {
std::cout << "Equation cannot start with " << *it << std::endl;
return false;
}
/* Iterate through the characters of the equation to check that it is valid based on
which characters are lined up next to which. For example, if two plus signs are found
next to each other, that makes the equation meaningless and the our function
valid_equation() immediately returns false.
*/
// Count for the number of right-facing and left-facing parantheses:
int RFPcnt(0), LFPcnt(0);
while ((it + 1) != eq.end()) {
if (isDigit(*it)) {
char nextchar = *(it + 1);
if (!isDigit(nextchar) && !isOp(nextchar)) {
std::cout << "Digit cannot be followed by " << nextchar << std::endl;
return false;
} else {
++it;
}
} else if (isOp(*it)) {
char nextchar = *(it + 1);
if (!isDigit(nextchar) && nextchar != '(') {
std::cout << "Operator cannot be followed by " << nextchar << std::endl;
return false;
} else {
++it;
}
} else if (*it == '(') {

} else if (*it == ')') {

} else {
std::cout << "Inavlid character: " << *it << std::endl;
return false;
}
}
/* At this point, 'it' is the last character in the equation. It must be a digit
or left-facing parenthesis.
*/
if (*it != ')' && !isDigit(*it)) {
std::cout << "Equation cannot end with " << *it << std::endl;
return false;
}

// Check for unbalanced parentheses
if (LFPcnt != RFPcnt) {
std::cout << "Unbalanced parantheses." << std::endl;
return false;
}

return true; // If we made it here, the equation is valid; return true
}

// Given a decimal representation as a string s, str2Int(s) returns the corresponding decimal as an int
int str2Int(const std::string& str) {
std::string::const_iterator it = str.begin();
if (it == str.end()) {
std::cout << "Invalid parameter: str2Int() only accepts non-empty strings." << std::endl;
return -1;
}
int sum = 0;
while (it != str.end()) {
if (!isDigit(*it)) {
std::cout << "Invalid parameter: str2Int only accepts strings of chars '0' through '9'" << std::endl;
return -1;
} else {
sum *= 10;
sum += *it++ - '0';
}
}
return sum;
}

// Given an int n, int2Str(n) return the string representation
std::string int2Str(unsigned int n) {
std::string retstring;
if (n == 0) {
retstring.push_back('0');
return retstring;
} else {
while (n != 0) {
retstring.insert(0, 1, char('0' + n % 10));
n /= 10;
}
return retstring;
}
}

// Function that checks whether a given character is in one of '0', '1', ..., '9'
bool isDigit(char c) {
return (c >= '0' && c <= '9');
}

bool isOp(char c) {
switch (c) {
case '^': return true;
case '*': return true;
case '/': return true;
case '+': return true;
case '-': return true;
default: return false;
}
}

// Adds 2 string decimal representations and returns the sum as a string decimal representation
std::string addStrs(const std::string& s1, const std::string& s2) {
return (int2Str(str2Int(s1) + str2Int(s2)));
}

// Substracts 2 string decimal representations and returns the result as a string decimal representation
std::string subtrctStrs(const std::string& s1, const std::string& s2) {
return (int2Str(str2Int(s1) - str2Int(s2)));
}// Multiplies 2 string decimal representations and returns the sum as a string decimal representation
std::string multStrs(const std::string& s1, const std::string& s2) {
return (int2Str(str2Int(s1) * str2Int(s2)));
}

// Divides 2 string decimal representations and returns the quotient as a string decimal representation
std::string divStrs(const std::string& s1, const std::string& s2) {
return (int2Str(str2Int(s1) / str2Int(s2)));
}

/* Raises the string decimal representation s to the string decimal representation p power and returns the
result as a string decimal representation.
*/
std::string powStr(const std::string& s, const std::string& p) {
return (int2Str((int)pow((double)str2Int(s), (double)str2Int(p))));
}

Когда я пытаюсь скомпилировать calcsteps.cpp, я получаю ошибки во всех точках, где реализации функций вызывают другие функции. Любой совет с благодарностью.

-3

Решение

Ваш calcSteps.h не включает стандартные заголовки, содержащие объявления для используемых вами стандартных типов, таких как std::string,

Это приведет, среди многих других сообщений об ошибках, к следующему:powStr не был объявлен в этой области «, потому что powStrОбъявление просто не может быть понято с этими ссылками на неизвестные стандартные типы.

Даже если вы включили эти заголовки в calcsteps.cppты сделал так после в том числе calcSteps.h, Так как вы абсолютно правы, что #include как копирование и вставка, эти включения приходят слишком поздно.

Обычно мы включаем заголовки где они нам нужны поэтому стандартные заголовки должны быть включены из calcSteps.h,

Я бы также предложил сделать ваше соглашение о соответствии имени файла согласованным, а ваш calcSteps.h в настоящее время защита от включения находится в main.cpp вместо этого — предположительно опечатка.

1

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

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector