When I compile a C++ project in eclipse it shows me errors saying that all functions in IO.cpp are already defined.
This is my code:
File: IO.cpp
#include <string>
#include <iostream>
using namespace std;
void print(string line) {
cout << line;
}
void println(string line) {
cout << line << endl;
}
void printError(string message, string error, string file) {
cout << "An error occurred!" << endl;
cout << "Message: "+ message << endl;
cout << "Error: "+ error << endl;
if(file != "") {
cout << "File/Method: "+ file << endl;
}
}
File: main.cpp
#include <string>
#include <iostream>
#include "IO.cpp"
using namespace std;
int main()
{
println("Hello world!");
}
You should remove the line below from main.cpp
#include "IO.cpp"
And add following lines afer using namespace std
void print(string line);
void println(string line);
void printError(string message, string error, string file);
If you include a cpp file again which is also present in your project source list (files to be compiled), your program will get multiple definitions for the same functions which is not allowed in C++. On the other hand, the alternative suggested here consists of declarations of function, which is allowed to present several times, but must present atleast once before first use.
Standard practice is to move the declarations in a header file (for ex: IO.h) and include this header file in both IO.cpp and main.cpp
Further readings:
Difference between declarations and definitions
You included module IO.cpp in module main.cpp
#include "IO.cpp"
So you have gotten the function definitions in two modules: IO.cpp and in main cpp
You should create a header file for example IO.h and place there all function declarations. Then you have to include this header file in IO.cpp and main.cpp
For example
IO.h
#include <string>
void print( std::string line);
void println( std::string line);
void printError( std::string message, std::string error, std::string file);
IO.cpp
#include <string>
#include <iostream>
#include <IO.h>
using namespace std;
void print(string line) {
cout << line;
}
void println(string line) {
cout << line << endl;
}
void printError(string message, string error, string file) {
cout << "An error occurred!" << endl;
cout << "Message: "+ message << endl;
cout << "Error: "+ error << endl;
if(file != "") {
cout << "File/Method: "+ file << endl;
}
}
main.cpp
#include <IO.h>
//...
Related
This question already has answers here:
What advantages does C++20's std::source_location have over the pre-defined macros __FILE__, __LINE__ and __FUNCTION__?
(3 answers)
Closed 3 months ago.
Is it possible to print the caller source file name calling a function defined in another file, without passing __FILE__ explicitly and without using preprocessor tricks?
// Header.h
#include <iostream>
#include <string>
using namespace std;
void Log1(string msg) {
cout << __FILE__ << msg << endl; // this prints "Header.h"
}
void Log2(string file, string msg) {
cout << file << msg << endl;
}
inline void Log3(string msg) {
cout << __FILE__ << msg << endl; // this prints "Header.h"
}
// Source.cpp
#include "Header.h"
int main()
{
Log1(" Test 1");
Log2(__FILE__, " Test 2");
Log3(" Test 3");
}
With this code, this is what I get:
pathTo\Header.h Test 1
pathTo\Source.cpp Test 2
pathTo\Header.h Test 3
I would have expected the last call to print: pathTo\Source.cpp Test 3
You could use std::source_location:
// library.h
#pragma once
#include <source_location>
#include <string>
void Log(std::string msg, const std::source_location loc =
std::source_location::current());
// library.cpp
#include "library.h"
#include <iostream>
void Log(std::string msg, const std::source_location loc) {
std::cout << loc.file_name() << ' '<< msg << '\n';
}
// Source.cpp
#include "library.h"
int main() {
Log("Test 1"); // Prints "Source.cpp Test 1"
}
This requires C++20. Prior to C++20 you can use boost::source_location.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main() {
string txt="";
ifstream file;
file.open ("ernio.txt", ios::in);
if (file.is_open()) {
while (getline(file, txt)) {
cout << txt << endl;
}
}
else
cout << "example" << endl;
return 0;
}
It prints example instead of reading line by line from the file. What am I doing wrong?!? (the file is in the exact same place as the main.cpp) We even tried:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main() {
string txt="";
ifstream file("ernio.txt");
if (file.is_open()) {
while (getline(file, txt)) {
cout << txt << endl;
}
}
else
cout << "example" << endl;
return 0;
}
Please help
The file needs to be in the directory from where the executable will be called, not in the source directory where your main.cpp resides.
When you build small programs with gcc or something similar from the command line, often the executable is in the current working directory, where the compiler will also draw the source files from.
When using a build system or an IDE, however, then usually the target of a build is different from that where the sources reside.
I created this piece of code (using C++11 standards):
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
string input;
cout << "Enter the name of a file:\n";
getline(cin, input);
cout << "Reading file...\n";
ifstream readstream(input);
if (!readstream.is_open()) {
cout << "Error while opening file\n";
return 0;
} else {
string currentln;
while (getline(readstream, currentln)) {
cout << currentln;
}
return 0;
}
}
I compiled this code with the mingw-w64 implementation of GCC, with this command:
gcc -std=c++11 read.cpp -o read.exe
It compiled successfully, however, when I run it:
Enter the name of a file:
example.txt
Reading file...
And then nothing. It doesn't output any characters of the file. The file does exist, and it doesn't have any problems opening it. However, when I compile and run this code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
string input;
cout << "Enter the name of a file:\n";
getline(cin, input);
cout << "Reading file...\n";
ifstream readstream(input);
if (!readstream.is_open()) {
cout << "Error while opening file\n";
return 0;
} else {
char currentchar;
while (!readstream.eof()) {
while(readstream.get(currentchar)) {
cout << currentchar;
}
}
return 0;
}
}
It works.
I compiled it the same way:
g++ -std=c++11 read.cpp -o read.exe
But instead of using getline(), I used ifstream.get();
Can anyone tell me why getline() does not work in this situation?
I need to write two programs write.cpp & read.cpp to run simultaneously. One of them write(overwrite) to a file and the other one reads from it.
Basically, there is always only one line in the file.
write.cpp performs the operation successfully but read.cpp doesn't show anything. Using tail -f also shows incorrect result.
write.cpp:
#include <stdio.h>
#include <ctime>
#include <unistd.h>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main () {
ofstream myfile;
int i = 70;
char c;
while(i <85)
{
myfile.open ("example.txt");
c = i++;
myfile << c << endl;
myfile.close();
sleep(1);
}
return 0;
}
read.cpp:
#include <iostream>
#include <fstream>
#include <string>
#include <unistd.h>
using namespace std;
int main () {
string line;
ifstream myfile ("example.txt");
if (myfile.is_open())
{
while ( myfile.good() )
{
sleep(1);
getline (myfile,line);
cout << line << endl;
}
myfile.close();
}
else cout << "Unable to open file";
return 0;
}
May I know which part of both programs causes the problem and how may I solve it?
You're doing the right thing in the writer, but once you've read to end of file, the input stream becomes unusable until the fail condition is set. The best solution is probably to do exactly what you're doing in the writer: open and close the file each time in the read loop.
Be aware that there will be a moment when the file is empty; when you open the file for writing in the writer, it will be truncated, and if the reader happens to try to read at precisely this moment, it will find an empty file. (It's no big problem; just be aware of it, maybe skipping the sleep if you find an empty line.)
To add some detail to my answer to your previous question, here is how you could use Boost's interprocess communication to achieve this if you insist on using a file for ipc.
A writer may look like this:
#include <boost/interprocess/sync/file_lock.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <fstream>
#include <iostream>
int main()
{
using namespace boost::interprocess;
std::string line, shared_filename = "shared";
{
std::ofstream create_shared_file(shared_filename.c_str());
}
for (;;)
{
std::cout << "Enter some text: ";
std::cin >> line;
try
{
file_lock lock(shared_filename.c_str());
scoped_lock<file_lock> lock_the_file(lock);
std::ofstream shared_file(shared_filename.c_str(), std::ofstream::trunc);
shared_file << line << std::endl;
shared_file.flush();
}
catch (interprocess_exception const& e)
{
std::cerr << e.what() << std::endl;
}
}
}
The corresponding reader:
#include <boost/interprocess/sync/file_lock.hpp>
#include <boost/interprocess/sync/sharable_lock.hpp>
#include <fstream>
#include <iostream>
#include <unistd.h>
int main()
{
using namespace boost::interprocess;
std::string line, shared_filename = "shared";
for (;;)
{
try
{
file_lock lock(shared_filename.c_str());
std::cout << "Waiting for file lock..." << std::endl;
sharable_lock<file_lock> lock_the_file(lock);
std::cout << "Acquired file lock..." << std::endl;
std::ifstream shared_file(shared_filename.c_str());
shared_file >> line;
if (line.empty())
{
std::cout << "Empty file" << line << std::endl;
}
else
{
std::cout << "Read: " << line << std::endl;
}
}
catch (interprocess_exception const& e)
{
std::cerr << "Could not lock " << shared_filename << ": " << e.what() << std::endl;
}
std::cout << "Sleeping..." << std::endl;
sleep(2);
}
}
I have a function "PrintHeader" for my project, defined in io.cpp. Even though io.h is included in my main file, I get the error
error C3861: 'PrintHeader': identifier not found.
When I copy the function for PrintHeader into my main file, I get the errors
error LNK2005: 'void _cdeci PrintHeader(void)" (?PrintHeader##YAXXZ) already defined in io.obj.
and
error LNK1169: one or more multiply defined symbols found.
I can understand the second error set, since I do have it defined twice, but I don't understand why it doesn't work when I just remove the duplicate definition. Any help is greatly appreciated.
Main file
#include "stdio.h"
#include <iostream>
#include "io.h"
void PrintHeader()
{
cout << endl;
cout << "Month\tPrincipal\t Interest\t Balance" << endl;
cout << "-----\t---------\t---------\t---------" << endl;
}
int main()
{
cout << "Hello World\n";
PrintHeader();
getchar();
return 0;
}
io.cpp
#include <iostream>
#include <iomanip>
#include "io.h"
void PrintHeader (void)
{
cout << endl;
cout << "Month\tPrincipal\t Interest\t Balance" << endl;
cout << "-----\t---------\t---------\t---------" << endl;
}
io.h
#ifndef __IO_H__
#define __IO_H__
#include <string>
using namespace std;
void PrintHeader (void);
#endif
You are most likely including the wrong file in main.cpp. You can make sure it is the right file by right clicking on the include "io.h" and choosing open file.