Hi Jim, as shown below
Remember to look at "build log" NOT the "message log" to see the Compiler output in the Code::Blocks IDE/editor.
I suggest making sure full compiler logging is on, also.
FAQ-Compiling (errors) - CodeBlocks
Tim S.
"...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson
Also, do NOT use Build and Run in CB; sometimes its hard to see the build log before its over written by the run log information.
Tim S.
"...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson
Did all that. Enabled all warnings as screen shot above. Did it for both the project and for global. Did it for both the debug and the release. Looking at the build log and all other logs.
No warnings whatsoever.
What is your current code?
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
Pretty much the same as the opening code, here it is again (I havent yet corrected the illogical if statement as you have suggested, still need to do that):
Code:#include <iostream> #include <fstream> #include <stdlib.h> #include <cmath> #include <string> #include <cstring> #define ERROR_LOW_WAGON_WEIGHT 101 #define ERROR_HIGH_WAGON_WEIGHT 102 #define ERROR_HIGH_GRADIENT 103 using namespace std; float ceiling(float unrounded, float increment) { float remainder = fmod (unrounded, increment); int quotient = unrounded/increment; if (remainder == 0) return (unrounded); else if (remainder != 0) return (quotient*increment + increment); } char* tokenizer (string inputstream) { if (inputstream != "NULL") // If parameter is equal to string "NULL", then invoke the strtok function by tokenizing the first token in parameter { char* cstringcpy = (char*)malloc (50 * sizeof(char)); const char* cstr = inputstream.c_str(); strcpy(cstringcpy,cstr); char* wordptr = (char*)malloc (50 * sizeof(char)); wordptr = strtok(cstringcpy,"\t"); return wordptr; } else // Else parameter is equal to string non-"NULL", then invoke the strtok function by tokenizing the second and n'th token in the parameter { char* cstringcpy = (char*)malloc (50 * sizeof(char)); const char* cstr = inputstream.c_str(); strcpy(cstringcpy,cstr); char* wordptr = (char*)malloc (50 * sizeof(char)); wordptr = strtok(NULL,"\t"); return wordptr; } } double slot_capacity_required (double volume_per_month, double tons_per_wagon, double wagons_per_train, double operating_weeks_per_year) { return (volume_per_month/(tons_per_wagon * wagons_per_train)) * 12 / operating_weeks_per_year; } double wagons_required (double slot_capacity_required, double turn_around_time, double wagons_per_train) { return ceiling((slot_capacity_required/(168/turn_around_time))*wagons_per_train, wagons_per_train); } double tons_per_axle (double tons_per_wagon) { return tons_per_wagon/4; } double train_tons_to (double tons_per_wagon, double wagons_per_train, double wagon_weight) { return (tons_per_wagon + wagon_weight) * wagons_per_train; } double train_tons_from (double wagons_per_train, double wagon_weight) { return (wagon_weight) * wagons_per_train; } int locomotives_required (double tons_per_wagon, double train_tons, double gradient) { double tons_per_axle_variable = tons_per_axle(tons_per_wagon); ifstream ifs; ifs.open ("C:\\LoadTables.txt", std::ofstream::out | std::ofstream::app); string lineread = ""; getline (ifs, lineread); char* wordptr = tokenizer(lineread); int locomotive_counter = 0; if (tons_per_axle_variable < atoi(wordptr)) return ERROR_LOW_WAGON_WEIGHT; for (int i = 1; *wordptr != EOF; i++) { wordptr = tokenizer("NULL"); if (tons_per_axle_variable < atof(wordptr)) for (int j = 1; j <= 18; j++) { getline (ifs, lineread); if (gradient == atof(tokenizer(lineread))) for (int k = 0; k <= 6; k++) { if (train_tons <= atof(tokenizer("NULL"))) return locomotive_counter; locomotive_counter++; } } else { getline(ifs,lineread); while (lineread != "") getline(ifs,lineread); getline(ifs,lineread); wordptr = tokenizer(lineread); } } if (*wordptr == EOF); return ERROR_HIGH_WAGON_WEIGHT; } int main () { int output = locomotives_required (55, 2986, 13); cout<< output; return 0; }
EDIT: It seems to show the warnings now i.e. only when I deliberately insert a compiler error like a simple syntax error. Then all warnings show. Otherwise if there are no compiler errors then it wont show anything.
Non-warning changes: - I changed the text file name to ldtbl.txt and used local directory instead of C:\. I added "endl" to the cout in main().
Warning changes: I changed ceiling() to use doubles instead of floats, and cast the division result to (int) to get rid of warnings. At the end of locomotives(), I changed line 126 to remove the trailing semicolon and added a return ERROR_UNKNOWN statement. Code seems to be working.
Code:#include <iostream> #include <fstream> #include <stdlib.h> #include <cmath> #include <string> #include <cstring> #define ERROR_LOW_WAGON_WEIGHT 101 #define ERROR_HIGH_WAGON_WEIGHT 102 #define ERROR_HIGH_GRADIENT 103 #define ERROR_UNKNOWN 104 using namespace std; double ceiling(double unrounded, double increment) { double remainder = fmod (unrounded, increment); int quotient = (int)(unrounded/increment); if (remainder == 0) return (unrounded); return (quotient*increment + increment); } char* tokenizer (string inputstream) { if (inputstream != "NULL") // If parameter is equal to string "NULL", then invoke the strtok function by tokenizing the first token in parameter { char* cstringcpy = (char*)malloc (50 * sizeof(char)); const char* cstr = inputstream.c_str(); strcpy(cstringcpy,cstr); char* wordptr = (char*)malloc (50 * sizeof(char)); wordptr = strtok(cstringcpy,"\t"); return wordptr; } else // Else parameter is equal to string non-"NULL", then invoke the strtok function by tokenizing the second and n'th token in the parameter { char* cstringcpy = (char*)malloc (50 * sizeof(char)); const char* cstr = inputstream.c_str(); strcpy(cstringcpy,cstr); char* wordptr = (char*)malloc (50 * sizeof(char)); wordptr = strtok(NULL,"\t"); return wordptr; } } double slot_capacity_required (double volume_per_month, double tons_per_wagon, double wagons_per_train, double operating_weeks_per_year) { return (volume_per_month/(tons_per_wagon * wagons_per_train)) * 12 / operating_weeks_per_year; } double wagons_required (double slot_capacity_required, double turn_around_time, double wagons_per_train) { return ceiling((slot_capacity_required/(168/turn_around_time))*wagons_per_train, wagons_per_train); } double tons_per_axle (double tons_per_wagon) { return tons_per_wagon/4; } double train_tons_to (double tons_per_wagon, double wagons_per_train, double wagon_weight) { return (tons_per_wagon + wagon_weight) * wagons_per_train; } double train_tons_from (double wagons_per_train, double wagon_weight) { return (wagon_weight) * wagons_per_train; } int locomotives_required (double tons_per_wagon, double train_tons, double gradient) { double tons_per_axle_variable = tons_per_axle(tons_per_wagon); ifstream ifs; ifs.open ("ldtbl.txt", std::ofstream::out | std::ofstream::app); string lineread = ""; getline (ifs, lineread); char* wordptr = tokenizer(lineread); int locomotive_counter = 0; if (tons_per_axle_variable < atoi(wordptr)) return ERROR_LOW_WAGON_WEIGHT; for (int i = 1; *wordptr != NULL; i++) { wordptr = tokenizer("NULL"); if (tons_per_axle_variable < atof(wordptr)) for (int j = 1; j <= 18; j++) { getline (ifs, lineread); if (gradient == atof(tokenizer(lineread))) for (int k = 0; k <= 6; k++) { if (train_tons <= atof(tokenizer("NULL"))) return locomotive_counter; locomotive_counter++; } } else { getline(ifs,lineread); while (lineread != "") getline(ifs,lineread); getline(ifs,lineread); wordptr = tokenizer(lineread); } } if (*wordptr == NULL) // removed semi-colon from this statement return ERROR_HIGH_WAGON_WEIGHT; return ERROR_UNKNOWN; } int main () { int output = locomotives_required (55, 2986, 13); cout << output << endl; return 0; }
Last edited by rcgldr; 01-20-2014 at 11:04 AM.
"...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson
I think you're onto something here and its your last return statement.
Let me explain to everyone if this makes sense.
I cleaned the code up until there were no warnings left or atleast there were some warnings about comparing int to float but that aside, nothing serious. Also I couldnt enable -Wreturn-type and -Wtype- as my compiler couldnt find these warnings. The former warning is the culprit as I will soon show!
Anyways, so I then ran the code as clean as I could using my compilers settings using rcgldr advice (barring his last return statement) and I still got the random return number.
I then added the last rcgldr return statement and voila, the code runs without the funny random number error.
So my question is, nobody has fully explained this error despite all the warnings being cleaned up (APART from -Wreturn-type and -Wtype-limits which I cant seem to get my compiler to enable)
So I have a theory that I would like your thoughts on.
Is the random number generated because all my return statements were embedded in conditional loops? I mean look at the two return statements, theyre both in conditional statements. I also did some reading on the net and a bloke on stack overflow wrote about the -Wreturn-type error as follows:
This then explains why rcgldr's last added return statement works: Its not within a conditional statement.The compiler cannot tell from that code if the function will ever reach the end and still return something.
This also explains why adding a trailing ; after the last if statement and leavingout of the if statement works.Code:return ERROR_HIGH_WAGON_WEIGHT;
Thoughts??
"...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson
Whoops, sorry, see below:
Code:-------------- Build: Debug in b --------------- mingw32-g++.exe -Wall -Wshadow -Winit-self -Wredundant-decls -Wcast-align -Wundef -Wfloat-equal -Winline -Wunreachable-code -Wmissing-declarations -Wmissing-include-dirs -Wswitch-enum -Wswitch-default -Weffc++ -Wmain -pedantic -Wextra -Wall -g -Wshadow -Winit-self -Wredundant-decls -Wcast-align -Wundef -Wfloat-equal -Winline -Wunreachable-code -Wmissing-declarations -Wmissing-include-dirs -Wswitch-enum -Wswitch-default -Weffc++ -Wmain -pedantic-errors -pedantic -Wextra -Wall -g -I"C:\Program Files (x86)\CLIPS\Projects\Libraries\Microsoft" -c "C:\Users\D\Documents\C Code\b\Untitled4.cpp" -o obj\Debug\Untitled4.o C:\Users\D\Documents\C Code\b\Untitled4.cpp: In function 'double ceiling(double, double)': C:\Users\D\Documents\C Code\b\Untitled4.cpp:28: warning: comparing floating point with == or != is unsafe C:\Users\D\Documents\C Code\b\Untitled4.cpp:30: warning: comparing floating point with == or != is unsafe C:\Users\D\Documents\C Code\b\Untitled4.cpp: In function 'int locomotives_required(double, double, double)': C:\Users\D\Documents\C Code\b\Untitled4.cpp:102: warning: comparing floating point with == or != is unsafe C:\Users\D\Documents\C Code\b\Untitled4.cpp:119: error: expected primary-expression before '.' token C:\Users\D\Documents\C Code\b\Untitled4.cpp:121: error: expected unqualified-id before 'if' C:\Users\D\Documents\C Code\b\Untitled4.cpp:121: error: expected ';' before 'if' Process terminated with status 1 (0 minutes, 0 seconds) 3 errors, 3 warnings Build log saved as: file://C:%5cUsers%5cD%5cDocuments%5cC%20Code%5cb%5cb_build_log.html
I did NOT see any option that looked wrong.
Could be an IDE Bug or user error.
I suggest looking at "Build Log" whenever things are NOT working right. And, doing a re-build when things are NOT working right.
The warning and pedantic options sorted with dups removed.
In case someone else see a conflict.
Code:-Wall -Wcast-align -Weffc++ -Wextra -Wfloat-equal -Winit-self -Winline -Wmain -Wmissing-declarations -Wmissing-include-dirs -Wredundant-decls -Wshadow -Wswitch-default -Wswitch-enum -Wundef -Wunreachable-code -pedantic -pedantic-errors
"...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson