convert char* to char? c++ - c++

I figured this question had been asked a million times but I can't find the answer anywhere. Should be simple. Ok so I have a struct in my .h file:
struct question{
string programNum;
string programDesc;
string programPoints;
string programInput;
char programQuestion;
};
And then I have function initiated in the .h and arguments in .cpp:
void setQuestionFileName(question q, char fileName){
q.programQuestion = fileName;
}
Ok all is well so far. Now in main I have the issue of trying to store argv[1] in programQuestion:
char* fileName = argv[count+1];
followed by:
setQuestionFileName(questions[count],fileName);
cout << questions[count].programQuestion << endl;
I'm not real good with pointers so if anyone could help me store the char* argv into the char questions[count].programQuestion that would be amazing. Thank you!

I'm going to post the code, I think it may work better that way. This is the .h:
using namespace std;
// Data
struct question{
string programNum;
string programDesc;
string programPoints;
string programInput;
char* programQuestion;
};
void setQuestionFileName(question* q, char* fileName);
void display(question* q);
void display(question* q);
This is the .cpp
using namespace std;
void setQuestionFileName(question* q, char* fileName){
strcpy(q->programQuestion, fileName);
}
void display(question* q){
cout << "Description = " << q->programDesc << endl;
cout << "Number of Points = " << q->programPoints << endl;
cout << "Name of Question File = " << q->programQuestion << endl;
}
// Not used or tested yet
int myCompare (const void * a, const void * b ) {
const char *pa = *(const char**)a;
const char *pb = *(const char**)b;
return strcmp(pa,pb);
}
And main.cpp:
using namespace std;
int main(int argc, char* argv[]){ //or char** argv
question* questions[argc-1]; //Array of questions to be filled by loop.
int sizeOfQuestions = argc; //number of questions passed in at run time
int numLines = 0; //number of lines in file
for(int i=0;i<argc;i++){ //Test loop to make sure the command line file names are read in
std::cout << argv[i] << " says hello" << std::endl;
}
for(int count=0;count<sizeOfQuestions-1;count++){ //This loop places the information from the files into structs
//char fileName = argv[count+1];
char* fileName = argv[count+1];
cout << "Problem number: " << count+1 << "\t Working with file " << fileName << endl;
std::fstream questionFile (fileName, std::fstream::in); //Open the file
if(questionFile.good()){
cout << "File Opened" << endl;
setQuestionFileName(questions[count],fileName);
cout << questions[count]->programQuestion << endl;
getline(questionFile,questions[count]->programNum);
getline(questionFile,questions[count]->programDesc);
getline(questionFile,questions[count]->programPoints);
getline(questionFile,questions[count]->programInput);
display(questions[count]);
questionFile.close();
}else{
cout << "Could not open file!!!" << endl;
}
}
return 0;
}
The way it is now, I'm getting a segmentation fault.

Change your programQuestion from char to char*
And, this function
void setQuestionFileName(question q, char fileName){
q.programQuestion = fileName;
}
I think it should be
void setQuestionFileName(question& q, char* fileName){
strcpy(q.programQuestion, fileName);
}
Hardly there is a file with only 1-character name.

Related

Undeclared Identifier in my function call (C++)

I am a new programmer working in C++, I am trying to make a program that will import information from a file to an output file and then I'm going to do a search algorithm on the data. I am trying to use a structure of data and import that into an array and then call it in the main program.
For some reason I can't, for the life of me, get my function call to work; I keep getting an undeclared identifier error on inputFile in my function call in the main program. I realize I'm probably doing something fundamentally wrong, so I would really appreciate any help that can be given.
#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <fstream>
using namespace std;
const int MAX_LOG_SIZE = 7584;
const string LOGFILE ="crimes.dat";
const string OUTPUT_FILE ="crimesorted.log";
// Structure of strings based on info from crimes.dat
struct CrimeInfo
{
string Crimedescr;
string Date;
string Time;
string Address;
string Grid;
string Latitude;
string Longitude;
};
CrimeInfo crimeList [MAX_LOG_SIZE];
void openInputFile(ifstream& inputFile, string inputFilename)
// here we open the input file crimes.dat
{
inputFile.open(inputFilename.c_str());
while (inputFile.fail())
{
cout << "Failed to open input file: " << inputFilename << ".\n";
exit(1);
}
};
void getLogEntry(ifstream &LOGFILE, CrimeInfo &entry)
{
getline(LOGFILE, entry.Date);
getline(LOGFILE, entry.Time);
getline(LOGFILE, entry.Address);
getline(LOGFILE, entry.Grid);
getline(LOGFILE, entry.Crimedescr);
getline(LOGFILE, entry.Latitude);
getline(LOGFILE, entry.Longitude);
}
/* opens an output file */
void openOutputFile(ofstream& outputFile, string outputFilename)
{
outputFile.open(outputFilename.c_str());
if (outputFile.fail())
{
cout << "Failed to open output file: " << outputFilename << ".\n";
exit(2);
}
}
void outputLogFile(string outputFilename, CrimeInfo arr[], int size)
{
// open output files
ofstream outputLogFile;
openOutputFile(outputLogFile, outputFilename);
// output the crime file
outputLogFile << "\nCrime log sort ^^:\n\n";
for (int i = 0; i < size; i++)
{
outputLogFile << arr[i].Date << " ";
outputLogFile << arr[i].Address << " (";
outputLogFile << arr[i].Longitude << " ";
outputLogFile << arr[i].Latitude << " ";
outputLogFile << arr[i].Time << " ";
outputLogFile << arr[i].Grid << " ";
outputLogFile << arr[i].Crimedescr << "";
outputLogFile << endl;
}
outputLogFile.close();
}
int main()
{
outputLogFile(OUTPUT_FILE, crimeList, MAX_LOG_SIZE);
for (int i =0; i < MAX_LOG_SIZE; i++)
getLogEntry(inputFile, crimeList[i].Date);
}
There are a lot of problems with your code. To help you out, I went through your code and left a lot of my own comments to tell you some suggestions I had; to make it easy, I deleted your comments so there's no confusion on what was yours and what I put there.
Here are some things I noticed in your code:
using namespace std is generally considered a very bad practice. Instead, just specify the namespace (e.g. std::string instead of just string).
You declared LOGFILE as a string at the top of your program, but then tried to use it as an ifstream& in the function getLogEntry.
Your main method is out of order. I'm assuming you want to load some data into the program from a file and then output that data to another file. The way you have it in your main method is, first, you output information you don't have yet and, second, import information but don't do anything with it.
You have a LOT of functions. As a general rule of thumb, don't make a whole function for opening a file, then a separate one for using it, then a separate one for closing it. There are a lot of big reasons why not to do this. The biggest reasons are that your program becomes very difficult to follow, and no one else will be able to use your code. In real-world applications, your code is only 20% for the computer and 80% for other programmers.
There are various formatting errors and such.
So, here is your original code with my comments...
#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib> // Unneeded since other headers here already include this
#include <fstream>
using namespace std; // NEVER globally use the entire standard namespace!
const int MAX_LOG_SIZE = 7584; // Can be declared 'constexpr'
const string LOGFILE ="crimes.dat";
const string OUTPUT_FILE ="crimesorted.log";
/*
NOTE:
> It often looks a lot cleaner to have a header part of your code
and then define your functions seperately. This is good practice
for when you need to start using header files with big projects
*/
struct CrimeInfo
{ // Can declare all variables by only listing type once if they're all the same type
string Crimedescr;
string Date;
string Time;
string Address;
string Grid;
string Latitude;
string Longitude;
};
CrimeInfo crimeList [MAX_LOG_SIZE]; // This should be in 'main()'
/*
This should not be its own function.
Making too many function can make things look a bit confusing.
Here, this is only 4 lines of code, so you shouldn't be making
an entire function for it.
*/
void openInputFile(ifstream& inputFile, string inputFilename)
{
inputFile.open(inputFilename.c_str());
while (inputFile.fail())
{
cout << "Failed to open input file: " << inputFilename << ".\n";
exit(1);
}
};
/*
This should also just be written out where its used. There's
no need to make a whole function for a task like this.
ERROR HERE:
> LOGFILE is NOT an std::ifstream! It is a std::string!
*/
void getLogEntry(ifstream &LOGFILE, CrimeInfo &entry)
{
getline(LOGFILE, entry.Date);
getline(LOGFILE, entry.Time);
getline(LOGFILE, entry.Address);
getline(LOGFILE, entry.Grid);
getline(LOGFILE, entry.Crimedescr);
getline(LOGFILE, entry.Latitude);
getline(LOGFILE, entry.Longitude);
}
/*
This should not be its own function.
Making too many function can make things look a bit confusing.
Here, this is only 4 lines of code, so you shouldn't be making
an entire function for it.
*/
void openOutputFile(ofstream& outputFile, string outputFilename)
{
outputFile.open(outputFilename.c_str());
if (outputFile.fail())
{
cout << "Failed to open output file: " << outputFilename << ".\n";
exit(2);
}
}
// It's a good idea to use some sort of documentation style for functions
void outputLogFile(
// Declare variables const when they aren't modified
/* (const) */ string outputFilename,
/* (const) */ CrimeInfo arr[],
/* (const) */ int size)
{
ofstream outputLogFile;
openOutputFile(outputLogFile, outputFilename); // Just write out the code
outputLogFile << "\nCrime log sort ^^:\n\n";
for (int i = 0; i < size; i++)
{
/*
You only need to declare the name of the stream one time
e.g.
outputLogFile << thing1 << thing2
<< thing3 << thing4 << thing5
<< thing6
<< endl;
*/
outputLogFile << arr[i].Date << " ";
outputLogFile << arr[i].Address << " (";
outputLogFile << arr[i].Longitude << " ";
outputLogFile << arr[i].Latitude << " ";
outputLogFile << arr[i].Time << " ";
outputLogFile << arr[i].Grid << " ";
outputLogFile << arr[i].Crimedescr << ""; // Empty quotes not needed here
outputLogFile << endl;
}
outputLogFile.close();
}
int main()
{
// What data are you outputting?
outputLogFile(OUTPUT_FILE, crimeList, MAX_LOG_SIZE);
// Are you trying to load the data you just outputted?
for (int i =0; i < MAX_LOG_SIZE; i++)
{ // I added these braces, but it's a good idea to always have braces
// You have not declared 'inputFile' anywhere
getLogEntry(inputFile, crimeList[i].Date);
}
}
Instead of leaving you to have to figure all that out on your own (I know how frustrating that can be), I went ahead and wrote your program how I'd do it. I tried to put comments in a lot of places to make it easy to follow along with. If you have any questions about it, feel free to ask me.
#include <fstream>
#include <iomanip>
#include <iostream>
#include <string>
/*
If you're using C++17, the lines below can just become one line:
using std::cin, std::cout, std::endl, std::ifstream,
std::ofstream, std::string, std::getline;
*/
using std::cin;
using std::cout;
using std::endl;
using std::ifstream;
using std::ofstream;
using std::string;
constexpr int MAX_LOG_SIZE = 7584;
const string LOGFILE_NAME = "crimes.dat";
// I'm assuming: inputFile ^^^
// outputFile vvv
const string OUTPUT_FILE_NAME = "crimesorted.log";
/*
NOTE: If you're trying to export data to "crimesorted.log"
and then load it back into the program through "crimes.dat",
that will be a problem. I say this because the main method
in your original code, this is the order you had it in.
*/
// [BEGIN] Function Prototypes
// Structure of strings based on info from crimes.dat
struct CrimeInfo
{
string Crimedescr, Date, Time, Address,
Grid, Latitude, Longitude;
};
/** (This is JavaDoc-style documentation)
[Purpose of function here]
#param outputFile [Describe paramater here]
#param arr[] [Describe parameter here]
#param size_of_arr Size of 'arr[]'
*/
void outputLogFile(
ofstream& outputFile, // Changed to 'std::ofstream&' because I declare this in 'main()'
const CrimeInfo arr[],
const int size_of_arr);
// [END] Function Prototypes
int main()
{
// Create std::ifstream and open a file
ifstream file_to_load;
file_to_load.open(LOGFILE_NAME);
// Constructing and using 'crimeList' here allows the size to be known in
// this scope. However, if it's passed to a function, it's passed as a pointer
CrimeInfo crimeList[MAX_LOG_SIZE];
// Check if file was open and do stuff with it
if (file_to_load.is_open())
{ // File was opened
for (int i = 0; i < MAX_LOG_SIZE; i++)
{
getline(file_to_load, crimeList[i].Date);
getline(file_to_load, crimeList[i].Time);
getline(file_to_load, crimeList[i].Address);
getline(file_to_load, crimeList[i].Grid);
getline(file_to_load, crimeList[i].Crimedescr);
getline(file_to_load, crimeList[i].Latitude);
getline(file_to_load, crimeList[i].Longitude);
}
file_to_load.close(); // Close file
}
else
{ // File could not be
cout << "Could not open file: " << LOGFILE_NAME << endl;
return 1;
}
// Create std::ofstream and output the log
ofstream outputFile;
outputFile.open(OUTPUT_FILE_NAME);
// Check if 'outputFile' opened OUTPUT_FILE_NAME successfully
if(outputFile.is_open())
{ // File was opened
outputLogFile(outputFile, crimeList, MAX_LOG_SIZE);
outputFile.close();
}
else
{ // File could not be opened
cout << "Could not open file: " << OUTPUT_FILE_NAME << endl;
return 1;
}
}
// Function definition for outputLogFile()
void outputLogFile(
ofstream &outputFile,
const CrimeInfo arr[],
const int size_of_arr)
{
outputFile << "\nCrime log sort ^^:\n\n";
for (int i = 0; i < size_of_arr; i++)
{
outputFile
<< arr[i].Date << '\n' // Newlines may look better than spaces here
<< arr[i].Address << " ("
<< arr[i].Longitude << ", "
<< arr[i].Latitude << ")\n"
<< arr[i].Time << '\n'
<< arr[i].Grid << '\n'
<< arr[i].Crimedescr
<< endl;
}
}

Reading or writing binary file incorrectly

The output of the code show gibberish values for all the variables of the Student struct. When the display function is ran.
I've include the relevant code in each of the add and display function for the binary file.
For the second function, does the seekg pointer automatically move to read the the next record each time the for loop runs?
//Student struct
struct Student
{
char name [30];
float labTest;
float assignments;
float exam;
};
//Writing function
afile.open(fileName,ios::out|ios::binary);
Student S;
strcpy(S.name,"test");
S.labTest = rand()%100+1;
S.assignments = rand()%100+1;
S.exam = rand()%100+1;
afile.write(reinterpret_cast<char*>(&S),sizeof(S));
afile.close();
//Reading function
afile.open(fileName,ios::in|ios::binary);
afile.seekg(0,ios::end);
int nobyte = afile.tellg();
int recno = nobyte / sizeof(Student);
Student S;
//Loop and read every record
for(int i = 0;i<recno;i++)
{
afile.read(reinterpret_cast<char*>(&S),sizeof(S));
cout << "Name of Student: " << S.name << endl
<< "Lab mark: " << S.labTest << endl
<< "Assignment mark: " << S.assignments << endl
<< "Exam mark: " << S.exam << endl << endl;
}
afile.close();
There are a lot of problems with your code:
Calling your write function will permanently overwrite the last written data set. You have to add: ios::append, so that new data will be written behind the last data you wrote before.
After you move with afile.seekg(0,ios::end); to get with tellg the file size, you have to go back to the start of the file before reading with afile.seekg(0,ios::beg)
It looks that you use a char array to store a string. This is not c++ style! And it is dangerous how you use it. If you use strcpy, you can copy a string which is longer than the space you reserved for it. So you should prefer std::string for that. But you can't simply write a struct which constains std::string as binary! To get checked copy you can use strncpy, but that is still not c++ ;)
For the second function, does the seekg pointer automatically move to read the the next record each time the for loop runs?
Yes, the file position moves which each successful read and write.
A general remark writing binary data by simply dumping memory content:
That is not a good idea, because you can only read that data back, if you use the same machine type and the same compiler options. That means: A machine with different endianness will read data totally corrupted. Also a different integer type ( 32 bit vs 64 bit ) will break that code!
So you should invest some time how to serialize data in a portable way. There are a lot of libraries around which can be used to read/write also complex data types like std::string or container types.
A hint using SO:
Please provide code which everybody can simply cut and paste and compiled. I did not know what your Student struct is. So I take a lot of assumptions! Is your struct really using char[]? We don't know!
#include <iostream>
#include <fstream>
#include <cstring>
const char* fileName="x.bin";
struct Student
{
char name[100]; // not c++ style!
int labTest;
int assignments;
int exam;
};
// Writing function
void Write()
{
std::ofstream afile;
afile.open(fileName,std::ios::out|std::ios::binary|std::ios::app);
Student S;
strcpy(S.name,"test"); // should not be done this way!
S.labTest = rand()%100+1;
S.assignments = rand()%100+1;
S.exam = rand()%100+1;
afile.write(reinterpret_cast<char*>(&S),sizeof(S));
afile.close();
}
void Read()
{
//Reading function
std::ifstream afile;
afile.open(fileName,std::ios::in|std::ios::binary);
afile.seekg(0,std::ios::end);
int nobyte = afile.tellg();
int recno = nobyte / sizeof(Student);
afile.seekg(0, std::ios::beg);
Student S;
//Loop and read every record
for(int i = 0;i<recno;i++)
{
afile.read(reinterpret_cast<char*>(&S),sizeof(S));
std::cout << "Name of Student: " << S.name << std::endl
<< "Lab mark: " << S.labTest << std::endl
<< "Assignment mark: " << S.assignments << std::endl
<< "Exam mark: " << S.exam << std::endl << std::endl;
}
afile.close();
}
int main()
{
for ( int ii= 0; ii<10; ii++) Write();
Read();
}
EDIT. Apparently, I was a bit too late in responding. Klaus has compiled a better, more comprehensive response dwelling into other problems regarding C-style char [], std::string and the endianness of the platform.
You should append to the file opened for every record. In your code you don't have this, at all. Please write the code in a way we can copy and paste, and test. As a working example, you should write some code that can be compiled and run as below:
#include <algorithm>
#include <cstring>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
// Student struct
struct Student {
char name[30];
float labTest;
float assignments;
float exam;
};
// Serializer
void serialize_student(const Student &s, const std::string &filename) {
// Append to the file, do not overwrite it
std::ofstream outfile(filename, std::ios::binary | std::ios::app);
if (outfile)
outfile.write(reinterpret_cast<const char *>(&s), sizeof(Student));
}
// Deserializer
std::vector<Student> deserialize_students(const std::string &filename) {
std::ifstream infile(filename, std::ios::binary);
std::vector<Student> students;
Student s;
while (infile.read(reinterpret_cast<char *>(&s), sizeof(Student)))
students.push_back(std::move(s));
return std::move(students);
}
int main(int argc, char *argv[]) {
// Generate records
std::vector<Student> mystudents;
std::generate_n(std::back_inserter(mystudents), 10, []() {
Student s;
std::strcpy(s.name, "test");
s.labTest = rand() % 100 + 1;
s.assignments = rand() % 100 + 1;
s.exam = rand() % 100 + 1;
return s;
});
// Print and write the records
for (const auto &student : mystudents) {
std::cout << student.name << ": [" << student.labTest << ','
<< student.assignments << ',' << student.exam << "].\n";
serialize_student(student, "students.bin");
}
// Read and print the records
auto records = deserialize_students("students.bin");
std::cout << "===\n";
for (const auto &student : records)
std::cout << student.name << ": [" << student.labTest << ','
<< student.assignments << ',' << student.exam << "].\n";
return 0;
}

c++ ifstream , Reading from file crashes

At the beginning I apologize for my English.
I was trying to write a XML Parser that I encountered a weird problem.
to explain my problem I should say, I have a xml parser class that has an ifstream member. And this class has a function which reads until it reaches an open tag matching with the given input.
this is the parser class I was working on:
// XMLParser.cpp
#include <fstream>
#include "Stack.h"
using namespace std;
class XMLParser{
private:
int charReadRate = 3;
public:
ifstream *stream;
XMLParser(string add){
stream = new ifstream(add); // open input stream
}
void nextTag(string tag){
// find the first occurance of open-tag with name 'tag'
cout << "nextTag\n";
char * readData;
string tagName="";
stream->read(readData, charReadRate);
int len = string(readData).length();
int i = 0;
// cout << len << endl;
while(true){
if((*readData) == '<'){
readData++;
i++;
while(*readData != '>'){
tagName+=*readData;
readData++;
i++;
if(i>=len){
if(stream->eof()){
return ; // error didn't find
}
stream->read(readData, charReadRate);
// cout << readData << endl;
len = string(readData).length();
i = 0;
}else{
if(tagName == tag){
// cout << "find\n";
stream->seekg(i-len, ios::cur);
return;
}
}
}
}else{
readData++;
i++;
if(i>=len){
if(stream->eof()){
return ; // error didn't find
}
stream->read(readData, charReadRate);
len = string(readData).length();
i = 0;
}
}
}
}
};
in the nextTag function I read the file until I reach the open tag which name's matches with the given input.
and here is my main function
int main(){
XMLParser parser("test.xml");
cout << "ready\n";
parser.nextTag("Log");
char *c;
parser.stream->read(c,3);
cout << c << endl;
return 0;
}
I have figured out that the program crashes when the fifth line of the main function [parser.stream->read(c,3);] is executed.
I wonder why this happens?
The char pointer you pass to ifstream::read is not initialized and thus points to an invalid memory region, causing your program to crash. You need it to point to a buffer you allocated:
int main(){
XMLParser parser("test.xml");
cout << "ready\n";
parser.nextTag("Log");
char c[3];
parser.stream->read(c,3);
cout << c << endl;
return 0;
}

c++ replace what with with on char array(string)

I have the task to write a function char * stringReplace(const char * str, const char * what, const char * with) which replaces "what" with "with" on a new string with the correct length. So Inside the function I created dynamic array, which the function returns. But my question is how can I delete it after, as If i try to delete it in the main function, after i use it, it says it's undefined. Aren't dynamic arrays without a scope or I'm wrong?
Here's my code:
#include <iostream>
#include <string.h>
using namespace std;
bool areTheSame(const char * str, const char * what, unsigned p)
{
return areEqual;
}
unsigned howManyTimes(const char * str, const char * what)
{
}
char * stringReplace(const char * str, const char * what, const char * with)
{
}
int main()
{
char str[1000];
char what[1000];
char with[1000];
cout << "Enter your string\n";
cin.getline(str, 1000);
cout << "\nEnter \"what\" you want to replace\n";
cin.getline(what, 1000);
if (strlen(str) < strlen(what))
{
cout << "\"What\" contains more characters than the string!\n";
return 0;
}
cout << "\nEnter with what you want to replace it\n";
cin.getline(with, 1000);
cout << "\nYour string with replaced words looks like\n";
cout << stringReplace(str, what, with) << endl;
return 0;
}
P.S I deleted parts of the code as I found the answer I wanted and there is still time for the task, and I'm not sure I'm allowed to post my code publicly
You have to delete it in order to avoid memory leak. You can do something like this:
int main()
{
char str[1000];
char what[1000];
char with[1000];
char *replaced;
cout << "Enter your string\n";
cin.getline(str, 1000);
cout << "\nEnter \"what\" you want to replace\n";
cin.getline(what, 1000);
if (strlen(str) < strlen(what))
{
cout << "\"What\" contains more characters than the string!\n";
return 0;
}
cout << "\nEnter with what you want to replace it\n";
cin.getline(with, 1000);
cout << "\nYour string with replaced words looks like\n";
replaced = stringReplace(str, what, with);
cout << replaced << endl;
delete [] replaced;
return 0;
}
However note that this isn't the best pratice to split allocation/deallocation responsibility.

multiple return statement in c++

I have tried to complete a C++ exercise where you have to complete function definitions for a 'Golf' function and devise a program based on this however, I am having a problem with one of the functions.
Part of the goal of the function, wants you to return 1 if the user has entered a name for the golf player, and return 0 if no name is entered.
I am experiencing some difficulty with this, as when I run the program, I am always getting 1 returned to the main.
Underneath I have listed what I have done so far for each file:
golf.h
#ifndef GOLF_H
#define GOLF_H
const int Len = 40;
struct golf {
char fullname[Len];
int handicap;
};
void setgolf(golf &g, const char *name, int hc);
int setgolf(golf &g);
void handicap(golf &g, int hc);
void showgolf(const golf &g);
#endif /* GOLF_H */
golf.cpp
#include "golf.h"
#include "iostream"
void setgolf(golf &g, const char *name, int hc) {
strcpy(g.fullname, name);
g.handicap = hc;
}
int setgolf(golf &g) {
std::cout << "Golfer's name:";
std::cin.getline(g.fullname, Len);
if (std::cin.get() == '\0')
return 0;
std::cout << "Golfer's handicap: ";
std::cin >> g.handicap;
return 1;
}
void handicap(golf &g, int hc) {
g.handicap = hc;
std::cout << g.fullname << "'s new handicap is:" << g.handicap;
}
void showgolf(const golf &g) {
std::cout << "Player's Name:" << g.fullname << std::endl;
std::cout << "Player's handicapped:" << g.handicap << std::endl;
}
main.cpp
#include <cstdlib>
#include <iostream>
#include "golf.h"
using namespace std;
int main(int argc, char** argv) {
int retuVal = 0;
golf ann;
setgolf(ann, "Ann Birdfree", 24);
showgolf(ann);
cout << "\n";
golf peter;
retuVal = setgolf(peter);
cout<<"return value is:"<<retuVal<<endl;
cout << "\nGolf details reset in new handicap\n";
handicap(peter, 5);
cout << "\nDetails reprinted";
showgolf(peter);
return 0;
}
Please let me know, what it is that I have done wrong, so that I can return 0 instead of returning 1 all of the time.
Thanks Jis.
In the function setgolf remove the following code:
if (std::cin.get() == '\0')
return 0;
and instead write...
if(strlen(g.fullname)==0)
return 0;
This is because when the user doesn't want to enter a name he just hits the enter key. This makes the string empty, since getline fills the character array until it is completely filled or it sees a newline character in the stream. So, if we just check its length, whether its greater than 0, then its enough. for furthur reference about getline see here
The probability of cin.get() returning '\0' is almost 0.
(If cin is connected to a terminal, it can only happen if the
user enters a control-#.) Maybe you want to return 0 if the user
enters an empty string?