Open GasimV opened 3 days ago
Here’s how you can add std::cout
statements to inspect the intermediate values in ParseCoordinates
, ParseDistances
, and ApplyCommands
. This will help debug why the output doesn't match expectations.
ParseCoordinates
Debug StatementsIn ParseCoordinates
, print the input string and the parsed latitude and longitude:
Coordinates ParseCoordinates(std::string_view str) {
static const double nan = std::nan("");
auto not_space = str.find_first_not_of(' ');
auto comma = str.find(',');
if (comma == str.npos) {
std::cout << "[ParseCoordinates] Invalid input: \"" << str << "\"\n";
return {nan, nan};
}
auto not_space2 = str.find_first_not_of(' ', comma + 1);
double lat = std::stod(std::string(str.substr(not_space, comma - not_space)));
double lng = std::stod(std::string(str.substr(not_space2)));
std::cout << "[ParseCoordinates] Input: \"" << str << "\" -> Lat: "
<< lat << ", Lng: " << lng << "\n";
return {lat, lng};
}
ParseDistances
Debug StatementsIn ParseDistances
, print the input string and each extracted distance:
std::vector<std::pair<std::string_view, int>> ParseDistances(std::string_view distances_part) {
std::vector<std::pair<std::string_view, int>> distances;
std::cout << "[ParseDistances] Input: \"" << distances_part << "\"\n";
size_t pos = 0;
while (pos < distances_part.size()) {
auto m_pos = distances_part.find("m to ", pos);
if (m_pos == distances_part.npos) {
break;
}
int distance = std::stoi(std::string(distances_part.substr(pos, m_pos - pos)));
auto stop_pos = m_pos + 5; // "m to " is 5 characters long
auto stop_end = distances_part.find_first_of(',', stop_pos);
if (stop_end == distances_part.npos) {
stop_end = distances_part.size();
}
std::string_view stop_name = distances_part.substr(stop_pos, stop_end - stop_pos);
distances.emplace_back(stop_name, distance);
std::cout << "[ParseDistances] Found: Distance = " << distance
<< "m to Stop \"" << stop_name << "\"\n";
pos = stop_end + 1;
}
return distances;
}
ApplyCommands
Debug StatementsAdd debug statements to each section in ApplyCommands
to track the parsing of stops, distances, and bus routes:
void InputReader::ApplyCommands(TransportCatalogue& catalogue) const {
// First pass: Add stops and their coordinates
for (const auto& command : commands_) {
if (command.command == "Stop") {
auto colon_pos = command.description.find(',');
auto coords = ParseCoordinates(command.description.substr(0, colon_pos));
catalogue.AddStop(command.id, coords);
std::cout << "[ApplyCommands] Added Stop: \"" << command.id
<< "\" with Coordinates: Lat = " << coords.lat
<< ", Lng = " << coords.lng << "\n";
}
}
// Second pass: Add distances for stops
for (const auto& command : commands_) {
if (command.command == "Stop") {
auto colon_pos = command.description.find(',');
auto distances_part = command.description.substr(colon_pos + 1);
const auto* from_stop = catalogue.GetStopInfo(command.id);
if (!from_stop) {
std::cout << "[ApplyCommands] Skip undefined Stop: \""
<< command.id << "\"\n";
continue;
}
auto distances = ParseDistances(distances_part);
for (const auto& [to_stop_name, distance] : distances) {
const auto* to_stop = catalogue.GetStopInfo(to_stop_name);
if (to_stop) {
catalogue.SetDistance(from_stop, to_stop, distance);
std::cout << "[ApplyCommands] Set Distance: " << distance
<< "m from \"" << command.id
<< "\" to \"" << to_stop_name << "\"\n";
if (catalogue.GetDistance(to_stop, from_stop) == 0) {
catalogue.SetDistance(to_stop, from_stop, distance);
std::cout << "[ApplyCommands] Set Reverse Distance: "
<< distance << "m from \""
<< to_stop_name << "\" to \"" << command.id << "\"\n";
}
} else {
std::cout << "[ApplyCommands] Destination Stop not found: \""
<< to_stop_name << "\"\n";
}
}
}
}
// Third pass: Add bus routes
for (const auto& command : commands_) {
if (command.command == "Bus") {
bool is_cyclic = command.description.find('>') != std::string::npos;
auto stops = ParseRoute(command.description);
catalogue.AddRoute(command.id, stops, is_cyclic);
std::cout << "[ApplyCommands] Added Bus Route: \"" << command.id
<< "\" with " << stops.size() << " stops. "
<< "Cyclic: " << std::boolalpha << is_cyclic << "\n";
}
}
}
After adding the debug statements, recompile your code as before:
g++ -std=c++17 -o transport_catalogue main.cpp input_reader.cpp stat_reader.cpp transport_catalogue.cpp -lm
Run the program with your input. For example:
./transport_catalogue < input.txt
The debug output will include detailed information about:
ParseCoordinates
.ParseDistances
.ApplyCommands
.Check for discrepancies or unexpected behavior. For example:
If something doesn’t match expectations, note where the process diverges and update me with the relevant debug output for further analysis.
Below is a structured approach to debugging a program, broken into key steps. This method can be applied to most software development scenarios.
Structured Debugging Approach
1. Understand the Problem
2. Narrow Down the Scope
ParseRoute
.ApplyCommands
.3. Add Debug Statements
std::cout
(or equivalent) at key locations in the code:Example Debug Outputs:
Debugging Categories:
4. Isolate the Issue
5. Cross-Check Assumptions
6. Fix the Issue
7. Clean Up Debug Statements
Example Method Implementation
Here’s how you could apply the above to debug route parsing (
ParseRoute
) in the future:Reusable Debug Checklist
Input Verification:
Intermediate Calculation Logging:
Branch/Condition Testing:
if
,else
, orswitch
blocks.Output Validation:
Example General Debugging Function
For consistent debugging in all functions, create a macro or utility:
Usage:
Conclusion
By following this structured approach, you can systematically identify and resolve issues. Keeping this as a reference will help you debug future programs efficiently.