Multiple definition error on the same line. (C++) - c++

I have a new complicated problem. The compiler complains that I am redefining a function, but it says that the first place I declared it at has the site of re-declaration. The problem began as soon as I included the cpp file in another. In attempt to fix my problem I exported it to a hpp file, but to know avail. Here is my code.
main.cpp:
#include <iostream>
#include <string>
#include "main.hpp"
using namespace std;
int main(int argc, char *argv[])
{
//Deal with arguments and send them to the correct functions
if (argc >= 2){
string op = argv[1];
if (op == "-a" || op == "--automatic"){
if (argc >= 3){
string FName = argv[2];
bool dbgbool;
if (argc == 4){
string dbgstring = argv[3];
if (dbgstring == "debug"){
dbgbool = true;
}
}
Lexer(FName, dbgbool);
}
}
else{
cout << "Invalid Argument\n";
goto help;
}
return 0;
}
//Or, just write help and info
help:
cout << "\n";
cout << "bwc v0.0.1U-(Unstable)\n\n";
cout << "Usage: bwc <operation> [...]\n";
cout << "Operations:\n";
cout << " bwc {-a --automatic} <file(s)>\n";
cout << " bwc {-i --interactive}\n";
cout << " bwc {-c --error-codes}\n";
cout << "\n";
return 0;
}
LA.cpp:
#include<iostream>
#include<fstream>
#include<string>
#include<sstream>
using namespace std;
string Lexer(string FileN, bool dbg){ //This is the line of re-declaration.
//If debugging,this writes out put to the console
if (dbg == true)
cout << "Beginning Lexical Analysis...\n";
//Create new file stream and set it equal to the source file
ifstream Ifile (FileN.c_str());
//Test if the last step failed, if so, write an error to the console, and terminate the compiler
if (!Ifile.is_open()){
cout << "Unable to open file. Path to file may not exist, or the file name could be incorrect.\n";
cout << "Error Code: -1\n";
return NULL;}
//Create new stringstream, and set it equal to the source file
string IFStream;
Ifile >> IFStream;
//Close the source file
Ifile.close();
//If debugging,this writes out put to the console
if (dbg == true)
cout << "Source file sucessfully read.\n";
//Set out stream equal to the modified in stream
string OFStream = IFStream;
return OFStream;
}
and finally,
main.hpp:
#ifndef MAIN_HPP_INCLUDED
#define MAIN_HPP_INCLUDED
#include "LA.cpp"
extern string Lexer(string,bool);
#endif // MAIN_HPP_INCLUDED
Thanks,
Brooks Rady

Your main.cpp is including main.hpp which is including LA.cpp, so the contents of LA.cpp are being compile once for LA.cpp and once for main.cpp.
.hpp files should contain only declarations (string Lexer(string,bool);), while the definitions (string Lexer(string,bool) {... }) should go in the .cpp
You will not see this kind of issue when you are dealing with class methods, because the compiler accepts definitions of methods. But functions should be defined only in the .cpp files.

Related

C++ problem trying to open a .txt file using Ifstream

This small bit of code is designed to look through a text file and identify account numbers that have already been written so that later on in my program, you can find the correct account without the error of two accounts with the same account number(id). But no matter what i do, whether its using double backslashes, forward slashes, or double forward slashes in the location for the ifstream object; i always get "cannot find file" as the output.
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ifstream accountsread("‪G:/Coding/Test/test/test/accounts.txt");
if (accountsread.is_open()) {
int tempAccno;
std::string tempname;
char tempchar;
int accountsfound = 0;
int input;
std::cout << "Enter the ID of the account \n";
cin >> x;
while (!accountsread.eof()) {
accountsread >> tempAccno;
if (tempAccno == input) {
accountsfound++;
}
else {}
}
if (accountsfound > 0) {
cout << "number found";
}
else {
cout << "number not found";
}
}
else {
cout << "cannot find file";
}
}
in windows, the location of the text file is ‪G:\Coding\Test\test\test\accounts.txt
std::ifstream can use relative paths as well as absolute ones. For your problem, I'd recommend looking into the <filesystem> header from the STL if you really need an absolute path to your file. However, if it's in the same directory as your working directory, you don't need to use absolute paths. Here's how I'd accomplish your task
#include <iostream>
#include <fstream>
#include <string> // Should include since you're using std::string
// Note that I am NOT "using namespace std;"
int main()
{
std::ifstream accountsRead("accounts.txt");
if (accountsRead.is_open())
{
int account_id;
bool account_found = false;
std::cout << "Enter the ID of the account: ";
while (!(std::cin >> account_id))
{ // This loop handles if the user inputs non-number
std::cout << "Please enter a NUMBER below!\n";
std::cout << "Enter: ";
std::cin.ignore(10000, '\n');
std::cin.clear();
}
int tmpAccNum;
while (accountsRead >> tmpAccNum)
{ // This loop reads the file, line by line, into tmpAccNum
if (tmpAccNum == account_id)
{
account_found = true;
break;
}
}
if (account_found)
{
std::cout << "Number found!" << std::endl;
}
else
{
std::cout << "Number not found..." << std::endl;
}
}
else
{ // Error opening file
std::cout << "File not found or is corrupted" << std::endl;
}
}
A few things about your code stylistically speaking. First, you should never be using namespace std, and (if you are for some reason) there isn't a reason to mix and match specifying the std namespace on only some std members. Second, you don't need to specify an else for every if-statement, and you probably shouldn't unless there actually are commands to execute if the else case is reached.
Edit
If you still need an absolute path, here is how you can do that:
#include <filesystem>
int main()
{
// Create path object for the file path
std::filesystem::path file_path("G:\Coding\Test\test\test\accounts.txt");
// The '.string()' method for a 'std::path' object returns the string
// version of the path, so you can use it with an 'std::ifstream'
std::ifstream accounts(file_path.string()); // Opens file via 'ifstream'
/* And so on... */
}

copy text from one file to another

I have tried two different while loops. I think they have a similar problem. Neither of them terminate or give any output.
The task is to copy (byte for byte) one file into another. The file does not have to have endlines, nor does it have to be a .txt file (it could be .exe...).
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <iomanip>
using namespace std;
int main(int argc, char *argv[])
{
char c, c1, c2;
ifstream inFile;
ofstream outFile;
inFile.open("blackbird.txt");
if (inFile.fail())
{
cout << "\nThe file was not successfully opened for reading."
<< "\nPlease check that the file currently exists.\n\n";
exit(1);
}
cout << "\nThe file has been successfully opened for reading.\n\n";
outFile.open("blackbird_copy.txt");
if (outFile.fail())
{
cout << "The file was not successfully opened for writing" << endl;
exit(1);
}
cout << "The file has been successfully opened for writing.\n\n";
//outFile << "Hello";
// 1) this loop doesn't terminate. 2) the computer doesn't know what c1 is.
/*
while (inFile.get(c1))
{
outFile << c1;
cout << c1;
}
*/
// This one is no better
/*
while (inFile.good())
{
inFile.get(c);
outFile << c;
}
*/
inFile.close();
outFile.close();
// read contents of blackbird_copy to check our work.
inFile.open("blackbird_copy.txt");
while (inFile.get(c2))
{
cout << c2;
}
cout << endl << endl;
return 0;
}
inFile.get(c1) Reads one character and stores it to c1 if available. Otherwise, leaves ch unmodified and sets failbit and eofbit.
You can use inFile.eof() to check whether the end of the file has been reached.

Getting a build error in c++

I am getting a weird C3681 error, keeps saying that an identifier cannot be found for one of my functions. I am very confused and have tried solutions found while using Google, but I cannot get it resolved. I would prefer not to use stl.
The error:
Error 1 error C3861: 'readTheStuff': identifier not found c:\users\xxxxxx\desktop\data structures\homework2\homework2\editor.cpp 38 1 Homework2
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int readFile(const char *fileName) {
ifstream myReadFile;
string line;
int i = 0;
myReadFile.open(fileName);
if (myReadFile.is_open()) {
while (!myReadFile.eof()) {
getline(myReadFile, line);
line += " "; //adds a space after every line
//cout << line << endl;
readTheStuff(line);
}
}
myReadFile.close();
return 0;
}
void readTheStuff(string command){
cout << command; //testing
}
int main(int argc, const char* argv[]){ //when they call, going to pass two parameters
if (argc > 2){
cout << "Error, more than one file given" << endl;
}
else if (argc < 2){
cout << "Error, no file given" << endl;
}
else if (argc == 2){
readFile(argv[1]);
}
}
You have to declare a function before you can call it. Either make a declaration of readTheStuff before readFile or, more simply, just move the whole function up above readFile
2 ways to fix this.
1.) Include the following line just underneath your #includes in editor.cpp
void readTheStuff(std::string command)
or include the following line in addition to your other #includes
#include "editor.h"
inside editor.h the following line would need to appear
void readTheStuff(string command)
This is called prototyping and allows the compiler to link readTheStuff(line) to the actual function reaTheStuff(string command).

When compiling code antivirus says it's virus and delete it

Hi i try to make code in c++. This code only makes text file easy encrypted and save into a new file. And when i compile this code antivirus says, it is virus/spyware Gen:Variant.Kazy.20825. I dont know why it is virus.
Here is my code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void controlParameters(int argc){ //check if input parameters are ok
if(argc == 1){
cout << "Pokud chcete text zasifrovat, spustte program s parametrem: -enc \"Nazev_souboru.txt\"\n";
cout << "Pokud ho chcete desifrovat, spustte program s parametrem: -dec \"Nazev_souboru.txt\"\n";
}else if(argc > 3){
cout << "Moc parametru. Spustte si program bez parametru.\n";
}else if(argc < 3){
cout << "Chybi jeden parametr. Spustte si program bez parametru.\n";
}else{
cout << "Vsechno vypada zatim dobre\n";
}
}
void encryption(string &file); //encrypt text file
void decryption(string &file); //decrypt text file
bool controlFile(string &file); //check if file can be opened
int main(int argc, char **argv){
controlParameters(argc);
string file;
file = argv[2];
if(controlFile(file)){
}else{
cout << "Soubor nesel nacist." << endl;
return -1;
}
cout << "Ukonceno.\nZmacknete ENTER pro pokracovani..."<<endl;
cin.get();
return 0;
}
bool controlFile(string &file){
ifstream ifs;
ifs.open(file);
if(ifs.is_open()){
ifs.close();
return true;
}else{
ifs.close();
return false;
}
}
void encryption(string &file){
ifstream ifs;
ofstream ofs;
string line;
ifs.open(file);
ofs.open("encrypt.txt");
if(ifs.is_open()){
while(!ifs.eof()){
getline(ifs,line);
int a = line.length();
int i = 0;
while(i < a){
ofs << ((char)(line[i]^100));
}
line.clear();
ofs << "\n";
}
}else{
cout << "Nelze nacist soubor" << endl;
}
}
void decryption(string &file){
ifstream ifs;
ofstream ofs;
string line;
ifs.open(file);
ofs.open("decrypt.txt");
if(ifs.is_open()){
while(!ifs.eof()){
getline(ifs,line);
int a =line.length();
int i = 0;
while(i < a){
ofs << ((char)(line[i]^100));
}
line.clear();
ofs << "\n";
}
}else{
cout << "Nelze nacist soubor" << endl;
}
}
It's good practice to exclude your source-control directories from virus scanners; they can cause performance and locking problems even if there are no false positives while performing source-control actions or compiling (I've seen it happen several times).
So if only to make your programming experience more reliable, disable the virus scanner on those directories.
You may still want to scan the final, released version of your executable to help avoid false positives: after all, even if it's not your fault the virus scanner chokes, it's not a good impression to leave behind on a user.
Antivirus software uses "heuristics" to determine what is a virus and what isn't. So it looks for patterns in the file that does things that it finds suspicious. I can't see anything directly wrong in your code, so I suspect it's a "false-positive". I personally don't like antivirus software, it causes more problems than it solves...
By the way, you could add the "output filename" to your encrypt/decrypt function, and make them one function! ;)

String turns up empty after find_last_of() and substr()?

Self-teaching myself C++, and I know I'm missing something critical, but I can't for the life of me figure out what it is.
Forgive the huge block of code, I was tempted to trim it down to the critical elements, but I figured if I left it intact, you folks might have other educational criticisms about my coding style...
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <fstream>
using namespace std;
// main routine
int main(int argc, char *argv[]) {
// will store filetype here for later
string filetype = "";
string filename;
// if no arguments, die.
if (argc < 2) {
cout << "ERROR: Nothing to do." << endl;
return 1;
}
// if more than one argument, die.
else if (argc > 2) {
// TODO: support for multiple files being checked would go here.
cout << "ERROR: Too many arguments." << endl;
return 1;
}
// otherwise, check filetype
else {
string filename = argv[1];
cout << "Filename: " << filename << endl;
//searching from the end, find the extension of the filename
int dot = filename.find_last_of('.');
if (dot == -1){
// TODO: Add support for filenames with no extension
cout << "ERROR: Filename with no extension." << endl;
return 1;
}
string extension = filename.substr(dot);
if (extension == ".htm" || extension == ".html"){
filetype = "html";
}
else if (extension == ".c"){
filetype = "c";
}
else if (extension == ".c++" || extension == ".cpp") {
filetype = "cpp";
}
else {
cout << "ERROR: unsupported file extension" << endl;
// TODO: try to guess filetype from file headers here
}
}
cout << "Determined filetype: " << filetype << endl;
cout << "Filename: " << filename << endl;
return 0;
}
// All done :]
The issue I'm having is mysterious. I put the argument passed into a string like so:
string filename = argv[1];
and then search it for an extension, starting from the end and working my way to the beginning:
int dot = filename.find_last_of('.');
string extension = filename.substr(dot);
This all works as expected, but afterwards, when I try to output filename, it is mysteriously empty? I tried debugging with cout. When I print out the string BEFORE I search it, it prints properly. After, nothing prints. Like so:
$ g++ test.cpp -o test.out; ./test.out foo.html
Filename: foo.html
Determined filetype: html
Filename:
I remembered something about iterators in the past, and tried using filename.begin() to reset it, but this did nothing. Can someone shed light onto this puzzling issue?
You are declaring a second variable called filename here, after the else:
string filename = argv[1];
This goes out of scope by the time you get here:
cout << "Filename: " << filename << endl;
You are now printing the contents of the 1st variable you declared called filename, just under main.