C++中char*与char类型转换错误:命令行参数赋值问题
Hey there! Let's break down your errors and fix them step by step—since you're new to C++, these are super common pitfalls, so don't worry about it.
First, let's tackle the compiler errors you're seeing:
Error: invalid conversion from 'char*' to 'char' [-fpermissive]
The problem here is how you're handling argv. Each element in argv (like argv[1], argv[2]) is a string pointer (char*), not a single character (char). When you type ./cl 2024 january 15, argv[1] is the full string "2024", not just the first character '2'. Assigning that entire string pointer to a single char variable is what's causing the error.
Fix 1: Correctly capture command-line arguments
Instead of using char for arg1 and arg3, use std::string (since you're already including <string>) to hold the full input strings:
int main(int argc, char** argv) { int year, month, day; // Use string to store the full argument strings string arg1 = argv[1]; string arg2 = argv[2]; string arg3 = argv[3]; argumentChange(argc, arg1, arg2, arg3, year, month, day); // ... rest of your code }
Fix 2: Update the argumentChange function signature
Your current function expects single char values for the year and day, but we're now passing full strings. Also, right now you're modifying year, month, and day inside the function, but since you're passing them by value, those changes won't show up in main()! You need to pass them by reference (using &) so the function can modify the original variables.
Update the function signature to this:
void argumentChange(int numArg, const string& chArg1, const string& sArg2, const string& chArg3, int& year, int& month, int& day)
- The
const string&means we're passing the strings without copying them (efficient, and we don't need to modify them) - The
int&means we're passing references to theyear,month,dayvariables inmain()—any changes to these inside the function will affect the original variables.
Fix 3: Properly convert strings to integers
Your original code tried to do year = chArg1 - '0'; which only works for single-digit numbers (like if the year was "5"). For full years like "2024", use std::stoi() (string to integer) to convert the entire string to an int:
// Replace these lines in argumentChange: year = stoi(chArg1); // Converts "2024" to 2024 day = stoi(chArg3); // Converts "15" to 15
Fix 4: Fix argument validation logic
Right now, your code checks if (numArg < 4 || numArg >4) which is the same as if (numArg !=4). After printing the usage message, you should exit the program (or return early) so it doesn't try to run the rest of the code with invalid arguments. Add a return; after the error message:
if (numArg != 4) { cout << "Correct Usage: ./cl <birth_year> <birth_month> <birth_day>" << endl; cout << "Try again, dude." << endl; return; // Exit the function early }
Full corrected code snippet
Here's what your updated code would look like with all these fixes:
#include <iostream> #include <ctime> #include <string> using namespace std; void argumentChange(int numArg, const string& chArg1, const string& sArg2, const string& chArg3, int& year, int& month, int& day) { cout << "Starting birth date: " << chArg1 << " " << sArg2 << " " << chArg3 << endl; if (numArg != 4) { cout << "Correct Usage: ./cl <birth_year> <birth_month> <birth_day>" << endl; cout << "Try again, dude." << endl; return; } else { year = stoi(chArg1); day = stoi(chArg3); if ((sArg2 == "january") || (sArg2 == "January")) { month = 0; } else if ((sArg2 == "february") || (sArg2 == "February")) { month = 1; } else if ((sArg2 == "march") || (sArg2 == "March")) { month = 2; } else if ((sArg2 == "april") || (sArg2 == "April")) { month = 3; } else if ((sArg2 == "may") || (sArg2 == "May")) { month = 4; } else if ((sArg2 == "june") || (sArg2 == "June")) { month = 5; } else if ((sArg2 == "july") || (sArg2 == "July")) { month = 6; } else if ((sArg2 == "august") || (sArg2 == "August")) { month = 7; } else if ((sArg2 == "september") || (sArg2 == "September")) { month = 8; } else if ((sArg2 == "october") || (sArg2 == "October")) { month = 9; } else if ((sArg2 == "november") || (sArg2 == "November")) { month = 10; } else if ((sArg2 == "december") || (sArg2 == "December")) { month = 11; } else { cout << "Error: You have entered an invalid term for month. Please type "; cout << "the complete name of a valid month." << endl; return; // Exit if month is invalid } } } struct tm bday(int year, int month, int day) { struct tm r {0}; r.tm_year = year - 1900; r.tm_mon = month; r.tm_mday = day; return r; } int main(int argc, char** argv) { int year, month, day; string arg1 = argv[1]; string arg2 = argv[2]; string arg3 = argv[3]; argumentChange(argc, arg1, arg2, arg3, year, month, day); struct tm a = bday(year, month, day); time_t x = mktime(&a); time_t y = time(0); if ( x != (time_t)(-1) && y != (time_t)(-1) ) { double difference = difftime(y, x) / (60 * 60 * 24); cout << ctime(&x); cout << ctime(&y); cout << "difference = " << difference << " days" << endl; } return 0; }
Key takeaways for beginners:
argvelements are strings (char*), not single characters. Usestd::stringto handle them easily.- When you want a function to modify variables from the caller, pass them by reference (using
&). Passing by value creates a copy that gets discarded when the function ends. - Use
stoi()to convert numeric strings to integers—don't try to do single-character math unless you're dealing with individual digits.
内容的提问来源于stack exchange,提问作者KingKenny04

