Why do I keep getting unresolved externals for my program? - c++

I keep getting unresolved externals when I try to run this code in Visual Studio.
Structure Time Assignment for College
Create a structure called Time that has members days, hours, minutes,
and seconds as ints.
Create an instance of Time and initialize the members.
Create a function to normalize the time when values are added to it.
For example, after adding values to the hours, call the normalize
function which should see if the hours > 24.
If so, add 1 to the days member and reset hours by subtracting 24
from the current value.
DO the same for minutes and seconds over 59.
Your main program should add values to hours, minutes and seconds and
after each, call the normalize function to properly set the values.
Output the members after each update. Assume hours use a 24-hour
clock.
#include <iostream>
using namespace std;
Struct time
{
int days = 0;
int hours = 0;
int minutes = 0;
int seconds = 0;
};
void normalize();
int main()
{
int clockRepeating;
for (clockRepeating = 0; clockRepeating < 150; clockRepeating++)
{
normalize();
}
return 0;
}
void normalize(Time &timenormalize)
{
if (timenormalize.days > 31)
timenormalize.days = 1;
if (timenormalizehours > 24)
{
timenormalize.hours = 0;
timenormalize.days++;
}
if (timenormalize.minutes > 59)
{
timenormalize.minutes = 0;
timenormalize.hours++;
}
if (time normalize.seconds > 59)
{
timenormalize.seconds = 0;
timenormalize.minutes++;
cout << timenormalize.days, timenormalize.hours, timenormalize.minutes, timenormalize.seconds;
}
else
timenormalize.seconds++;
cout << timenormalize.days, timenormalize.hours, timenormalize.minutes,timenormalize.seconds;

The signature you declared for void normalize(); does not match the signature as it's defined in this file (void normalize(Time &timenormalize)).

Here's a fixed up version of your code. First the compilation errors:
changed Struct to struct: struct is a key word, must be lowercase;
changed Time to struct time in void normalize(..): symbols are case sensitive: Time isn't declared, but struct time is;
added missing . to if (timenormalizehours): if (timenormalize.hours);
added } to the end of the file (probably copy/paste error).
And then the linker error undefined reference to 'normalize':
change function declaration void normalize() to void normalize(struct time &): you declare the normalize function without parameters, but define it with one parameter.
And then finally the compilation error this introduces:
change the normalize(); call to normalize( mytime ); because it takes a paramter
and declare a local variable struct mytime to pass as the parameter.
#include <iostream>
using namespace std;
struct time
{
int days = 0;
int hours = 0;
int minutes = 0;
int seconds = 0;
};
void normalize(struct time &);
int main()
{
int clockRepeating;
struct time mytime;
for (clockRepeating = 0; clockRepeating < 150; clockRepeating++)
{
normalize( mytime );
}
return 0;
}
void normalize(struct time &timenormalize)
{
if (timenormalize.days > 31)
timenormalize.days = 1;
if (timenormalize.hours > 24)
{
timenormalize.hours = 0;
timenormalize.days++;
}
if (timenormalize.minutes > 59)
{
timenormalize.minutes = 0;
timenormalize.hours++;
}
if (timenormalize.seconds > 59)
{
timenormalize.seconds = 0;
timenormalize.minutes++;
cout << timenormalize.days, timenormalize.hours, timenormalize.minutes, timenormalize.seconds;
}
else
timenormalize.seconds++;
cout << timenormalize.days, timenormalize.hours, timenormalize.minutes,timenormalize.seconds;
}
It prints a series of 0. Now it's up to you to put some values in struct time mytime. I hope this helps!

Related

CPP: why is dereferencing a pointer to a template type not populating a variable?

I do a lot of modeling and simulation and I am writing a sim_logger in CPP. The basics of it are this: a user constructs the class with a logging frequency and an output path. They can then "register" any number of variables which gives the logger a reference to the desired variable (its not incredibly safe right now but I'll work on that later, focused on the issue at hand). I've created a template type called "variable" which contains three things, T *var, T last_val, and string ID. My problem is this, whenever I set the last_val equivalent to the var, the last_val inside the variable does not actually change. I am setting this value in line 180 of sim_logger.h. I feel like this is a silly problem, probably due to some misunderstanding I have of pointers. However, I've tried several different things and cannot seem to solve this problem.
sim_logger.h
#include <iostream>
#include <iomanip>
#include <fstream>
#include <vector>
#include <variant>
#include <type_traits>
#include <math.h>
pragma once
// a class to log simulation data
// specifically for logging time dependent differential functions
class sim_logger
{
private:
// a type that represents a variable
/*
meant to contain anything, but limited by the variadic type
"poly_var_types" below
*/
template <typename T>
struct variable
{
T *var; // pointer to the variable itself
T last_val; // the last value of the variable
std::string ident; // the identity of the variable
};
// a variadic type
template <typename ... T>
using poly_var_types = std::variant<T...>;
// defined variable types
// these are the typical types that are logged, feel free to add more
using var_types = poly_var_types<
variable<double>,
variable<float>
// variable<int>,
// variable<bool>,
// variable<std::string>
>;
// class members
std::vector<var_types> registered_variables; // container of all variables
std::ofstream file; // output file stream
double dt; // the logging time step in seconds
double clock = 0.0; // the logging clock in seconds
double last_sim_time = clock; // the last sim time for interp
bool is_time_to_log = false; // flag for log function
const double EPSILON = 0.000000001; // rounding error
// a linear interpolation method
// only returns floating point values
double lin_interp(double x, double x1, double x2, double y1, double y2)
{
return (y1+(x-x1)*((y2-y1)/(x2-x1)));
}
public:
// constructor which sets the logging frequency and output path
// log_dt is a floating point value in units of seconds
// path_to_file is a string representation of the desired output path
sim_logger(double log_dt, std::string path_to_file)
{
dt = log_dt;
file.open(path_to_file);
file << std::setprecision(16) << std::fixed;
}
// method to register a variable with the logger
template <typename T>
void register_variable(std::string ident, T *aVar)
{
variable<T> v;
v.ident = ident;
v.var = aVar;
registered_variables.push_back(v);
};
// a method to write the log file header and log sim time 0.0 data
void write_header_and_log_init_data()
{
// write header
file << "sim_time" << " ";
for (int i = 0; i < registered_variables.size(); i++)
{
std::visit([&](auto rv)
{
if (i == registered_variables.size()-1)
file << rv.ident << "\n";
else
file << rv.ident << " ";
}, registered_variables[i]);
}
// log all registered variables
file << clock << " ";
for (int i = 0; i < registered_variables.size(); i++)
{
std::visit([&](auto rv)
{
if (i == registered_variables.size()-1)
file << *rv.var << "\n";
else
file << *rv.var << " ";
}, registered_variables[i]);
}
}
// method to log all registered variables
void log_data(double sim_time)
{
// check the timing
if (sim_time > (clock + dt))
{
is_time_to_log = true;
}
// check if its time to log
if (is_time_to_log)
{
// update the clock
clock += dt;
// debug
std::cout << "\n";
// log all registered variables
file << clock << " ";
for (int i = 0; i < registered_variables.size(); i++)
{
std::visit([&](auto rv)
{
// instantiate the value to be logged
double log_val;
// debug
std::cout << rv.last_val << " " << *rv.var << std::endl;
// if sim time is even with clock time, log at time
if (fabs(sim_time - clock) < EPSILON)
// if (true)
{
log_val = *rv.var;
}
// if sim time is past clock time, interpolate
else
{
log_val = lin_interp(sim_time, last_sim_time,
clock, rv.last_val, *rv.var);
}
// if last variable in vector create new line
if (i == registered_variables.size()-1)
file << log_val << "\n";
// otherwise just whitespace
else
file << log_val << " ";
}, registered_variables[i]);
}
// debug
std::cout << "\n";
// reset flag
is_time_to_log = false;
}
// get all the last values
for (int i = 0; i < registered_variables.size(); i++)
{
std::visit([&](auto rv)
{
// have to get last value at every update call
// This works in scope but the memory does not actually change?
// I am very confuse.
rv.last_val = *rv.var;
// debug
std::cout << rv.last_val << " " << *rv.var << std::endl;
}, registered_variables[i]);
}
// set the last sim time
last_sim_time = sim_time;
}
};
main.cpp
include <iostream>
include "sim_logger.h"
int main()
{
sim_logger logger(0.1, "sim_logger/log.dat");
double test1 = 100.0;
double test2 = 100.0;
double test3 = 100.0;
logger.register_variable("test1", &test1);
logger.register_variable("test2", &test2);
logger.register_variable("test3", &test3);
logger.write_header_and_log_init_data();
double simTime = 0.0;
double simDt = 1.0 / 20.0;
for (int i = 0; i < 3; i++)
{
simTime += simDt;
test1 += 1.0;
test2 += 2.0;
test3 += 3.0;
logger.log_data(simTime);
}
return 0;
};
output
101 101
102 102
103 103
102 102
104 104
106 106
1.88705e-26 103
1.88705e-26 106
1.88705e-26 109
103 103
106 106
109 109
std::visit([&](auto rv)
rv is, effectively, a parameter to this function (the closure, for the purposes of this answer, is effectively a function).
As you know: in C++ function parameters get passed by value. For example, using a simple function:
void func(int x)
{
x=5;
}
This func can set x to 5 as often as it wants. Whatever actually gets passed in, by anyone that calls func(), will remain unaffected:
int z=7;
func(z);
z is still 7. Even though func set its parameter to 5. This is fundamental to C++:
std::visit([&](auto rv)
{
rv.last_val = *rv.var;
So, this sets rv.last_val. Great. But this has no effect on whatever gets passed into here.
}, registered_variables[i]);
The visited instance of this variant is still what it is. It hasn't changed. Why would it change? C++ does not work this way.
So, if your intent, here, is to modify registered_variables[i], it should be passed by reference:
std::visit([&](auto &rv)
Now, the object referenced by rv gets modified.

C++ (Arduino), Can't update object when accessing it as attribute of another object

I have recently bought an Arduino which uses C++ to code on. I am familiar with Java and as C++ allows OO programming I didn't think it would have been that difficult. But...
CODE:
// LEDCLOCK CLASS /////////////////////////////////////////////////////////////////////////
class LedClock{
private:
int hours;
int minutes;
int seconds;
static const long secondInterval = 1000;
unsigned long previousMilliseconds;
unsigned long currentMilliseconds;
public:
LedClock(){
hours = 0;
minutes = 0;
seconds = 0;
previousMilliseconds = 0;
currentMilliseconds = 0;
};
int getHours(){
return hours;
};
int getMinutes(){
return minutes;
};
int getSeconds(){
return seconds;
};
long getSecondInterval(){
return secondInterval;
};
unsigned long getPreviousMilliseconds(){
return previousMilliseconds;
};
void setHours(int h){
if(h < 24 && h >= 0){
hours = h;
}else{
hours = 0;
}
};
void setMinutes(int m){
if(m < 60 && m > 0){
minutes = m;
}else{
minutes = 0;
}
};
void setSeconds(int s){
if(s < 60 && s > 0){
seconds = s;
}else{
seconds = 0;
}
};
void setPreviousMilliseconds(unsigned long ms){
previousMilliseconds = ms;
};
void increaseOneHour(){
// as there is no day counter to increment atm this if-else statement is a bit useless.
// setHour(getHours() + 1) would have sufficed here with the current setter
if(getHours()==23){
setHours(0);
}else{
setHours(getHours() + 1);
}
};
void increaseOneMinute(){
if(getMinutes() == 59){
increaseOneHour();
setMinutes(0);
}else{
setMinutes(getMinutes() + 1);
}
};
void increaseOneSecond(){
if(getSeconds() == 59){
increaseOneMinute();
setSeconds(0);
}else{
setSeconds(getSeconds() + 1);
}
};
void tick(){
currentMilliseconds = millis();
if(currentMilliseconds - getPreviousMilliseconds() >= getSecondInterval()){
setPreviousMilliseconds(currentMilliseconds);
increaseOneSecond();
}
};
};
// LEDCLOCKCONTROLLER CLASS ////////////////////////////////////////////////////////////////
class LedClockController{
private:
LedClock ledClock;
int mode = 2;
public:
LedClockController(LedClock lc){
ledClock = lc;
};
LedClock getLedClock(){
return ledClock;
};
int getMode(){
return mode;
};
void setMode(int newMode){
mode = newMode;
};
};
// ARDUINO CODE /////////////////////////////////////////////////////////////////////////
LedClock lc = LedClock();
LedClockController lcc(lc);
void setup() {
Serial.begin(9600); //Begin serializer to print out value
}
void loop() {
//doesn't give me updated values
if(lcc.getLedClock().getPreviousMilliseconds()<63000){
Serial.println(lcc.getLedClock().getSeconds());
lcc.getLedClock().tick();
}
//does give me updated values
//commented out for now
/*
if(lc.getPreviousMilliseconds()<63000){
Serial.println(lc.getSeconds());
lc.tick();
}
*/
}
Q1:
I have difficulties to update attributes of my LedClock attribute in my Controller class.
When I target the LedClock by itself, everything runs fine but when I would update it via the Controller, then it wouldn't. In short, when getting the seconds in the first case, I could see the increment in values in the output. When I did the same thing but via the controller, the seconds stayed 0.
So I am missing something vital here. Can someone help/explain what I am missing?
Q2: Ideally I would want to create the LedClock object inside the constructor but didn't seem to find how to.
I tried things that could make sense but with the issues I have been having, I was holding off on this:
LedClockController lcc(LedClock lc());
LedClockController lcc(LedClock);
//would make sense to me, I noticed C++ doesn't use the 'new' keyword so have no idea how to do that then
LedClockController lcc(LedClock());
All of those ran into compilation issues so probably another important C++ thing that I haven't taken into account.
P.S. I have been noticing that there are some different views on getter and setters (accessing the attributes directly vs actual functions). I have been using the method I am used to (and were mentioned on W3schools) because I will rely on setting logic in 1 place.

C++: Error in Object-Oriented Program - Works in Visual Studios but not CodeBlocks

I'm new to C++. We are learning object-oriented programming at the moment but I'm having an error with my program. I normally use Visual Studios and the program compiled fine. When I submitted it on Mimir, a program that checks your work automatically, it stated that it did not want to compile. I went ahead to try and run it on CodeBlocks and it does not compile. I'm really stumped with this issue. I'm 99% sure that it is a error within my code and not the compilers.
*ClockMan.cpp*
#include "CClockType.h"
#include <iostream>
using namespace std;
int main(){
CClockType myclock;
myclock.printTime();
myclock.setTime(10,9,35);
myclock.printTime();
CClockType yourclock;
yourclock.setTime(10, 9, 36);
yourclock.printTime();
CClockType Figueroaclock (12, 0, 0);
Figueroaclock.printTime();
CClockType classClocks[10];
for (int i = 0; i < 10; i++)
classClocks[i].setTime(9,27,30);
CClockType * ptrClock = & (classClocks[1]);
ptrClock = &yourclock;
ptrClock ->setTime(9, 32, 20);
ptrClock = classClocks;
for (int i = 0; i < 10; i++){
ptrClock->setTime(9,27,30);
ptrClock++;
}
int size = 2;
ptrClock = new CClockType[size];
CClockType * tmpClock = ptrClock;
for (int i = 0; i < size; i++){
tmpClock->setTime(9,27,30);
tmpClock++;
}
delete [] ptrClock;
cin.ignore(1124, '\n');
cin.get();
return 0;
}
*CClockType.h*
// CClockType header file : class declaration
class CClockType{
private:
int hr, mins, sec;
public :
//constructor : declare a way to initialize our member variables
// how to write a constructor (special member function,
// where the function name is the class name and which syntax is similar to member function but
// the constructor need no return specifier
// we can declare diverse constructors
CClockType();
CClockType(int hours, int minutes, int seconds);
//destructor : special member function which can be used to define how to release all members variables
//only one destructor is allowed without parameters and with ~ leading the function name
~CClockType();
void setTime(int , int , int ); //member function prototype
void printTime();
void getTime(int *hours, int *minutes, int *seconds);
void incrementTimeBySeconds();
void incrementTimeByMinutes();
void incrementTimeByHours();
};
*CClockTypeImpl.cpp*
#include "CClockType.h"
#include <iostream>
using namespace std;
/*
void setTime(int hours, int minutes, int seconds);
void setTime2(int hours, int minutes, int seconds);
void getTime(int *hours, int *minutes, int *seconds);
void incrementTimeBySeconds();
void incrementTimeByMinutes();
void incrementTimeByHours(); */
// TODO Define a constructor with no parameter list
CClockType::CClockType() {
hr = 0;
mins = 0;
sec = 0;
}
// TODO Define a constructor with three int parameters for setting up hours, minutes, and seconds
CClockType::CClockType(int hours, int minutes, int seconds) {
setTime(hr, mins, sec);
}
// Define a destructor
CClockType::~CClockType() {
setTime(hr, mins, sec);
}
// Define a member function
// (Here we specify the class which function belongs to so that the member function can use all variables and other functions declared in the class )
// static member function is an exception
// TODO Define the member function named setTime, which need three int parameters, hours, minutes, and seconds and return nothing
void CClockType::setTime(int hours, int minutes, int seconds) {
if (0 <= hours && hours < 24) // hours can not be less than 0 nor bigger than 24
hr = hours; // initialize
else
hr = 0;
if (0 <= minutes && minutes < 60) // minutes can not be less than 0 nor bigger than 60
mins = minutes; // initialize
else
mins = 0;
if (0 <= seconds && seconds < 60) // seconds can not be less than 0 nor bigger than 60
sec = seconds; // initialize
else
sec = 0;
}
/*
TODO Define member function CClockType::getTime
Goal: read out the hours, minutes, and seconds and save them to the outside variables
Inputs: pointers referring to outside variables used to save hours, minutes, and seconds
Output: void
*/
void CClockType::getTime(int *hours, int *minutes, int *seconds) {
*hours = hr;
*minutes = mins;
*seconds = sec;
}
/*
TODO Define member function CClockType::incrementTimeBySeconds
Goal: to adjust time by increasing seconds by 1.
Inputs:
Output: void
*/
void CClockType::incrementTimeBySeconds() {
sec++;
if (sec > 59) {
sec = 0;
incrementTimeByMinutes(); // Increment Minute
}
}
/*
TODO Define member function CClockType::incrementTimeByMinutes
Goal: to adjust time by increasing seconds by 1.
Inputs:
Output: void
*/
void CClockType::incrementTimeByMinutes() {
mins++;
if (mins > 59) {
mins = 0;
incrementTimeByHours(); // Increment Hour
}
}
/*
TODO Define member function CClockType::incrementTimeByHours
Goal: to adjust time by increasing seconds by 1.
Inputs:
Output: void
*/
void CClockType::incrementTimeByHours() {
hr++;
if (hr > 23)
hr = 0;
}
/*
TODO Define member function CClockType::printTime
Goal: to adjust time by increasing seconds by 1.
Inputs:
Output: void
*/
void CClockType::printTime() {
setTime(hr, mins, sec);
cout << hr << ":";
cout << mins << ":";
cout << sec << endl;
}
Error I receive:
Compiler/Debug output:
g++: error: *.cpp: No such file or directory
g++: error: *.h: No such file or directory
g++: fatal error: no input files
compilation terminated.
:g++: error: *.cpp: No such file or directory
g++: error: *.h: No such file or directory
g++: fatal error: no input files
compilation terminated.
The correct output of the test case
0:0:0
10:9:35
10:9:36
12:0:0
Like I mentioned, when I run it in Visual Studios,I get the proper output but when I submit it, it states that it doesn't compile. It doesn't compile in Codeblocks as well. Any help is appreciated! Thank you in advance!

Error C2228 In a Simple Counter Program C++

First time here, so forgive me if I'm not entirely following protocol. I will adjust as is necessary. I'm trying to make a simple program that increments (or decrements) through a counter. The counter's functions are through a class, and I'm trying to use the main for testing for functionality. I could very easily be missing something super simple, as is always the case with me, but I can't figure it out so I figured I'd ask here, since I've come here very often finding help easily. I've tried sifting through answers and nothing has been helping so far. Here's the code:
#include <iostream>
using namespace std;
class counter
{
public:
counter();
counter(int begin, int maximum);
void increment();
void decrement();
int getter();
private:
int count;
int max;
};
// Default constructor.
counter::counter()
{
count = 0;
max = 17;
}
// Constructor that allows you to put in a starting point for the counter
// and a maximum value for the counter.
counter::counter(int begin, int maximum)
{
max = maximum;
if (begin > maximum)
{
cout << "You input an invalid value to begin. Set to default.";
count = 0;
}
else
{
count = begin;
}
}
// Increments counter by one. If counter would exceed max, then goes to 0.
void counter::increment()
{
if (count == max)
{
count = 0;
}
else
{
count++;
}
}
// Decrements counter by one. If counter we go below 0, then goes to max.
void counter::decrement()
{
if (count == 0)
{
count = max;
}
else
{
count--;
}
}
// Getter for counter value.
int counter::getter()
{
return count;
}
int main()
{
counter test();
for (int i = 0; i < 20; i++)
{
test.increment();
cout << test.getter() << "\n";
}
}
The error that's appearing is:
"dsCh2Exercise.cpp(81): error C2228: left of '.increment' must have
class/struct/union dsCh2Exercise.cpp(82): error C2228: left of
'.getter' must have class/struct/union"
Thanks ahead of time for any and all input! It's greatly appreciated!
counter test(); declares a function named test that takes no arguments and returns a counter, not a variable named test that contains a counter. Change that line to:
counter test;

Digital clock c++

Making a digital clock in c++ and I get these errors:
expected ; before reloj
statement is a reference, not call, to funcion 'time'
statement has no effect
''reloj'' is undeclared (first use this function)
Each undeclared identifier is reported only once for each function it appears
#include<iostream>
#include<Windows.h>
using namespace std;
struct time
{
int hr,mint,seg;
};
int main()
{
time reloj;
reloj.hr = 0;
reloj.mint = 0;
reloj.seg = 0;
for(int i = 0; i<24; i++)
{
if(reloj.hr == 23)
{
reloj.hr = 0;
}
for(int j = 0; j<60; j++)
{
if(reloj.mint == 59)
{
reloj.mint = 0;
}
for(int k = 0; k<60; k++)
{
if(reloj.seg == 59)
{
reloj.seg = 0;
}
cout<<reloj.hr<<" : "<<reloj.mint<<" : "<<reloj.seg<<endl;
reloj.seg++;
Sleep(1000);
system("Cls");
}
reloj.mint++;
}
reloj.hr++;
}
}
using namespace std; in the global namespace is a bad idea, and is probably dumping std::time there, along with a host of other names. This will clash with your time class.
Unfortunately, simply removing the evil using isn't a solution here, since time comes from the C library. Implementations are allowed to (and many do) dump names from the C library into the global namespace whether you want them there or not.
So your options are:
Rename your class, or put it in your own namespace;
Refer to it as struct time rather than just time;
Don't include any standard library headers, just in case they mess with your global names.
I have Another codes :
#include <iostream>
#include <unistd.h>
#include <ctime>
using namespace std;
void Timer()
{
int HOUR = 0, MINUTE = 0 , SECOND = 0;
time_t now = time(0);
tm *ltm = localtime(&now);
HOUR = ltm->tm_hour;
MINUTE = ltm->tm_min;
SECOND = ltm->tm_sec;
while(true)
{
system("clear");
cout << HOUR << ":" << MINUTE << ":" << SECOND << endl;
SECOND ++;
if(SECOND == 60)
{
MINUTE++;
SECOND = 0;
if(MINUTE == 60);
{
HOUR++;
MINUTE = 0;
if(HOUR ==24)
{
HOUR = 0;
}
}
}
sleep(1);
}
}
int main()
{
Timer();
}
*IF YOU USE THIS ON WINDOWS THEN CHANGE system("clear") into system("cls")