Linked List Help!! (Now have 23 errors with code)

Pages: 123
Hello Lacy9265,

Remove the "template" from the class and functions then replace all the "T"s with proper data types and you can split the files.

There is another way to split "template" code into 2 files, but in the end it is still 1 file. Not what you want.

Andy

Edit:
Last edited on
Hello Lacy9265,

One other point.

In your 1st post you need to include the full instructions for the program so everyone will know what is to be done.

Without these instructions you are open to whatever someone feels to be the best way to write the program even if you can not use it.

Keep this in mind for the future.

Andy
@Handy Andy

Doing what you said caused me to have 45 errors with my code. Could anyone show me how I do what @Handy Andy said. I don't understand why I have 45 errors between the list.h and list.cpp file? Thank you.
For my code I must use file list.cpp and list.h. I cannot combine list.cpp and list.h into one file. I do I take what see plus has for the link.hpp file but make it two separate file called link.h and link.cpp


List is a templated class - it will work for any data. List doesn't need - nor should know - anything about the stored data. You can't split this into .h and .cpp files like you can with rainfall. As list is a container to be used like any other container such as std::string, neither would you want to. If you want to use std::string in a program you just #include <string>. You don't also have to add say string.cpp to your solution as well. The same with List.

This teaching of always splitting into .h and .cpp files is not appropriate in every case.

Well has I mentioned before I must use certain files for my code including link.cpp and link.h. I CANNOT combine what’s on link.h and link.cpp into one file. Could someone please show me how I can do it separately without using template or “T” as the data type like @seeplus did.
Hello Lacy9265,

Sorry I did not see your posts until this morning.

Like I said to avoid a total rewrite of your program, no matter how much better it is, you need to post the full instructions for your assignment.

I was at the point where I had your original code working to add to the linked list and printing it out. It is still good code that can work, but need some rework because I eventually noticed that the "Rainfall" class was not being used properly or at all. You do not have to use seeplus's code in full, but it does give you some ideas of what you need to do.

Like adding the function "~List()" to the "List.cpp" file. Using "new" to create a node must have a "delete" to free the memory before the program ends.

This eluded me because I do not use linked list as much as I use to.

If you want to go back to your original code we can figure it out or you could wait for seeplus to figure out that you need 5 files and rewrite his code to match.

Andy
As I'm feeling in good mood - here's my previous code de-templated and split as your professor unnecessarily wants:

List.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#pragma once

#include <iostream>

struct Data {
	int month {};
	int rain {};
};

class List {
private:
	struct node {
		node(const Data& d) : data(d) {}
		Data data {};		// Store the data of each node
		node* next {};	// Will point to the next node in the list
	};

	using nodePtr = node*;

	nodePtr head {};	// head of node

public:
	List() {}
	~List();
	List(const List&) = delete;
	List& operator=(const List&) = delete;
	void addNode(const Data& addData);
	void deleteNode(const Data& delData);
	void printList() const;
	const nodePtr getHead() const { return head; }
	nodePtr find(const Data& d);
};

std::ostream& operator<<(std::ostream& os, const Data& d);
bool operator==(const Data& d, int m);
bool operator!=(const Data& d1, const Data& d2);
bool operator==(const Data& d1, const Data& d2);


List.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include <iostream>
#include <iomanip>
#include "List.h"

std::ostream& operator<<(std::ostream& os, const Data& d)
{
	return os << std::setw(3) << d.month << "  " << std::setw(4) << d.rain;
}

bool operator==(const Data& d, int m) {
	return d.month == m;
}

bool operator==(const Data& d1, const Data& d2) {
	return d1.month == d2.month && d1.rain == d2.rain;
}

bool operator!=(const Data& d1, const Data& d2) {
	return !(d1 == d2);
}

List::~List() {
	while (head) {
		const auto curr {head};

		head = head->next;
		delete curr;
	}
}

List::nodePtr List::find(const Data& d) {
	for (auto curr = head; curr; curr = curr->next)
		if (curr->data == d)
			return curr;

	return nullptr;
}

void List::addNode(const Data& addData) {
	const auto n {new node(addData)};	// node pointer equals new node

	if (head) {
		auto curr {head};

		for (; curr->next; curr = curr->next);
		curr->next = n;
	} else
		head = n;
}

void List::deleteNode(const Data& delData) {
	auto temp {head};
	auto curr {head};

	while (curr && curr->data != delData) {
		temp = curr;
		curr = curr->next;
	}

	if (curr == nullptr)
		std::cout << delData << " was not in the list\n";
	else {
		auto delPtr {curr};

		curr = curr->next;
		temp->next = curr;

		if (delPtr == head)
			head = curr;

		//std::cout << "The value " << delData << "was deleted\n";
		delete delPtr;
	}
}

void List::printList() const {
	for (auto curr = head; curr; curr = curr->next)
		std::cout << curr->data << '\n';
}


rainfall.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#pragma once

#include <iostream>
#include <iomanip>
#include "list.h"

class RainFall {
public:
	RainFall() {}

	int getHighestRainfall() const;
	int getLowestRainfall() const;
	int getTotalRainfall() const;
	void appendNode(const Data& num);
	void displayList() const;

	auto find(int m) {
		auto curr {rlist.getHead()};

		for (; curr; curr = curr->next)
			if (curr->data.month == m)
				return curr;

		return (decltype(curr)) nullptr;
	}

	void remove(const Data& d) {
		rlist.deleteNode(d);
	}

private:
	List rlist;
};


rainfall.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
#include <iomanip>
#include "list.h"
#include "rainfall.h"

int RainFall::getLowestRainfall() const
{
	int lowrain {9999};

	for (auto nodePtr = rlist.getHead(); nodePtr; nodePtr = nodePtr->next)
		if (nodePtr->data.rain < lowrain)
			lowrain = nodePtr->data.rain;

	return lowrain;
}

int RainFall::getHighestRainfall() const
{
	int highrain {-9999};

	for (auto nodePtr = rlist.getHead(); nodePtr; nodePtr = nodePtr->next)
		if (nodePtr->data.rain > highrain)
			highrain = nodePtr->data.rain;

	return highrain;
}

int RainFall::getTotalRainfall() const
{
	int total {};

	for (auto nodePtr = rlist.getHead(); nodePtr; nodePtr = nodePtr->next)
		total += nodePtr->data.rain;

	return total;
}

void RainFall::appendNode(const Data& num)
{
	rlist.addNode(num);
}

void RainFall::displayList() const
{
	std::cout << std::left << "Mon" << "  Rain\n";

	for (auto nodePtr = rlist.getHead(); nodePtr; nodePtr = nodePtr->next)
		std::cout << std::right << nodePtr->data << '\n';
}


driver.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <iostream>
#include "rainfall.h"

int main() {
	char userAnswer {};
	RainFall rf;

	do {
		std::cout << "\nA--Add a month of statistics\n"
			<< "R--Remove a month of statistics\n"
			<< "E--Edit a month of statistics\n"
			<< "P--Print report\n"
			<< "D--Display details\n"
			<< "Q--Quit\n"
			<< "\nChoice: ";

		std::cin >> userAnswer;

		switch (userAnswer) {
			case 'A':
			case 'a':
			{
				Data rd;

				std::cout << "Enter month: ";
				std::cin >> rd.month;

				std::cout << "Enter rainfall: ";
				std::cin >> rd.rain;

				rf.appendNode(rd);
			}
			break;

			case 'E':
			case 'e':
			{
				int m {};

				std::cout << "Enter month: ";
				std::cin >> m;

				if (const auto f {rf.find(m)}; f != nullptr) {
					std::cout << "Current rainfall value is " << f->data.rain << '\n';
					std::cout << "Enter new rainfall: ";
					std::cin >> f->data.rain;
				} else
					std::cout << "Month not found\n";
			}
			break;

			case 'R':
			case 'r':
			{
				int m {};

				std::cout << "Enter month: ";
				std::cin >> m;

				if (const auto f {rf.find(m)}; f != nullptr)
					rf.remove(f->data);
				else
					std::cout << "Month not found\n";
			}
			break;

			case 'D':
			case 'd':
				rf.displayList();
				break;

			case 'P':
			case 'p':
				std::cout << "\nLow rain is " << rf.getLowestRainfall() << '\n';
				std::cout << "High rain is " << rf.getHighestRainfall() << '\n';
				std::cout << "Total rain is " << rf.getTotalRainfall() << '\n';
				break;

			case 'Q':
			case 'q':
				break;

		}
	} while (userAnswer != 'q' && userAnswer != 'Q');
}


Have fun!
Last edited on
PS You could also split this into 7 files. The code in List.h/List.cpp that just deals with the Data type could be split off into Data.h and Data.cpp!
@seeplus have you ran this new code you have provided. When I run this code I get about 23 errors.
Last edited on
Yes. It compiled and ran OK with VS2019 on my system. I just copied/pasted the various files from the IDE windows.

You have got the 3 .cpp files specified as part of the solution Source Files?
Last edited on
Yes I have the list.ccp, driver.cpp, and rainfall.cpp in the source file. Okay was able to get it down to 15 errors did not have #pragma once in list.h and rainfall.h
Last edited on
This is the code split over the 7 files!

Data.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#pragma once

#include <iostream>

struct Data {
	int month {};
	int rain {};
};

std::ostream& operator<<(std::ostream& os, const Data& d);
bool operator==(const Data& d, int m);
bool operator!=(const Data& d1, const Data& d2);
bool operator==(const Data& d1, const Data& d2);


Data.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <iomanip>
#include "Data.h"

std::ostream& operator<<(std::ostream& os, const Data& d)
{
	return os << std::setw(3) << d.month << "  " << std::setw(4) << d.rain;
}

bool operator==(const Data& d, int m) {
	return d.month == m;
}

bool operator==(const Data& d1, const Data& d2) {
	return d1.month == d2.month && d1.rain == d2.rain;
}

bool operator!=(const Data& d1, const Data& d2) {
	return !(d1 == d2);
}


List.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#pragma once

#include <iostream>
#include "Data.h"

class List {
private:
	struct node {
		node(const Data& d) : data(d) {}
		Data data {};		// Store the data of each node
		node* next {};	// Will point to the next node in the list
	};

	using nodePtr = node*;

	nodePtr head {};	// head of node

public:
	List() {}
	~List();
	List(const List&) = delete;
	List& operator=(const List&) = delete;
	void addNode(const Data& addData);
	void deleteNode(const Data& delData);
	void printList() const;
	const nodePtr getHead() const { return head; }
	nodePtr find(const Data& d);
};


List.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <iostream>
#include <iomanip>
#include "List.h"

List::~List() {
	while (head) {
		const auto curr {head};

		head = head->next;
		delete curr;
	}
}

List::nodePtr List::find(const Data& d) {
	for (auto curr = head; curr; curr = curr->next)
		if (curr->data == d)
			return curr;

	return nullptr;
}

void List::addNode(const Data& addData) {
	const auto n {new node(addData)};	// node pointer equals new node

	if (head) {
		auto curr {head};

		for (; curr->next; curr = curr->next);
		curr->next = n;
	} else
		head = n;
}

void List::deleteNode(const Data& delData) {
	auto temp {head};
	auto curr {head};

	while (curr && curr->data != delData) {
		temp = curr;
		curr = curr->next;
	}

	if (curr == nullptr)
		std::cout << delData << " was not in the list\n";
	else {
		auto delPtr {curr};

		curr = curr->next;
		temp->next = curr;

		if (delPtr == head)
			head = curr;

		//std::cout << "The value " << delData << "was deleted\n";
		delete delPtr;
	}
}

void List::printList() const {
	for (auto curr = head; curr; curr = curr->next)
		std::cout << curr->data << '\n';
}


rainfall.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#pragma once

#include <iostream>
#include <iomanip>
#include "list.h"

class RainFall {
public:
	RainFall() {}

	int getHighestRainfall() const;
	int getLowestRainfall() const;
	int getTotalRainfall() const;
	void appendNode(const Data& num);
	void displayList() const;

	auto find(int m) {
		auto curr {rlist.getHead()};

		for (; curr; curr = curr->next)
			if (curr->data.month == m)
				return curr;

		return (decltype(curr)) nullptr;
	}

	void remove(const Data& d) {
		rlist.deleteNode(d);
	}

private:
	List rlist;
};


rainfall.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
#include <iomanip>
#include "list.h"
#include "rainfall.h"

int RainFall::getLowestRainfall() const
{
	int lowrain {9999};

	for (auto nodePtr = rlist.getHead(); nodePtr; nodePtr = nodePtr->next)
		if (nodePtr->data.rain < lowrain)
			lowrain = nodePtr->data.rain;

	return lowrain;
}

int RainFall::getHighestRainfall() const
{
	int highrain {-9999};

	for (auto nodePtr = rlist.getHead(); nodePtr; nodePtr = nodePtr->next)
		if (nodePtr->data.rain > highrain)
			highrain = nodePtr->data.rain;

	return highrain;
}

int RainFall::getTotalRainfall() const
{
	int total {};

	for (auto nodePtr = rlist.getHead(); nodePtr; nodePtr = nodePtr->next)
		total += nodePtr->data.rain;

	return total;
}

void RainFall::appendNode(const Data& num)
{
	rlist.addNode(num);
}

void RainFall::displayList() const
{
	std::cout << std::left << "Mon" << "  Rain\n";

	for (auto nodePtr = rlist.getHead(); nodePtr; nodePtr = nodePtr->next)
		std::cout << std::right << nodePtr->data << '\n';
}


driver.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <iostream>
#include "rainfall.h"

int main() {
	char userAnswer {};
	RainFall rf;

	do {
		std::cout << "\nA--Add a month of statistics\n"
			<< "R--Remove a month of statistics\n"
			<< "E--Edit a month of statistics\n"
			<< "P--Print report\n"
			<< "D--Display details\n"
			<< "Q--Quit\n"
			<< "\nChoice: ";

		std::cin >> userAnswer;

		switch (userAnswer) {
			case 'A':
			case 'a':
			{
				Data rd;

				std::cout << "Enter month: ";
				std::cin >> rd.month;

				std::cout << "Enter rainfall: ";
				std::cin >> rd.rain;

				rf.appendNode(rd);
			}
			break;

			case 'E':
			case 'e':
			{
				int m {};

				std::cout << "Enter month: ";
				std::cin >> m;

				if (const auto f {rf.find(m)}; f != nullptr) {
					std::cout << "Current rainfall value is " << f->data.rain << '\n';
					std::cout << "Enter new rainfall: ";
					std::cin >> f->data.rain;
				} else
					std::cout << "Month not found\n";
			}
			break;

			case 'R':
			case 'r':
			{
				int m {};

				std::cout << "Enter month: ";
				std::cin >> m;

				if (const auto f {rf.find(m)}; f != nullptr)
					rf.remove(f->data);
				else
					std::cout << "Month not found\n";
			}
			break;

			case 'D':
			case 'd':
				rf.displayList();
				break;

			case 'P':
			case 'p':
				std::cout << "\nLow rain is " << rf.getLowestRainfall() << '\n';
				std::cout << "High rain is " << rf.getHighestRainfall() << '\n';
				std::cout << "Total rain is " << rf.getTotalRainfall() << '\n';
				break;

			case 'Q':
			case 'q':
				break;

		}
	} while (userAnswer != 'q' && userAnswer != 'Q');
}


You should have the 4 .cpp files as part of the solution Source Files.

This compiles, links and runs OK with VS2019.
Last edited on
Was able to run the code without any errors. I not having an issue where I enter A then enter the month the options keep looping over and over.
where I enter A then enter the month the options keep looping over and over.


From my system:



A--Add a month of statistics
R--Remove a month of statistics
E--Edit a month of statistics
P--Print report
D--Display details
Q--Quit

Choice: a
Enter month: 1
Enter rainfall: 1

A--Add a month of statistics
R--Remove a month of statistics
E--Edit a month of statistics
P--Print report
D--Display details
Q--Quit

Choice: a
Enter month: 2
Enter rainfall: 2

A--Add a month of statistics
R--Remove a month of statistics
E--Edit a month of statistics
P--Print report
D--Display details
Q--Quit

Choice: a
Enter month: 3
Enter rainfall: 3

A--Add a month of statistics
R--Remove a month of statistics
E--Edit a month of statistics
P--Print report
D--Display details
Q--Quit

Choice: d
Mon  Rain
  1     1
  2     2
  3     3

A--Add a month of statistics
R--Remove a month of statistics
E--Edit a month of statistics
P--Print report
D--Display details
Q--Quit

Choice: p

Low rain is 1
High rain is 3
Total rain is 6

A--Add a month of statistics
R--Remove a month of statistics
E--Edit a month of statistics
P--Print report
D--Display details
Q--Quit

Choice: q

For my code I'm not using R or D for the options. I don't know If I have a bracket out of place which is making it to loop the options menu over and over again. Here is my code for the driver.cpp file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <iostream>
#include <string>
#include "List.h"
#include "Rainfall.h"



int main() {
	char userAnswer{};
	Rainfall rf;

	do {
		std::cout << "\nA--Add a month of statistics\n"
			<< "E--Edit a month of statistics\n"
			<< "P--Print report\n"
			<< "Q--Quit\n"
			<< "Choice: ";

		std::cin >> userAnswer;

		switch (userAnswer) {
		case 'A':
		case 'a':
		{
			Data rd;

			std::cout << "Enter month: ";
			std::cin >> rd.month;

			std::cout << "Enter rainfall (in Inches): ";
			std::cin >> rd.rain;

			rf.appendNode(rd);
		}
		break;

		case 'E':
		case 'e':
		{
			int m{};

			std::cout << "Enter month: ";
			std::cin >> m;

			if (const auto f{ rf.find(m) }; f != nullptr) {
				std::cout << "Enter new rainfall (in Inches): ";
				std::cin >> f->data.rain;
			}
			else
				std::cout << "ERROR: Invalid Month\n";
		}
		break;

		
		case 'P':
		case 'p':
			std::cout << "Total rainfall: " << rf.getTotalRainfall() << " inches\n";
			std::cout << "Average rainfall: " << rf.getAverageRainfall() << " inches\n";
			std::cout << "Highest rainfall: " << rf.getHighestRainfall() << " inches\n";
			std::cout << "Lowest rainfall: " << rf.getLowestRainfall() << " inches\n";
			
			
			break;

		case 'Q':
		case 'q':
			break;

		}
	} while (userAnswer != 'q' && userAnswer != 'Q');
}
The switch could do with a default: case to display an error message (I forget when I coded this - doh!).

The options menu will be looped continuously until the option q or Q is entered. This is by design. Add just adds one value - not multiple values.

There's various extras that could be done with Add. eg. check that the specified month doesn't already exist. If it does, then give option to edit. Allow multiple months data to be entered without returning to the menu to add each separately etc etc etc.

Just my personal preference:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
bool Quit = false;

while(!Quit) {
   switch // ...
   // ...

   case 'q' :
   case 'Q' : {
      Quit  = true;
      break;
   }

   default: {
    // ...
   } 

}// end while 


I just find the condition to be very simple & easy to read.

I personally have never liked this:

} while (userAnswer != 'q' && userAnswer != 'Q');

Anyway, it's my preference - there may be someone else who starts to do that too :+)

Perhaps controversially, I don't use do loops purely because something is to be done at least once, rather if something must be done if it loops once. In other words, just because a do loop always executes at least once, that is not a reason IMO to choose a do loop. The example in K&R IIRC is the placement of '/0' at the end of a C string, even if the string is empty. Because all 3 loops can be converted from one to another, it is not often I find myself using a do loop.

KRCprogramming wrote:
Experience shows that do-while is much less used than while and for . Nonetheless, from
time to time it is valuable, as in the following function itoa , which converts a number to a
character string (the inverse of atoi ). The job is slightly more complicated than might be
thought at first, because the easy methods of generating the digits generate them in the wrong
order. We have chosen to generate the string backwards, then reverse it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* itoa: convert n to characters in s */
void itoa(int n, char s[])
{
int i, sign;
if ((sign = n) < 0) /* record sign */
   n = -n; /* make n positive */
i = 0;

do {  /* generate digits in reverse order */
s[i++] = n % 10 + '0'; /* get next digit */
} while ((n /= 10) > 0);  /* delete it */

if (sign < 0)
   s[i++] = '-';
s[i] = '\0';
reverse(s);
}


The do-while is necessary, or at least convenient, since at least one character must be
installed in the array s , even if n is zero. We also used braces around the single statement that
makes up the body of the do-while , even though they are unnecessary, so the hasty reader
will not mistake the while part for the beginning of a while loop.


I guess a reason for using a do loop is when variables declared inside the body are used in the condition of the do loop.
I guess a reason for using a do loop is when variables declared inside the body are used in the condition of the do loop.


Variables defined inside the body of a do loop can't be used in the condition! Their scope is up-to the do body closing } before the while...

@TheIdeasMan Just my personal preference:

One day I'll code it one way, one day another. Just depends on the phase of the moon or how I'm feeling at the time! I have no major issue with either way. After refactoring the rest of the code, the main menu part was the least of it!

L1 3 could be replaced with a for loop though if doing it this way. :)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
for (bool quit {}; !quit; ) {
    // Display menu
    // Get option
    switch (opt) {
        case 'a':
            break;

       case 'q':
           quit = true;
           break;

       default:
           std::cout << "Invalid option!\n";
           break;
    }
}

Last edited on
seeplus wrote:
Just depends on the phase of the moon or how I'm feeling at the time!


No worries :+) I didn't mean it to come across as criticism, it really is just my preference, others may like it and adopt it for their code, especially if they are a beginner.

It is incumbent on me to mention the reality of where I stand in terms of experience & knowledge: I first taught myself C from K&R in 1988 (no internet, just me & the book!) on a Sparc Station 1* Unix machine, and have a been a hobby programmer since, with some exposure to other languages through university & work. But I gather that you have a degree and have been a developer for more than 3 decades, so your knowledge and experience is vastly superior. So I always look forward to any code & advice you provide to anyone :+)

Variables defined inside the body of a do loop can't be used in the condition! Their scope is up-to the do body closing } before the while...


This just proves that I can screw things up just as well as anyone !!

Thinking about that a bit more, what about a variable declared before the do loop; some calcs are done in the body; then that value is part of the while condition? I guess I am trying to think of other situations where a do loop is justified, I am sure there are plenty of them.

* It was a high end machine in those days: Sun Sparc Station 1, 32 bit, a whopping 8Mb Ram, I don't remember how much disk space, we had a carousel pen plotter, and a quite good CAD system with 20 inch colour screen. The rest of the plebs had DOS 3.0 with 640Kb & 10MB disk, some of the fancy pants had DOS 6.0 with 1MB ram, although they didn't realise they weren't using all of it because they didn't run HIMEM.SYS !!
Pages: 123