simple c++ function inclusion failure - c++

I am trying to include a function from another file inside a "main" file. I'm following this paradigm:
http://www.learncpp.com/cpp-tutorial/18-programs-with-multiple-files/
Here is my main file, digispark.cpp:
#include <iostream>
using namespace std;
int send(int argc, char **argv);
int main()
{
char* on;
*on = '1';
char* off;
*off = '0';
send(1,&on);
return 0;
}
And here is my send.cpp:
#include <stdio.h>
#include <iostream>
#include <string.h>
#if defined WIN
#include <lusb0_usb.h> // this is libusb, see http://libusb.sourceforge.net/
#else
#include <usb.h> // this is libusb, see http://libusb.sourceforge.net/
#endif
// I've simplified the contents of send for my debugging and your aid, but the
// complicated arguments are a part of the function that will eventually need
// to be here.
int send (int argc, char **argv)
{
std::cout << "Hello";
return 0;
}
I'm compiling on Ubuntu 12.10 using the g++ compiler like so:
g++ digispark.cpp send.cpp -o digispark
It compiles successfully.
However, when I run the program, "Hello" does not come up. Therefore I don't believe the function is being called at all. What am I doing wrong? Any help would be great! Thanks!
EDIT:
How I dealt with the issue:
int send(int argc, char **argv);
int main()
{
char* on[4];
on[0] = (char*)"send";
on[1] = (char*)"1";
char* off[4];
off[0] = (char*)"send";
off[1] = (char*)"0";
send(2,on);
return 0;
}
For those of you who were confused as to why I insisted doing this, as I said before, the send function was already built to accept the char** argv (or char* argv[]). My point was to try to mimic that in my main function.
It would have been much more difficult to rewrite the function that actually goes in the send function to take a different type of argument than just to send in what it wanted. Thanks everyone!
So if this helps anyone trying something similar feel free to use it!

Your problem is not the one you think it is. It's here:
char* on;
*on = '1';
You declared a char pointer, but did not initialize it. Then you dereferenced it. Bang, you're dead. This is what is known as Undefined Behavior. Once you invoke U.B., anything can happen. If you're lucky, it's a crash. But I guess you weren't lucky this time.
Look, if you want to start storing things in memory, you have to allocate that memory first. The best way, as hetepeperfan said, is to just use std::string and let that class take care of all the allocating/deallocating for you. But if for some reason you think you have to use C-style strings and pointers, then try this:
char on[128]; //or however much room you think you'll need. Don't know? Maybe you shoulda used std::string ...
*on = '1';
*(on+1) = '\0'; //if you're using C-strings, better null terminate.
char off[128];
*off = '0';
*(off+1) = '\0';
send(1,&on);

ok I think you try to do something like the following, I tried to make it a bit more in the Style of C++ and prevent the use of pointers since they should not be necessary in the code that you showed.
digispark.cpp
#include "send.h"
int main (int argc, char** argv){
string on = "1";
string off = "0";
send ( on );
send ( off );
return 0;
}
send.cpp
#include <iostream>
#include <string>
void send( const std::string& s) {
std::cout << s << std::endl;
}
send.h
void send(const std::string& s);

Related

Using a program(.exe), inside a program, but passing command line arguments on linux C++

I've been trying to call a program inside another c++ program using the command "execvp()" from the <unistd.h> library but it gets core dump, and i dont know what i am doing wrong;
below its the code i use to call the program i want to use
#include <iostream>
#include <unistd.h>
int main(int argc, char **argv)
{
char *argument_list[]={argv[1],argv[2],NULL};
char *filename = "./bin/program.exe";
execvp(filename, argument_list);
return 0;
}
below this, its the code of the program i want to call
#include <iostream>
int main(int argc, char **argv)
{
int a = atoi(argv[1]);
int b = atoi(argv[2]);
std::cout << a+b<<std::endl;
return 0;
}
when i compile the the first code, i get a "main.exe" binary, then i type "main.exe 5 6" to sum both integers, and i get the "core dump" error.
Curious thing is, if i run gdb on it, i get the sum i want
the first command line, its running directly the "child" program, showing that it works. The second command line, its using the "main" program that calls the child one
(Obviously, this programs aren't the ones i need to apply this, they're just for illustration of the problem, they're really big codes, and it wouldn't be helpful to post them here);
How can i fix this?
So, it works if i set the first argument as the filename, as said by #WhozCraig, so now it works, and looks like this:
#include
#include <unistd.h>
int main(int argc, char **argv)
{
char *argument_list[]={"program.exe",argv[1],argv[2],NULL};
char *filename = "./bin/program.exe";
execvp(filename, argument_list);
return 0;
}
However, i get this warning:
1
How can i get around it? Is there a problem leaving it like this?

What is wrong with this C++ main method driver to run this method?

I'm doing C++ this semester (just finished learning Java) and using Codewars to get some practice (this has been my most effective way of practicing but it only requires the method not the driver) with my C++ coding but unsure how to create the driver for this method so I can practice in my IDE.
What am I missing here in the main so it runs in my IDE? The solution (not my code) works but my main method doesn't drive it.
#include <iostream>
#include <cctype>
#include <unordered_set>
int main(int argc, char *argv[]) {
using namespace std;
cout << is_isogram("Dermatoglyphics"); //error: use of undeclared identifier 'is_isogram'
}
bool is_isogram(std::string str) { //warning: Function is never used
std::unordered_set<char> char_set;
for (const auto &c : str) {
auto c_lower = std::tolower(c);
if (char_set.count(c_lower) == 0) char_set.insert(c_lower);
else return false;
}
return true;
}
At the point where you try to use is_isogram() in main(), it has not actually been declared yet, hence the "use of undeclared identifier" (a).
You can solve this in one of two ways, the first being to declare it with a function prototype before use, such as with:
bool is_isogram(std::string); # declare
int main(int argc, char *argv[]) { # define
// main stuff
}
bool is_isogram(std::string str) { # define
// is_isogram stuff
}
And the second is to swap is_isogram() and main() so that the declaration is done as part of the definition (defining something implicitly declares it):
bool is_isogram(std::string str) { # define
// is_isogram stuff
}
int main(int argc, char *argv[]) { # define
// main stuff
}
(a) The second reported issue, "function not used", is almost certainly just a side-effect of the first. Because the compiler couldn't do anything with the is_isogram() call from main(), it just throws it away after reporting the error. As a result, there is now no code that calls your function when you define it.

Main method is different to those in tutorials

So I am starting with c++ (i am trying to broaden my mind with new languages) but I came across a little issue which confuses me more than what I guess it should...
Using Visual Studio Express 2012, I created a console win32 application in C++ and this is my main method decleration:
// TestApp.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
however, since I dont know anything about c++, I searched for some tuts online and all of them had there declerations setup in a different manner
#include <iostream>
using namespace std;
int main()
{
cout<<"HEY, you, I'm alive! Oh, and Hello World!\n";
cin.get();
}
and
// my first program in C++
#include <iostream>
int main()
{
std::cout << "Hello World!";
}
I tried typing in the "std::cout", but it wouldnt accept it,
could someone just clarify why and the significance of the difference ?
The main method can be define with or without parameters. It all depends upon what you are using your application for.
Take a look at this: https://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fmainf.htm
Also for your program you need to have a return value
// my first program in C++
#include <iostream>
int main()
{
std::cout << "Hello World!";
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
is (at least I think so) a Windows only library and compiler depending way of declaring the main function.
Definitly not wrong is to declare main like this:
int main(int argc, char const *argv[])
{
//do something
return 0;
}
or like this:
int main()
{
//do something
return 0;
}
This is definitly proper C++ and you can use this universially.
C++ programs may have one of two beginnings:
int main(int argc, char *argv[])
or
int wmain(int argc, wchar_t *argv[])
The first of these gets its arguments (argv) as ANSI charachers, while the second gets "wide" characters -- generally UTF-16 or UTF-32, depending on the platform.
Microsoft define a framework to allow you make code that can compile with either ANSI or wide characters.
int _tmain(int argc, TCHAR *argv[])
Behind the scenes, they have something like this:
#if defined UNICODE
#define _tmain wmain
#define TCHAR wchar_t
#else
#define _tmain main
#define TCHAR char
#endif
They also have helper functions like _tprintf() and _tcscpy().
NOTE: as pointed out by others, the argc and argv params are optional, so you can also have
int main()
and
int wmain()
and (for Microsoft and compatible compilers)
int _tmain()
Also note that while _tmain() is not strictly portable, you can easily create your own #define macros if you want to be portable to other platforms.

Different output between release and Debug

I can't figure this one out. I have a c++ Application that works in Debug mode exactly as expected:
#include "stdafx.h"
#include <string>
#include <Windows.h>
#include <iostream>
using namespace std;
void truncateServer(std::string inString);
int _tmain(int argc, char *argv[])
{
char* server = argv[1];
truncateServer(server);
}
void truncateServer(std::string inString)
{
std::string server = "";
int whackCount = 0;
for (unsigned int i = 0; i < inString.length(); i++)
{
char c = inString[i];
if (whackCount < 3)
{
if (c == '\\') whackCount++;
else
server += c;
}
}
cout << server;
}
For example if I call the server I want via its UNC path \\serverName\Share\ in the debug it gives me exactly what I want: servername
However, if I use the release build I get nothing:
I deleted the release output folder, but the issue is exactly the same. I can only assume there is some other difference between the release and build applications that is exposing a major issue with my code? Or another difference between the outputs I need to account for.
What do I need to do to get the expected output?
It looks like your Debug build is set as Ansi and your release build as Unicode.
The _tmain declaration is a Visual Studio specific macro which changes the entry point of your application depending on the used charset.
For ANSI it maps to int main(int argc, char *argv[]) .
For Unicode it maps to int wmain(int argc, wchar_t *argv[]).
By using the char type as parameter to _tmain, you cause the compiler to use the wrong type when using an Unicode build, and so end up with a '\0' character as first byte, which std::string can't handle.
In your case, I recommend sticking to int main(int argc, char *argv[]) as it will work in all cases, especially with std::string which use chars.
Also, it is more portable across compilers and operating systems.

taking command line input in different ways

How can one take command line argument by not using below structure ?
int main ( int argc, char* argv ) {
}
My question is really : how can I take below input :
./executableProgramName inputX inputY inputZ inputT
in any function ?
in foo () {
// what should I write so that I can get same effect
}
Are there any other way for taking command line input ?
The method specified by the standard for getting command line arguments is the argc and argv parameters passed to the entry point function main. There's no other standard method.
Some platforms offer non-standard methods. For example, if you're on Windows you can use GetCommandLineW
Here's an example that uses some C++11 stuff too.
#include <ShellAPI.h> // for CommandLineToArgvW
#include <string>
#include <vector>
#include <codecvt>
#include <locale>
int main() {
#ifdef WIN32
LPWSTR *szArglist;
int argc;
szArglist = CommandLineToArgvW(GetCommandLineW(),&argc);
if(NULL==szArglist) {
std::cerr << "CommandLineToArgvW failed\n";
}
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>,wchar_t> convert; // codecvt_utf8 or codecvt<char16_t,char,mbstate_t> should work (will work once the char16_t specialization of codecvt works)
vector<string> args;
for(int i=0;i<argc;++i) {
args.push_back(convert.to_bytes(szArglist[i]));
}
#endif //ifdef WIN32
}
Maybe the best way is to forward the handling of command line arguments into an object, or simply a function:
#include <vector>
#include <string>
void handle_commandline_args(const std::vector<std::string>& args){
...
}
int main(int argc, char* argv[]){
handle_commandline_args(std::vector<string>(argv[0], argv[0] + argc));
...
}
You can not arbitrarily get the command-line arguments from any function. In C++, the only way command-line arguments are passed in is through the char* array in the main function.
If you want them to be accessible from anywhere, consider keeping them in a global variable, or passing them into each necessary function call. For example:
int argumentCount;
char **argumentArray;
int main ( int argc, char** argv )
{
argumentCount = argc;
argumentArray = argv;
}
int foo()
{
std::cout << argumentArray[0]; // or whatever
}
If you're working with MSVC++, then you can use below win32 API to get command line arguments anytime in your program:
GetCommandLine
However, this makes your code non-standard. So it is better if you use main(int argc, char *argv[]) to get the command line arguments and save them for later use, e.g to be used by other functions.