0

Hi I have a few errors that are puzzling me. One of them is huge and the other is just bothering me.

So just a few things before you suggest I make other functions: The prototypes I made were specified by my teacher. I'm not allowed to use any functions other than the ones he instructed me to use. So I'm not allowed to make up any functions to fix my problems.

In my COPY function, I'm using a linebuffer reading into an input file to take each line from my input text and printing it onto my output file. My problem is that if I don't add a null newline in my input, the function reads 1 less line.

for example if I have 5 lines of text in my input file, and don't press enter after my last line, it will only print 4 lines of text.

Second, I'm getting these errors:

Error   2   error LNK2019: unresolved external symbol "int __cdecl calcFactorial(void)" (?calcFactorial@@YAHXZ) referenced in function _main    C:\Users\UserName\Documents\CS161\Atilla\main\main\main.obj main


Error   3   error LNK1120: 1 unresolved externals   C:\Users\UserName\Documents\CS161\Atilla\main\Debug\main.exe    1   1   main

And this warning:

Warning 1   warning C4996: 'strerror': This function or variable may be unsafe. Consider using strerror_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.    c:\users\UserName\documents\cs161\atilla\main\main\main.cpp 127 1   main

Then from time to time, all my "cout"s get errors saying "cout is ambiguous"

Any suggestions to fixing my errors? Sorry if there's a lot. I searched for solutions online but I don't quite understand how to fix it. Can someone explain for a newbie like me? Thanks

Oh and heres my code:

#include <iostream>
#include <string>
#include <fstream>
#include <cmath>

using namespace std;

int getUserOption();
void copyFiles();
string getFileName();
int calcFactorial();
void countWords();
void countBytes();


int main()
{
    //List of main variables
    int option;
    int userFactorialInt;

    do {
        option = getUserOption();
        switch (option) {
        case 0:
            break;
        case 1:
            cout << "\n\nYou Chose COPY\n" << endl;
            copyFiles();
            break;
        case 2:
            cout << "\n\nYou Chose FACTORIAL\n" <<
                "\nPlease type an integer number between 1 and 12: ";
            cin >> userFactorialInt;
            cin.ignore(8192, '\n');
            if (userFactorialInt >= 1, userFactorialInt <= 12)
            {
                cout << userFactorialInt << "'s factorial is: " << calcFactorial() << endl << endl;
            }
            else
            {
                cout << "Error, the number must be between 1 and 12" << endl;
            }
            break;
        case 3:
            cout << "\n\nYou Chose COUNT WORDS\n";
        case 4:
            cout << "\n\nYou Chose COUNT BYTES\n";
        case -1:
            cout << "\n\n*Invalid option entered.* Did you remember to type the word"<<
                "\nin full caps? A valid option is demonstrated below:"<<
                "\n(example) \nEnter Option: COUNT WORDS \n\n" << endl;
            getUserOption();
            break;
        }
    } while (option != 0);
    cout << "Program ending" << endl;

    return 0;
}

int getUserOption() {
    string userInput;
    cout << "-------------------------------------------------------------------------------\n"<<
        "Enter one of the following options in full capital letters as it appears:\n\n" <<
        "QUIT - Exit the program\n" <<
        "COPY - Copy the contents of a .txt file\n" <<
        "FACTORIAL - Calculate the factorial of an integer between 1 and 12\n" <<
        "COUNT WORDS - Count the number of words in a .txt file\n" <<
        "COUNT BYTES - Count the number of bytes in a .txt file\n" <<
        "Enter option: ";

    getline(cin, userInput);
    if (userInput == "COPY") {
        return 1;
    }
    else if (userInput == "FACTORIAL") {
        return 2;
    }
    else if (userInput == "COUNT WORDS") {
        return 3;
    }
    else if (userInput == "COUNT BYTES") {
        return 4;
    }
    else if (userInput == "QUIT") {
        return 0;
    }
    else {
        return -1;
    }
    return 0;
}

string getFileName()
{
    string inFileName;
    cout << "Enter input file address: ";
    getline(cin, inFileName);
    return inFileName;
}

void copyFiles()
{
    ifstream inFile;
    ofstream outFile;

    string inputFileName, outputFileName, lineBuffer;

    cout << "Enter output file name: ";
    getline(cin, outputFileName);

    do
    {
        inputFileName = getFileName();
        inFile.open(inputFileName.c_str());    //Try the open inputFileName
        if (inFile.good() != true) { // If "it works" is not true,
            cout << "Error: Invalid input file address. \n" //tell the user it doesn't work.
                 << strerror(errno) << endl; //If open did not work tell why
            cout << "Please type a valid file address\n" <<
                "eg: C:\\Users\\ThisUnit\\Documents\\CS161\n";
        }
    } while (inFile.good() != true);             //Loop as long as the open fails

    outFile.open(outputFileName.c_str());        //Open the output
    do {
        getline(inFile, lineBuffer);            //Read a line of input
        if (inFile.eof() != true) {
            outFile << lineBuffer << endl;    //If read worked, write to output
        }
    } while (inFile.eof() != true);            //Repeat for all lines in the file

    inFile.clear();
    inFile.close();
}

**Thanks for the edits

jsantander
  • 4,972
  • 16
  • 27
  • You never defined `calcFactorial`... – chris Jun 06 '14 at 04:38
  • @chris How would I go defining it again? Also in case 2 I wanted to make a loop that would continue to loop if it fails to detect a valid integer number between 1 and 12. I'm not sure how to construct that loop and am reserving myself from inserting the calcFactorial. Any suggestions? – user3505632 Jun 06 '14 at 04:56
  • It needs a body. You can't call a function when it doesn't have a body. – chris Jun 06 '14 at 05:00

1 Answers1

0

You must learn about the difference between declaring and defining.

With int calcFactorial() you've just declared that a function called calcFactorial exists. This enables you to use it in the code after the declaration, as in the line

cout << userFactorialInt << "'s factorial is: " << calcFactorial() << endl << endl;

The problem you are getting is a linker error. The linker (the program in charge of putting together all the components of your program) is complaining that you've said you are using a function that it cannot find a definition for.

The definition, i.e. something of the sort:

int calcFactorial() {

   // Do things to calculate the factorial

   return theComputedFactorial;
}

Must be present somewhere in your program:

  1. Either on the same compilation unit (your main.cpp) that it is using it.
  2. Or on a different compilation unit (other *.cpp... that you can link into the program, or packed into a library that you will link into the program.

There must be only one definition.


About the warning on strerror. This functions returns a pointer to an internal buffer and it is not thread-safe. See more at Why can't I use strerror?


Not sure what the problem is with your cout is ambiguous

Community
  • 1
  • 1
jsantander
  • 4,972
  • 16
  • 27