Sorry super noob question. I'm new to C++ and any sort of programming in general but I created these programs to read user input and then read what command and file it is. I want to include file a.h but I'm having trouble with it. It's telling me my function main is redefined but when I take it out it spits out more errors. I'm considering maybe an if else statement? Any advice to get me going?
File name tryout.cpp
#include <iostream>
#include <string.h>
#include "a.h"
using namespace std;
int main()
{
string cmd,command,file1,file2;
cout << "prompt<<";
cin >> cmd;
int len = cmd.length();
int temp = cmd.find('<');
command = cmd. substr(0,temp);
cout << "COMMAND: " << command << "\n";
cout << "File Redirection: " << cmd.at(temp) << "\n";
int temp1 = cmd.find('>');
file1 = cmd.substr(temp+1,temp1-temp-1);
cout << "FILE: " << file1 << "\n";
cout << "File Redirection: " << cmd.at(temp1) <<"\n";
file2 = cmd.substr(temp1+1, len-1);
cout << "File: " << file2 <<"\n";
return 0;
}
File name "a.h"
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
string cmd,command1,command2,command3;
cout << "prompt<<";
cin >> cmd;
int len = cmd.length();
int temp = cmd.find('|');
command1 = cmd.substr(0,temp);
cout << "COMMAND: " << command1 << "\n";
cout << "PIPE: " << cmd.at(temp) << "\n";
command2 = cmd.substr(temp+1,len-1);
cout << "COMMAND: " << command2 << "\n";
cout << "PIPE: " << cmd.at(temp) << "\n";
command3 = cmd.substr(temp+2,len-2);
cout << "COMMAND: " << command3 << "\n";
return 0;
}
The ".h" suffix is for a "header" file. If you think of a form letter, say from your cell company, at the top is a bunch of stuff telling you the company name, contact, etc.
A "header file" in C++ is a file that mostly provides definitions, things that you might need to share between multiple ".cpp" files. A ".cpp" file is generally a "compilation unit", a discrete file that the compiler is expected to turn into a similarly named "object file".
So in what you've shown us your division of interest is wrong. You've actually implemented main in the ".h" file.
When the compiler reads your ".cpp" file, it reads in the iostream and string.h headers, and then it reads in a.h, which includes an implementation of main. Then, it returns to processing tryout.cpp where it sees another implementation of main.
Solution: Remove main from a.h.
You cannot have multiple main() functions. When compiling, the C++ complier will take the content of the header files and add them where your #include statement is. If it finds more than one main() function, it does not know where to set the start point for the executable. You will have to rename the header file function to something else. Also note that it is common practice not to include function definitions in header files, rather than to use function declarations and have the definitions in other .cpp or pre-compiled .lib files.
I have found this article to be helpful for learning about how headers work.
You cannot have two main functions. If you want to include your file you should put everything in a function or better build a class.
Related
I'm trying to expand my C++ game hacking skills as when I was starting (2 years ago) I made a bad decision: continue in game hacking with vb.net instead of learning c++ (as I had some vb.net knowledge and 0 knowledge with other languages)
So, now as the very first steps I have to create my toolkit, where I will be using my own templates:
Nathalib.h (my template with all common functions for game hacking).
#pragma once
#include <iostream>
#include <Windows.h>
#include <string>
#include <TlHelp32.h>
#include <stdio.h>
using namespace std;
DWORD ProcessID;
int FindProcessByName(string name)
{
HWND hwnd = FindWindowA(0, name);
GetWindowThreadProcessId(hwnd, &ProcessID);
if (hwnd)
{
return ProcessID;
}
else
{
return 0;
}
}
Hack.cpp (obviously the cheat, will be different for every game).
#pragma once
#include "pch.h"
#include <iostream>
#include <Windows.h>
#include <string>
#include <Nathalib.h>
using namespace std;
int main()
{
While(True)
{
cout << FindProcessByName("Calculator") << endl;
getchar();
cout << "-----------------------------------" << endl << endl;
}
return 0;
}
Target.cpp (as we're not bad boys, I must provide my own target).
#include "pch.h"
#include <iostream>
#include <Windows.h>
#include <string>
using namespace std;
#define CHAR_ARRAY_SIZE 128
int main()
{
int varInt = 123456;
string varString = "DefaultString";
char arrChar[CHAR_ARRAY_SIZE] = "Long char array right there ->";
int * ptr2int;
ptr2int = &varInt;
int ** ptr2ptr;
ptr2ptr = &ptr2int;
int *** ptr2ptr2;
ptr2ptr2 = &ptr2ptr;
while(True) {
cout << "Process ID: " << GetCurrentProcessId() << endl;
cout << "varInt (0x" << &varInt << ") = " << varInt << endl;
cout << "varString (0x" << &varString << ") = " << varString << endl;
cout << "varChar (0x" << &arrChar << ") = " << arrChar << endl;
cout << "ptr2int (0x" << hex << &ptr2int << ") = " << ptr2int << endl;
cout << "ptr2ptr (0x" << hex << &ptr2ptr << ") = " << ptr2ptr << endl;
cout << "ptr2ptr2 (0x" << hex << &ptr2ptr2 << ") = " << ptr2ptr2 << endl;
cout << "Press ENTER to print again." << endl;
getchar();
cout << "-----------------------------------" << endl << endl;
}
return 0;
}
I don't know why the header file is not being recognized.
This is the correct way to include header files? Should I create a namespace/class/object for calling it?
It's the correct way creating a header file? Or I should create another kind of project/resource for this purpose?
How should I call my library methods? Like LibraryName.MethodName?
I just come from other languages and some ideas/features are not available in the other languages (that's why I'm interested in this one)
If there's something I forgot to add, please tell me and I will update
Thanks
There are multiple errors - please check your textbook.
You include your own headers with #include "". System headers are included with #include<>
The header file generally contains function declarations. Function bodies go into the corresponding .cpp file.
You call your library functions by their name. If they're in a namespace, that might mean the format is namespacename::functionname(arguments).
There are two ways to include headers, using "" or <>
with <> the file will be searched in the system search path (which is not the $PATH variabel, but the list of paths provided with `-I' together with standard headers already known by compiler) and included if found
with "" the file will be search in the current folder and in the system search path
Assuming your header is in th esame folder of hack.cpp, you should use
#include "Nathalib.h"
First off, your header lacks include guards, #pragma once only works with msvc++.
Your header file is probably not in PATH, so you need to specify it's path relative to your project. If your header file is in the same root as your cpp file, all you need to do is change the include statement for that header file to #include "Nathalib.h" otherwise you'll have to specify the relative path.
To add to other aswers- why you should put declaration of function in .h file, while its definition to .cpp file: Writing function definition in header files in C++
I suggest to find some c++ tutorials for example: http://www.tutorialspoint.com/cplusplus/cpp_functions.htm
You should learn tutorials first, making some exercises on simply code. Personally I prefer check then most simply code for new programming construct. Then more complicated.
After such learning you may use for reference also : http://www.cplusplus.com and https://en.cppreference.com/w/
I have a class where I store a filename that a user has provided:
string EMNfn; // IDF file EMN name
// IDF file EMN name
void CcaAna::put_EMNfn(string s)
{
CcaAna::EMNfn = s;
}
string CcaAna::get_EMNfn()
{
return EMNfn;
}
However, when I try to open the file, and I know it exists in the current directory that I am using with the following:
femn.open(cCCA.get_EMNfn());
I get a compile error C2664 ...cannot convert parameter 1 from 'class std::basic_string,class std::allocator >' to 'const char *'
When I try using:
femn.open(cCCA.get_EMNfn().c_str());
it compiles but trips my error code:
if(!femn)
{
cout << "Open of Original EMN file failed\n";
cout << "EMN file: " << cCCA.get_EMNfn() << endl;
cout << "Press any key to exit" << endl;
ch = getchar();
return 1;
}
However when I type it in directly everthing works fine:
femn.open("262-003841-7-23.emn");
running out of ideas is there another way to open the stream?
molbdnilo - I think you are on to something (see below)
OK I added the two COUT lines after and I have included the OUTPUT below the code:
cout << "EMN file: " << cCCA.get_EMNfn() << endl;
// THIS WORKS
// femn.open("262-003841-7-23.emn");
femn.open(cCCA.get_EMNfn().c_str());
// femn.open(cCCA.get_EMNfn());
cout << "this works: " << "262-003841-7-23.emn" << endl;
cout << "*****" << cCCA.get_EMNfn() << "*****" << endl;
OUTPUT:
PROCESSING USER INPUT FILE ...
EMN file: "262-003841-7-23.emn"
this works: 262-003841-7-23.emn
*****"262-003841-7-23.emn"*****
Open of Original EMN file failed
EMN file: "262-003841-7-23.emn"
Press any key to exit
What I am seeing is that the stored string has " around it. Is there a C++ way to remove those?
You are not assigning strings correctly!string variables should not be assigned with = operator . Here is a reference for working with strings.
There are lots of ways for doing your task here is one:
#include <string.h>
...
strcpy(CcaAna::EMNfn,s);//instead of CcaAna::EMNfn=s;
maybe this might work,if not check the link and use a correct way to work with strings.
cheers
so I worked on my program and now I am on a point where I can not find a solution. I need to replace some more signs in the fext file, for now the program only replaces "TIT" with the code number "*245$a", if I want to replace other letters the same way, the program does not change. Does anybody know how I can implement some more replacements in the text file? Let me know if there is a better option to replace more than 5 signs with another ones.
Thank you
#include <fstream>
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{
char dateiname[64], kommando[64];
ifstream iStream;
cout << "Choose an activity" << endl <<
" s - search " << endl <<
" c - convert" << endl <<
" * - end program" << endl;
cin.getline(kommando,64,'\n');
switch(kommando[0])
{
case 'c':
cout << "Enter a text file!" << endl;
cin.getline(dateiname,64,'\n');
iStream.open("C://users//silita//desktop//schwarz.txt");
case 's':
break;
case '*':
return 0;
default:
cout << "I can not read " << kommando << endl;
}
if (!iStream)
{
cout << "The File" << dateiname << "does not exist." << endl;
}
string s;
char o[] = "TIT";
while (getline(iStream, s))
{
while(s.find(o, 0) < s.length())
s.replace(s.find(o, 0), s.length() - s.find(o, 3),"*245$a");
cout << s << endl;
}
iStream.close();
}
You can use map in C++ STL to store multiple convert rules:
#include<map>
#include<algorithm>
using namespace std;
map<string,string> convertRules;
typedef map<string,string>::iterator MIT;
void setConvertRules(int numOfRules){
string word,code;
for(int i = 0 ; i < numOfRules; ++i){
cin>>word>>code;
//Use code as search key in order to decrypt
//If you want to encrypt, use convertrules[word] = code;
convertRules[code] = word;
}
}
To convert a file, just do as follows (some functions and classes need to be declared and implemented first, but here we mainly focus on top-level design):
/* Detailed class implementations are omitted for simplicity */
//a class to store contents of a file
class File;
//a processor to read, insert and overwrite certain file
class FileProcessor;
void FileProcessor::convert(const string &code, const string &word){
cursor == file.begin();
while(cursor != fp.end()){
_fp.convertNextLine(code,word);
}
}
File file;
FileProcessor filePcr;
int main()
const string sourceDir = "C://users//silita//desktop//schwarz.txt";
const string destDir = "C://users//silita//desktop//schwarz_decrypted.txt";
//Open a .txt file and read in its contents
if (!file.openAndReadIn(sourceDir)){
cerr << "The File" << sourceDir << "does not exist." << endl;
abort();
}
//Try to link processor to open file
if(!fp.linkTo(file)){
cerr << "Access to file" << sourceDir << "is denied." << endl;
abort();
}
//iterator is like a more safe version of C-style pointer
//the object type is a string-string pair
for(MIT it = convertRules.begin(); it != convertRules.end(); ++it){
fp.convert(it->first, it->second);
}
file.saveAs(destDir);
return 0;
}
Finally, if I would suggest you use C-style strstr function for efficiency when dealing with large files or batch processing. string::find adopts a naive sequential search startegy while strstr is implemented with the famous KMP algorithm for fast pattern match in strings, which is both efficient and thorough(can replace all matchs in one go instead of another for-loop).
This very well could be a syntax error on my part since I am rather new with using multiple files and structs in C++ (in particular, passing structs to functions). Here are the three files:
main.cpp:
#include <iostream>
#include <fstream>
#include <string>
#include "common.h"
using namespace std;
void honorStatus(int, student studentList[]);
int main(void)
{
int header;
string filename;
ifstream inputFile;
student studentList[MAX_STUDENTS];
// Get filename from user and try to open file
cout << "Please enter a filename: ";
cin >> filename;
inputFile.open(filename.c_str());
// If file cannot be opened, output error message and close program
if (inputFile.fail())
{
cout << "Input file could not be opened. Please try again." << endl;
return 1;
}
// Get header number from file. If header is larger than max number
// of students, error is output and program is closed
inputFile >> header;
if (header > MAX_STUDENTS)
{
cout << "Number of students has exceeded maximum of " << MAX_STUDENTS
<< ". Please try again." << endl;
return 1;
}
// Read file information (student ID, hours, and GPA) into struct array
for (int i = 0; i < header; i++)
{
inputFile >> studentList[i].ID >> studentList[i].hours >> studentList[i].GPA;
}
// Close the file
inputFile.close();
// Calls function honorStatus
honorStatus(header, studentList);
return 0;
}
functs.cpp:
#include <iostream>
#include "common.h"
using namespace std;
// Function to determine classification and honors society eligibility requirements
// of each student, outputting this information and the number of students eligible
void honorStatus(int fheader, student fstudentList[])
{
int cnt = 0;
for (int i = 0; i < fheader; i++)
{
if (fstudentList[i].hours < 30)
{
cout << "Student #" << fstudentList[i].ID << " is a freshman with GPA of "
<< fstudentList[i].GPA << ". Not eligible." << endl;
}
else if (fstudentList[i].hours > 29 && fstudentList[i].hours < 60)
{
if (fstudentList[i].GPA >= 3.75)
{
cout << "Student #" << fstudentList[i].ID << " is a sophomore with GPA of "
<< fstudentList[i].GPA << ". Eligible." << endl;
cnt++;
}
else
{
cout << "Student #" << fstudentList[i].ID << " is a sophomore with GPA of "
<< fstudentList[i].GPA << ". Not Eligible." << endl;
}
}
else if (fstudentList[i].hours > 59 && fstudentList[i].hours < 90)
{
if (fstudentList[i].GPA >= 3.5)
{
cout << "Student #" << fstudentList[i].ID << " is a junior with GPA of "
<< fstudentList[i].GPA << ". Eligible." << endl;
cnt++;
}
else
{
cout << "Student #" << fstudentList[i].ID << " is a junior with GPA of "
<< fstudentList[i].GPA << ". Not eligible." << endl;
}
}
else
{
if (fstudentList[i].GPA >= 3.25)
{
cout << "Student #" << fstudentList[i].ID << " is a senior with GPA of "
<< fstudentList[i].GPA << ". Eligible." << endl;
cnt++;
}
else
{
cout << "Student #" << fstudentList[i].ID << " is a senior with GPA of "
<< fstudentList[i].GPA << ". Not eligible." << endl;
}
}
}
cout << "\nTotal number of students eligible for the Honor Society is " << cnt << "." << endl;
}
common.h:
// Maximum number of students allowed
const int MAX_STUDENTS = 10;
// Struct for student info
struct student
{
int ID;
int hours;
float GPA;
};
When using TextPad/G++, I get the following error:
/cygdrive/c/Users/Korina/AppData/Local/Temp/ccxq9DAh.o:p7b.cpp:(.text+0x0): multiple definition of `main'
/cygdrive/c/Users/Korina/AppData/Local/Temp/ccmtzOP2.o:p5.cpp:(.text+0x0): first defined here
/cygdrive/c/Users/Korina/AppData/Local/Temp/ccLa96oD.o:test.cpp:(.text+0x0): multiple definition of `main'
/cygdrive/c/Users/Korina/AppData/Local/Temp/ccmtzOP2.o:p5.cpp:(.text+0x0): first defined here
/usr/lib/gcc/i686-pc-cygwin/4.8.2/../../../../i686-pc-cygwin/bin/ld: /cygdrive/c/Users/Korina/AppData/Local/Temp/ccmtzOP2.o: bad reloc address 0x1b in section `.text$_ZNSt11char_traitsIcE7compareEPKcS2_j[__ZNSt11char_traitsIcE7compareEPKcS2_j]'
collect2: error: ld returned 1 exit status
When using an online C++ compiler (CompileOnline), I get:
/tmp/ccIMwHEt.o: In function `main':
main.cpp:(.text+0x1cf): undefined reference to `honorStatus(int, student*)'
collect2: error: ld returned 1 exit status
I wasn't able to find a guide on how to set up TextPad/G++ to compile and link multiple files, but my instructor gave a short set of instructions that I followed. Here is how it's set up:
So this could a two-parter question (how do I set up TextPad to correctly compile/link files? why is my honorStatus() function undefined in main.cpp?) or it could just be that my syntax is wrong. I'm honestly not sure. Sorry if this is a bit long; I wanted to include as much detail as possible. Any help is greatly appreciated.
The problem is that you are compiling "*.cpp" all together. Given this
/cygdrive/c/Users/Korina/AppData/Local/Temp/ccxq9DAh.o:p7b.cpp:(.text+0x0): multiple definition of `main'
/cygdrive/c/Users/Korina/AppData/Local/Temp/ccmtzOP2.o:p5.cpp:(.text+0x0): first defined here
/cygdrive/c/Users/Korina/AppData/Local/Temp/ccLa96oD.o:test.cpp:(.text+0x0): multiple definition of `main'
/cygdrive/c/Users/Korina/AppData/Local/Temp/ccmtzOP2.o:p5.cpp:(.text+0x0): first defined here
/usr/lib/gcc/i686-pc-cygwin/4.8.2/../../../../i686-pc-cygwin/bin/ld: /cygdrive/c/Users/Korina/AppData/Local/Temp/ccmtzOP2.o: bad reloc address 0x1b in section `.text$_ZNSt11char_traitsIcE7compareEPKcS2_j[__ZNSt11char_traitsIcE7compareEPKcS2_j]'
collect2: error: ld returned 1 exit status
we can see that the the compiler has been trying to combine p5.cpp, p7b.cpp and test.cpp into one executable (possibly other .cpp files too).
You need to actually tell the compiler exactly which files you want to build together to one program. E.g.
g++ main.cpp functs.cpp -o main.exe
(I would suggest also adding -Wall -Wextra -Werror to the compile line, as that allows the compiler to detect the small mistakes that aren't strictly errors, but where you probably got something wrong)
From the linker output you can see that main function is found in these files: p7b.cpp, p5.cpp and test.cpp. As there's no main.cpp file listed in the linker output, I guess that current directory is setup to be where p7b.cpp and other files are located.
Try to change Initial Folder to be where your main.cpp file is set (something like /cygdrive/c/Users/Korina/programming/). Also, remove all unrelevant files from that directory, as you're compiling all cpp files.
The error message is clear enough. Your project contains the following files
p7b.cpp, p5.cpp, test.cpp
where in each file there is defined function main. Put a place in order with your project files.
As for the error message when you use the inline compiler then it seems module functs.cpp is not included in the project. So the compiler does not see the function definition.
I have a C++ program which dumps out a C++ program. Some of the functions are boiler plate code and certain functions has boiler plate code and code tailored based on a few variables.
A simplified example is presented below:
// Snippet: 1
#include <fstream>
using namespace std;
int main()
{
ofstream fout("output.cc");
// bp() has just boiler plate code
fout << "void bp() {" << endl;
fout << "std::cout << \"Hello World!\" << std::endl" << endl;
// a few hundred lines of C++ code send to fout
fout << "}" << endl;
// mix() has boiler plate + some custom code
int size = 4096;
fout << "void mix() {" << endl;
fout << "char buffer[" << size << "];" << endl;
// a few hundred lines of C++ code send to fout
fout << "}" << endl;
// compile output.cc into *.so and delete output.cc
return 0;
}
The output.cc gets compiled and user gets the *.so file. The user does not have access to output.cc.
I wanted to rewrite this since it is difficult to read the boiler plate code when it is inside fout and having escaped quotes makes it a nightmare. Hence I thought of storing the functions in a separate file. For example have bp() in bp.cc:
// file: bp.cc
void bp() {
std::cout << "Hello World" << std::endl
// a few hundred lines of C++ code
}
Then the main file can be written as
int main()
{
std::ifstream src("bp.cc");
std::ofstream dst("output.cc");
dst << src.rdbuf();
}
In case of mix() I would use the Form-Letter Programming by storing the function mix() in mix.cc.
When the functions bp() and mix() were dumped using fout as in Snippet:1, all I had to do was ship the executable since the Snippet:1 is self-contained. But
If I split the functions into separate files `bp()` into `bp.cc` and `mix()` into `mix.cc` how do I ship it as a single executable? I need to ship `bp.cc` and `mix.cc` along with the executable. I do not want the user to access `bp.cc` and `mix.cc`.
Is there a better way to rewrite the `Snippet:1` than what I have suggested to better suit my needs?
You can use raw string literals and just put the code into one of those:
#include <iostream>
char const source[] = R"end(
#include <iostream>
int main() {
std::cout << "hello, world\n";
}
)end";
int main()
{
std::cout << source;
}