In an effort to simplify the problem I am having, I have included two classes in foo.mqh and bar.mqh.
When I compile them, I get:
'bar' - wrong parameters count foo.mqh Line 20 Column 9
which is this line in foo.mqh:
foobar(bar & b) { example = b;}
I have read up on other posts that deal with this error, but they don't seem to be object oriented and I can't correllate those instances with this one.
Is it that bar has a default value? .... because of the constructor? Actually that is probably not it because if I put them in the same file I get the same error.
Is there anyway to get around this?
Any help would be appreciated. Thanks
bar.mqh
#property copyright "Copyright 2015, MetaQuotes Software Corp." // 01
#property link "https://www.mql5.com" // 02
#property strict // 03
// 04
class bar{ // 05
private: // 06
int b; // 07
int u; // 08
int g; // 09
public: // 10
bar * operator=(const bar & example) // 11
{ // 12
b = example.b; // 13
u = example.u; // 14
g = example.u; // 15
return GetPointer(this); // 16
} // 17
bar(bar & example) // 18
{ // 19
b = example.b; // 20
u = example.u; // 21
g = example.u; // 22
} // 23
// 24
}; // 25
foo.mqh
#property copyright "Copyright 2015, MetaQuotes Software Corp." // 01
#property link "https://www.mql5.com" // 02
#property strict // 03
// 04
// 05
#include<bar.mqh> // 06
// 07
class foo { // 08
}; // 09
// 10
class foobar: public foo { // 11
private: // 12
bar example; // 13
public: // 14
foobar(bar & b) { example = b;} // 15
bar getExample() { return example; } // 16
}; // 17
The issue was that I did not have a constructor/destructor declaration.
See bar.mqh below:
//+------------------------------------------------------------------+
//| bar.mqh |
//| Copyright 2015, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property strict
class bar{
private:
int b;
int u;
int g;
public:
bar() {}
~bar() {}
bar * operator=(const bar & example)
{
b = example.b;
u = example.u;
g = example.u;
return GetPointer(this);
}
bar(bar & example)
{
b = example.b;
u = example.u;
g = example.u;
}
};
foo.mqh did not have to change.
Related
I have created a markdown file as part of a c++ project intended to describe a specific functionality in the project.
In this markdown file, I have defined a group using '\defgroup myGroup Explanation of group'
I've also tagged all objects related to this group by including the \ingroup tag for the group in question.
The question is on how to render UML diagrams only for the context for this specific group in the detailed section of the module for this functionality?
I have read through the doxygen documentation and have not found any information on how to define the group context boundaries for rendering a specific group of objects/classes using graphviz.
#include <string>
#include <iostream>
/**
* #ingroup markingsgroup
* #brief This class defines a base class
*/
class BaseClass
{
public:
BaseClass() {}
virtual bool getStatus(void) const = 0;
virtual void setStatus(const bool status) = 0;
};
/**
* #ingroup markingsgroup
* This class defines Class1
*/
class Class1 : public BaseClass
{
public:
Class1() {}
bool getStatus() const
{
return m_status;
}
void setStatus(const bool status)
{
m_status = status;
}
private:
bool m_status;
};
/**
* #ingroup markingsgroup
* This class defines a Class2
*/
class Class2 : public BaseClass
{
public:
Class2() {}
bool getStatus() const
{
return m_status;
}
void setStatus(const bool status)
{
m_status = status;
}
private:
bool m_status;
};
/**
* #ingroup markingsgroup
* #brief Main function
*/
int main(int argc, char *argv[])
{
Class1 myClass1;
Class2 myClass2;
myClass1.setStatus(true);
myClass2.setStatus(myClass1.getStatus());
std::cout << "Class1: " << myClass1.getStatus() << " Class2: " << myClass2.getStatus() << std::endl;
}
Doxyfile changes form default:
PROJECT_NAME = "My Project"
PROJECT_NAME = "Marking Project"
OUTPUT_DIRECTORY = /home/fblidner/doxgentest/documentation
EXTRACT_ALL = YES
EXTRACT_PRIVATE = YES
EXTRACT_PACKAGE = YES
EXTRACT_STATIC = YES
EXTRACT_LOCAL_METHODS = YES
INPUT = project
RECURSIVE = YES
GENERATE_XML = YES
XML_PROGRAMLISTING = NO
UML_LOOK = YES
CALLER_GRAPH = YES
PLANTUML_JAR_PATH = /home/fblidner/puppet-manifests/devvm/files/generated/plantuml.jar
MAX_DOT_GRAPH_DEPTH = 10
HAVE_DOT = YES
CALLER_GRAPH = YES
I came across on linker error of c++ cli:
Error LNK2022 metadata operation failed (80131195) : Custom attributes are not consistent: (0x0c00019d). foo.obj 1
Error LNK2022 metadata operation failed (80131195) : Custom attributes are not consistent: (0x0c0001ab). bar.obj 1
What is actually metadata tokens? I have learned obj files via ildasm, but I have no idea what is actually problem. Here is brief content:
foo.obj:
// TypeDef #190 (020000bf)
// -------------------------------------------------------
// TypDefName: FooClass (020000BF)
// Flags : [Public] [SequentialLayout] [Class] [Sealed] [AnsiClass] [BeforeFieldInit] (00100109)
// Extends : 01000017 [TypeRef] System.ValueType
// Layout : Packing:0, Size:12
// CustomAttribute #1 (0c00019c)
// -------------------------------------------------------
// CustomAttribute Type: 0a000006
// CustomAttributeName: System.Runtime.CompilerServices.NativeCppClassAttribute :: instance void .ctor()
// Length: 4
// Value : 01 00 00 00 > <
// ctor args: ()
//
// CustomAttribute #2 (0c00019d)
// -------------------------------------------------------
// CustomAttribute Type: 0a000007
// CustomAttributeName: System.CLSCompliantAttribute :: instance void .ctor(bool)
// Length: 5
// Value : 01 00 00 00 00 > <
// ctor args: ( <can not decode> )
bar.obj
// TypeDef #199 (020000c8)
// -------------------------------------------------------
// TypDefName: FooClass (020000C8)
// Flags : [Public] [SequentialLayout] [Class] [Sealed] [AnsiClass] [BeforeFieldInit] (00100109)
// Extends : 01000016 [TypeRef] System.ValueType
// Layout : Packing:0, Size:12
// CustomAttribute #1 (0c0001aa)
// -------------------------------------------------------
// CustomAttribute Type: 0a000006
// CustomAttributeName: System.Runtime.CompilerServices.NativeCppClassAttribute :: instance void .ctor()
// Length: 4
// Value : 01 00 00 00 > <
// ctor args: ()
//
// CustomAttribute #2 (0c0001ab)
// -------------------------------------------------------
// CustomAttribute Type: 0a000007
// CustomAttributeName: System.CLSCompliantAttribute :: instance void .ctor(bool)
// Length: 5
// Value : 01 00 00 00 00 > <
// ctor args: ( <can not decode> )
All I see, that FooClass extends different ValueTypes (I don't know why). Is there any documentation about that tokens? Is it some kind of pdb information about symbols?
I am translating an Obj-C app to Swift and having trouble dealing with some syntax. I believe I have declared the variable types correctly so I don't know why I'm be getting these errors. Maybe some blocks are located incorrectly inside classes/functions when they should be outside or something. I would love it if you could review my code. I'm new to programming so what may be a clear and explicit explanation to you probably will still be vague for me so please show with examples using existing names.
Thanks
"Unary operator '++' cannot be applied to an operand of type 'Int?'"
and
"Binary operator '<' cannot be applied to an operand of type 'Int? and Float'"
and
"Use of unresolved identifier '=-'"
import UIKit
import Foundation
import AVFoundation
let minFramesForFilterToSettle = 10
enum CurrentState {
case statePaused
case stateSampling
}
class ViewController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate {
let session = AVCaptureSession()
var camera : AVCaptureDevice?
var validFrameCounter: Int = 0
var pulseDetector: PulseDetector!
var filter: Filter!
var currentState = CurrentState.stateSampling // Is this initialized correctly?
override func viewDidLoad() {
super.viewDidLoad()
self.pulseDetector = PulseDetector()
self.filter = Filter()
// TO DO startCameraCapture() // call to un-used function.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
let NZEROS = 10
let NPOLES = 10
class Filter {
var xv = [Float](count: NZEROS + 1, repeatedValue: 0)
var yv = [Float](count: NPOLES + 1, repeatedValue: 0)
func processValue(value: Float) -> Float {
let gain: Float = 1.894427025e+01
xv[0] = xv[1]; xv[1] = xv[2]; xv[2] = xv[3]; xv[3] = xv[4]; xv[4] = xv[5]; xv[5] = xv[6]; xv[6] = xv[7]; xv[7] = xv[8]; xv[8] = xv[9]; xv[9] = xv[10]; xv[10] = value / gain;
yv[0] = yv[1]; yv[1] = yv[2]; yv[2] = yv[3]; yv[3] = yv[4]; yv[4] = yv[5]; yv[5] = yv[6]; yv[6] = yv[7]; yv[7] = yv[8]; yv[8] = yv[9]; yv[9] = yv[10];
yv[10] = (xv[10] - xv[0]) + 5 * (xv[2] - xv[8]) + 10 * (xv[6] - xv[4])
+ ( -0.0000000000 * yv[0]) + ( 0.0357796363 * yv[1])
+ ( -0.1476158522 * yv[2]) + ( 0.3992561394 * yv[3])
+ ( -1.1743136181 * yv[4]) + ( 2.4692165842 * yv[5])
+ ( -3.3820859632 * yv[6]) + ( 3.9628972812 * yv[7])
+ ( -4.3832594900 * yv[8]) + ( 3.2101976096 * yv[9]);
return yv[10];
}
}
let maxPeriod = 1.5 // float?
let minPeriod = 0.1 // float?
let invalidEntry:Double = -11
let maxPeriodsToStore:Int = 20
let averageSize:Float = 20
class PulseDetector {
var upVals: [Float] = [averageSize]
var downVals: [Float] = [averageSize]
var upValIndex: Int?
var downValIndex: Int?
var lastVal: Float?
var periodStart: Float?
var periods: [Double] = []
var periodTimes: [Double] = []
var periodIndex: Int?
var started: Bool?
var freq: Float?
var average: Float?
var wasDown: Bool?
func reset() {
for var i=0; i < maxPeriodsToStore; i++ {
periods[i] = invalidEntry
}
for var i=0; i < averageSize; i++ { // why error when PulseDetector.h said averageSize was an Int?
upVals[i] = invalidEntry
downVals[i] = invalidEntry
}
freq = 0.5
periodIndex = 0
downValIndex = 0
upValIndex = 0
}
func addNewValue(newVal:Float, atTime:Double) -> Float {
// we keep track of the number of values above and below zero
if newVal > 0 {
upVals[upValIndex!] = newVal
upValIndex++
if upValIndex >= averageSize {
upValIndex = 0
}
}
if newVal < 0 {
downVals[downValIndex] =- newVal
downValIndex++
if downValIndex >= averageSize {
downValIndex = 0
}
}
// work out the average value above zero
var count: Float
var total: Float
for var i=0; i < averageSize; i++ {
if upVals[i] != invalidEntry {
count++
total+=upVals[i]
}
}
var averageUp = total/count
// and the average value below zero
count=0;
total=0;
for var i=0; i < averageSize; i++ {
if downVals[i] != invalidEntry {
count++
total+=downVals[i]
}
}
var averageDown = total/count
// is the new value a down value?
if newVal < (-0.5*averageDown) {
wasDown = true
}
// original Objective-C code
PulseDetector.h
#import <Foundation/Foundation.h>
#define MAX_PERIODS_TO_STORE 20 // is this an Int?
#define AVERAGE_SIZE 20 // is this a Float?
#define INVALID_PULSE_PERIOD -1 // done
#interface PulseDetector : NSObject {
float upVals[AVERAGE_SIZE];
float downVals[AVERAGE_SIZE];
int upValIndex;
int downValIndex;
float lastVal;
float periodStart;
double periods[MAX_PERIODS_TO_STORE]; // this is an array!
double periodTimes[MAX_PERIODS_TO_STORE]; // this is an rray !!
int periodIndex;
bool started;
float freq;
float average;
bool wasDown;
}
#property (nonatomic, assign) float periodStart; // var periodStart = float?
-(float) addNewValue:(float) newVal atTime:(double) time; // declaring a method called addNewValue with 2 arguments called atTime and time that returns a float
-(float) getAverage; // declaring a method called getAverage that returns a float
-(void) reset; // declaring a method that returns nothing
#end
PulseDetector.m
#import <QuartzCore/QuartzCore.h>
#import "PulseDetector.h"
#import <vector>
#import <algorithm>
#define MAX_PERIOD 1.5
#define MIN_PERIOD 0.1
#define INVALID_ENTRY -100 // is this a double?
#implementation PulseDetector
#synthesize periodStart;
- (id) init
{
self = [super init];
if (self != nil) {
// set everything to invalid
[self reset];
}
return self;
}
-(void) reset {
for(int i=0; i<MAX_PERIODS_TO_STORE; i++) {
periods[i]=INVALID_ENTRY;
}
for(int i=0; i<AVERAGE_SIZE; i++) {
upVals[i]=INVALID_ENTRY;
downVals[i]=INVALID_ENTRY;
}
freq=0.5;
periodIndex=0;
downValIndex=0;
upValIndex=0;
}
-(float) addNewValue:(float) newVal atTime:(double) time {
// we keep track of the number of values above and below zero
if(newVal>0) {
upVals[upValIndex]=newVal;
upValIndex++;
if(upValIndex>=AVERAGE_SIZE) {
upValIndex=0;
}
}
if(newVal<0) {
downVals[downValIndex]=-newVal;
downValIndex++;
if(downValIndex>=AVERAGE_SIZE) {
downValIndex=0;
}
}
// work out the average value above zero
float count=0;
float total=0;
for(int i=0; i<AVERAGE_SIZE; i++) {
if(upVals[i]!=INVALID_ENTRY) {
count++;
total+=upVals[i];
}
}
float averageUp=total/count;
// and the average value below zero
count=0;
total=0;
for(int i=0; i<AVERAGE_SIZE; i++) {
if(downVals[i]!=INVALID_ENTRY) {
count++;
total+=downVals[i];
}
}
float averageDown=total/count;
// is the new value a down value?
if(newVal<-0.5*averageDown) {
wasDown=true;
}
// is the new value an up value and were we previously in the down state?
if(newVal>=0.5*averageUp && wasDown) {
wasDown=false;
// work out the difference between now and the last time this happenned
if(time-periodStart<MAX_PERIOD && time-periodStart>MIN_PERIOD) {
periods[periodIndex]=time-periodStart;
periodTimes[periodIndex]=time;
periodIndex++;
if(periodIndex>=MAX_PERIODS_TO_STORE) {
periodIndex=0;
}
}
// track when the transition happened
periodStart=time;
}
// return up or down
if(newVal<-0.5*averageDown) {
return -1;
} else if(newVal>0.5*averageUp) {
return 1;
}
return 0;
}
-(float) getAverage {
double time=CACurrentMediaTime();
double total=0;
double count=0;
for(int i=0; i<MAX_PERIODS_TO_STORE; i++) {
// only use upto 10 seconds worth of data
if(periods[i]!=INVALID_ENTRY && time-periodTimes[i]<10) {
count++;
total+=periods[i];
}
}
// do we have enough values?
if(count>2) {
return total/count;
}
return INVALID_PULSE_PERIOD;
}
#end
Your problem is that you didn't copied the defines:
#define MAX_PERIODS_TO_STORE 20 // is this an Int?
#define AVERAGE_SIZE 20 // is this a Float?
#define INVALID_PULSE_PERIOD -1 // done
You have to change your defines so they work in your Swift code.
Check this answer how to replace the Objective-C #define to make Swift-Workable.
Also you could just change the defines to variables and initialize your variables with them.
First, a bit on optionals. Variables that end with a '?' are Optional, meaning that they are allowed to be nil (basically not exist). The compiler will not know at compile time whether this variable exists or not, because you are allowed to set it to nil.
"Unary operator '++' cannot be applied to an operand of type 'Int?'"
You seem to have read that last word as Int, but it is Int? which is significant. Basically, since it is an optional (as indicated by the question mark), the compiler knows it can be nil. You cannot use ++ on nil, and since optionals can be nil, you cannot use ++ on optionals. You must forcibly unwrap it first:
downValIndex!++ //note the exclamation point for unwrapping
"Use of unresolved identifier '=-'"
=- isnt a thing. -= is a thing. So
downVals[downValIndex] -= newVal
downVals[downValIndex] = downVals[downValIndex]-newVal //equivalent to above
"Binary operator '>=' cannot be applied to an operand of type 'Int? and Float'"
The compiler thinks you have an optional int on the left of the < and a Float on the right. Assuming you want two Ints, you must unwrap the left and make sure the right is cast to be an int (something like this). If you want two floats instead, cast or define as floats instead of ints.
if downValIndex! >= averageSize as! Int { //casting to Int
You should just be defining averageSize as an int though
var averageSize:Int = 10 //or whatever number
Also, you have lots of optionals. If any of them can be defined to something at compile time, it will make your life easier as you won't need to unwrap them everywhere. Alternately you could implicitly unwrap them (only do this if you are absolutely sure they will never be nil).
var implicitlyUnwrappedOptional:Int!
I keep receiving these errors when I run the compiler:
Program04.cpp:21:14: error: variable or field âgetDataâ declared void
Program04.cpp:21:14: error: âStudentTypeâ was not declared in this scope
Program04.cpp:21:26: error: expected primary-expression before â]â token
Program04.cpp:21:29: error: expected primary-expression before âintâ
Program04.cpp:23:15: error: variable or field âsortDataâ declared void
Program04.cpp:23:15: error: âStudentTypeâ was not declared in this scope
Program04.cpp:23:27: error: expected primary-expression before â]â token
Program04.cpp:23:30: error: expected primary-expression before âintâ
Program04.cpp:27:22: error: variable or field âcomputeAveragesâ declared void
Program04.cpp:27:22: error: âStudentTypeâ was not declared in this scope
Program04.cpp:27:34: error: expected primary-expression before â]â token
Program04.cpp:27:37: error: expected primary-expression before âintâ
Program04.cpp:29:16: error: variable or field âprintDataâ declared void
Program04.cpp:29:16: error: âStudentTypeâ was not declared in this scope
Program04.cpp:29:28: error: expected primary-expression before â]â token
Program04.cpp:29:31: error: expected primary-expression before âintâ
Program04.cpp: In function âint main()â:
Program04.cpp:34:1: error: âStudentTypeâ was not declared in this scope
Program04.cpp:34:13: error: expected â;â before âstudentsâ
Program04.cpp:37:9: error: âstudentsâ was not declared in this scope
Program04.cpp:37:19: error: ânâ was not declared in this scope
Program04.cpp:37:20: error: âgetDataâ was not declared in this scope
Program04.cpp:38:21: error: âsortDataâ was not declared in this scope
Program04.cpp:39:25: error: âcomputeAveragesâ was not declared in this scope
Program04.cpp:40:19: error: âprintDataâ was not declared in this scope
Program04.cpp: At global scope:
Program04.cpp:45:14: error: variable or field âgetDataâ declared void
Program04.cpp:45:14: error: âStudentTypeâ was not declared in this scope
Program04.cpp:45:38: error: expected primary-expression before âintâ
Everything looks good to me, so i'm obviously not understanding something.
Any suggestions?
PROGRAM FILE
using namespace std;
#include "StudentType.h"
#include <iostream>
#include <iomanip>
#include <fstream>
#include <climits>
#include <string>
const int MAX_STDS = 20;
void getData(StudentType[], int&);
void sortData(StudentType[], int&);
void getFormat(string&);
void computeAverages(StudentType[], int&);
void printData(StudentType[], int&);
int main () {
StudentType students[MAX_STDS];
StudentType();
getData(students, n);
sortData(students, n);
computeAverages(students);
printData(students);
return 0;
}
void getData(StudentType students[], int n){
ifstream fin;
int grade;
string filename, name;
bool done = false;
cout << "Enter filename: ";
cin >> filename;
fin.open(filename.c_str());
while(true) {
try {
fin.open(filename.c_str());
if(!fin) {
throw(string("Could not open " + filename + "."));
}
break;
}
catch (string s) {
cout << s << endl;
cout << "Enter a different file name: ";
cin >> filename;
}
}
n=0;
while(n<MAX_STDS && getline(fin, name)) {
students[n].setName(getFormat(name));
for(int i = 0; i < NUM_GRDS; ++i) {
fin >> grade;
student[n].setGrade(grade, i);
}
getline(fin, name);
++n;
}
}
void printData(StudentType students[], int n) {
for(int i = 0; i < n; ++i) {
students[i].printLine();
}
}
void computeAverages(StudentType students[], int n) {
for(int i = 0; i < n; ++i) {
students[i].computeAverage();
}
}
void sortData(StudentType students[], int n) {
for(int i=0; i<n-1; i++) {
for(int j=0; j < n-1-i; ++j) {
if(students[j].getName() > students[j+1].getName()) {
swap(students[j], students[j+1]);
}
}
}
}
void getFormat(string& name) {
string first;
string middle;
string last;
char n, m;
int size = 0;
n = name.find(' ');
first = name.substr(0, n);
m = name.find(' ', n + 1);
size = name.size();
if (m != string::npos) {
middle = name.substr(n+1, m-(n+1));
last = name.substr(m+1, size - (m+1));
}
else {
middle = "";
last = name.substr(n + 1, size - (n + 1));
}
name = last + ", " + first;
if (middle != "") {
name = (name + ' ') + middle[0];
}
}
HEADER FILE
#ifdef STUDENTTYPE__H
#define STUDENTTYPE__H
#include <string>
#include<iostream>
const int NUM_GRDS = 10;
class StudentType {
public:
StudentType();
void setName(std::string);
void setGrade(int, int);
void computeAverage();
std::string getName() const;
void print(std::ostream& = std::cout) const;
private:
std::string name;
int grades[NUM_GRDS];
float avg;
};
#endif
IMPLEMENTATION FILE
#include "StudentType.h"
#include <iomanip>
StudentType::StudentType(){
name = "";
for(int i =0; i <NUM_GRDS; ++i){
grades[i] = 0;
}
avg = 0.0;
}
void StudentType::setName(std::string newName){
name = newName;
}
void StudentType::setGrade(int grade, int num){
grades[num] = grade;
}
void StudentType::computeAverage(){
float total = 0;
for(int i = 0; i<NUM_GRDS; ++i){
total += grades[i];
}
avg = total/NUM_GRDS;
}
std::string StudentType::getName() const{
return name;
}
void StudentType::printLine(std::ostream& out) const {
out.setf(std::left);
out.setf(std::fixed);
out.setf(std::showpoint);
out << "\n" << setw(25) << "Student" << setw(50) << "Grades" << setw(10) << "Average" << endl;
out << "_____________________________________________________________________________________" << endl;
out << std::left << std::setw(25) << name << std::right << ' ';
for(int i = 0; i < NUM_GRDS; ++i){
out << std::setw(5) << grades[i] << ' ';
}
out << setprecision(2) << std::setw(6) << avg << endl;
}
My output should look like this after the program compiles...
Enter file name: grades.dat
Student Grades Average
________________________________________________________________________________________
Last, First 90 80 70 60 50 40 30 20 10 0 45.00
Last, First 40 40 40 40 40 40 40 40 40 40 40.00
Last, First 54 98 65 32 21 87 54 65 98 32 60.60
Flames, Blood A 9 8 7 6 5 4 3 2 1 0 4.50
Bottoms, Car 32 65 98 87 54 24 56 89 78 68 65.10
Guitars, Dean 10 10 10 10 10 10 10 10 10 10 10.00
Honer, Ruth T 78 56 12 23 45 89 31 64 97 79 57.40
Hot, Zepher R 12 54 87 89 56 32 51 46 97 31 55.50
.
.
.
The input file should have this format and include over 20 students for testing purposes:
g0, g1,...g9 should be 10 grades ranging from 0 to 100
First Middle Last
g0 g1 g2 g3 g4 g5 g6 g7 g8 g9
First Last
g0 g1 g2 g3 g4 g5 g6 g7 g8 g9
Change
#ifdef STUDENTTYPE__H
to
#ifndef STUDENTTYPE__H
then you have proper double-inclusion guard
(quite a common typo I must say)
From taking a sharp look at your files, i spotted 2 main errors:
your include guard in the header file is messed up:
#ifdef STUDENTTYPE__H
#define STUDENTTYPE__H
you probably want:
#ifndef STUDENTTYPE__H
#define STUDENTTYPE__H
Also, in the program file:
void getData(StudentType[], int&);
does not match the implementation
void getData(StudentType students[], int n){
as it should be
void getData(StudentType students[], int& n){
which is also true for the other methods.
Also, i am not sure whether stackoverflow is the correct place for you, as you do not have a specific question but just seem to "debug" all your errors here. Maybe start with some c++ tutorials and try to use the error messages of the compiler to trace down all errors.
I need to know the network interface name of the currently connected network interface, as in en0, lo0 and so on.
Is there a Cocoa/Foundation function that is going to give me this information?
You can cycle through network interfaces and get their names, IP addresses, etc.
#include <ifaddrs.h>
// you may need to include other headers
struct ifaddrs* interfaces = NULL;
struct ifaddrs* temp_addr = NULL;
// retrieve the current interfaces - returns 0 on success
NSInteger success = getifaddrs(&interfaces);
if (success == 0)
{
// Loop through linked list of interfaces
temp_addr = interfaces;
while (temp_addr != NULL)
{
if (temp_addr->ifa_addr->sa_family == AF_INET) // internetwork only
{
NSString* name = [NSString stringWithUTF8String:temp_addr->ifa_name];
NSString* address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
NSLog(#"interface name: %#; address: %#", name, address);
}
temp_addr = temp_addr->ifa_next;
}
}
// Free memory
freeifaddrs(interfaces);
There are many other flags and data in the above structures, I hope you will find what you are looking for.
Since iOS works slightly differently to OSX, we had luck using the following code based on Davyd's answer to see the names of all available network interfaces on an iPhone: (also see here for full documentation on ifaddrs)
#include <ifaddrs.h>
struct ifaddrs* interfaces = NULL;
struct ifaddrs* temp_addr = NULL;
// retrieve the current interfaces - returns 0 on success
NSInteger success = getifaddrs(&interfaces);
if (success == 0)
{
// Loop through linked list of interfaces
temp_addr = interfaces;
while (temp_addr != NULL)
{
NSString* name = [NSString stringWithUTF8String:temp_addr->ifa_name];
NSLog(#"interface name: %#", name);
temp_addr = temp_addr->ifa_next;
}
}
// Free memory
freeifaddrs(interfaces);
Alternatively you can also utilize if_indextoname() to get available interface names. Here is how Swift implementation would look like:
public func interfaceNames() -> [String] {
let MAX_INTERFACES = 128;
var interfaceNames = [String]()
let interfaceNamePtr = UnsafeMutablePointer<Int8>.alloc(Int(IF_NAMESIZE))
for interfaceIndex in 1...MAX_INTERFACES {
if (if_indextoname(UInt32(interfaceIndex), interfaceNamePtr) != nil){
if let interfaceName = String.fromCString(interfaceNamePtr) {
interfaceNames.append(interfaceName)
}
} else {
break
}
}
interfaceNamePtr.dealloc(Int(IF_NAMESIZE))
return interfaceNames
}
Ported the sample code of #ambientlight to iOS 13:
public func interfaceNames() -> [String] {
let MAX_INTERFACES = 128;
var interfaceNames = [String]()
let interfaceNamePtr = UnsafeMutablePointer<Int8>.allocate(capacity: Int(Int(IF_NAMESIZE)))
for interfaceIndex in 1...MAX_INTERFACES {
if (if_indextoname(UInt32(interfaceIndex), interfaceNamePtr) != nil){
let interfaceName = String(cString: interfaceNamePtr)
interfaceNames.append(interfaceName)
} else {
break
}
}
interfaceNamePtr.deallocate()
return interfaceNames
}
Most likely leaking memory - Use with caution.
Output:
▿ 20 elements
- 0 : "lo0"
- 1 : "pdp_ip0"
- 2 : "pdp_ip1"
- 3 : "pdp_ip2"
- 4 : "pdp_ip3"
- 5 : "pdp_ip5"
- 6 : "pdp_ip4"
- 7 : "pdp_ip6"
- 8 : "pdp_ip7"
- 9 : "ap1"
- 10 : "en0"
- 11 : "en1"
- 12 : "en2"
- 13 : "ipsec0"
- 14 : "ipsec1"
- 15 : "ipsec2"
- 16 : "ipsec3"
- 17 : "awdl0"
- 18 : "utun0"
- 19 : "utun1"