How do I open a URL from C++? - html

how can I open a URL from my C++ program?
In ruby you can do
%x(open https://google.com)
What's the equivalent in C++? I wonder if there's a platform-independent solution. But if there isn't, I'd like the Unix/Mac better :)
Here's my code:
#include <stdio.h>
#include <string.h>
#include <fstream>
int main (int argc, char *argv[])
{
char url[1000] = "https://www.google.com";
std::fstream fs;
fs.open(url);
fs.close();
return 0;
}

Your question may mean two different things:
1.) Open a web page with a browser.
#include <windows.h>
#include <shellapi.h>
...
ShellExecute(0, 0, L"http://www.google.com", 0, 0 , SW_SHOW );
This should work, it opens the file with the associated program. Should open the browser, which is usually the default web browser.
2.) Get the code of a webpage and you will render it yourself or do some other thing. For this I recommend to read this or/and this.
I hope it's at least a little helpful.
EDIT: Did not notice, what you are asking for UNIX, this only work on Windows.

Use libcurl, here is a simple example.
EDIT: If this is about starting a web browser from C++, you can invoke a shell command with system on a POSIX system:
system("<mybrowser> http://google.com");
By replacing <mybrowser> with the browser you want to launch.

Here's an example in windows code using winsock.
#include <winsock2.h>
#include <windows.h>
#include <iostream>
#include <string>
#include <locale>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
string website_HTML;
locale local;
void get_Website(char *url );
int main ()
{
//open website
get_Website("www.google.com" );
//format website HTML
for (size_t i=0; i<website_HTML.length(); ++i)
website_HTML[i]= tolower(website_HTML[i],local);
//display HTML
cout <<website_HTML;
cout<<"\n\n";
return 0;
}
//***************************
void get_Website(char *url )
{
WSADATA wsaData;
SOCKET Socket;
SOCKADDR_IN SockAddr;
int lineCount=0;
int rowCount=0;
struct hostent *host;
char *get_http= new char[256];
memset(get_http,' ', sizeof(get_http) );
strcpy(get_http,"GET / HTTP/1.1\r\nHost: ");
strcat(get_http,url);
strcat(get_http,"\r\nConnection: close\r\n\r\n");
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
{
cout << "WSAStartup failed.\n";
system("pause");
//return 1;
}
Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
host = gethostbyname(url);
SockAddr.sin_port=htons(80);
SockAddr.sin_family=AF_INET;
SockAddr.sin_addr.s_addr = *((unsigned long*)host->h_addr);
cout << "Connecting to "<< url<<" ...\n";
if(connect(Socket,(SOCKADDR*)(&SockAddr),sizeof(SockAddr)) != 0)
{
cout << "Could not connect";
system("pause");
//return 1;
}
cout << "Connected.\n";
send(Socket,get_http, strlen(get_http),0 );
char buffer[10000];
int nDataLength;
while ((nDataLength = recv(Socket,buffer,10000,0)) > 0)
{
int i = 0;
while (buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r')
{
website_HTML+=buffer[i];
i += 1;
}
}
closesocket(Socket);
WSACleanup();
delete[] get_http;
}

I was having the exact same problem in Windows.
I noticed that in OP's gist, he uses string("open ") in line 21, however, by using it one comes across this error:
'open' is not recognized as an internal or external command
After researching, I have found that open is MacOS the default command to open things. It is different on Windows or Linux.
Linux: xdg-open <URL>
Windows: start <URL>
For those of you that are using Windows, as I am, you can use the following:
std::string op = std::string("start ").append(url);
system(op.c_str());

I've had MUCH better luck using ShellExecuteA(). I've heard that there are a lot of security risks when you use "system()". This is what I came up with for my own code.
void SearchWeb( string word )
{
string base_URL = "http://www.bing.com/search?q=";
string search_URL = "dummy";
search_URL = base_URL + word;
cout << "Searching for: \"" << word << "\"\n";
ShellExecuteA(NULL, "open", search_URL.c_str(), NULL, NULL, SW_SHOWNORMAL);
}
p.s. Its using WinAPI if i'm correct. So its not multiplatform solution.

There're already answers for windows. In linux, I noticed open https://www.google.com always launch browser from shell, so you can try:
system("open https://your.domain/uri");
that's say
system(("open "s + url).c_str()); // c++
https://linux.die.net/man/1/open

C isn't as high-level as the scripting language you mention. But if you want to stay away from socket-based programming, try Curl. Curl is a great C library and has many features. I have used it for years and always recommend it. It also includes some stand alone programs for testing or shell use.

For linux environments, you can use xdg-open. It is installed by default on most distributions. The benefit over the accepted answer is that it opens the user's preferred browser.
$ xdg-open https://google.com
$ xdg-open steam://run/10
Of course you can wrap this in a system() call.

Create a function and copy the code using winsock which is mentioned already by Software_Developer.
For Instance:
#ifdef _WIN32
// this is required only for windows
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
{
//...
}
#endif
winsock code here
#ifdef _WIN32
WSACleanup();
#endif

Related

texinfo include HTML header from file

I am writing a Texinfo manual, and for its HTML I need to include the contents of another file into the <head> ... </head> section of the HTML output. To be more specific, I want to add mathjax capability to the HTML version of the output to show equations nicely. But I can't seem to find how I can add its <script>...</script> to the header!
Since I couldn't find an answer and doing the job my self didn't seem to hard, I wrote a tiny C program to do the job for me. It did the job perfectly in my case!
Ofcourse, if there is an option in Texinfo that does the job, that would be a proper answer, this is just a remedy to get things temporarily going for my self.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ADDTOHEADER " \n\
<script type=\"text/javascript\" \n\
src=\"http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML\">\n\
</head>"
void
addtexttohtml(char *filename)
{
char toadd[]=ADDTOHEADER;
size_t len=0;
ssize_t read;
FILE *in, *out;
char tmpname[]="tmp457204598345.html", *line=NULL;
in=fopen(filename, "r");
out=fopen(tmpname, "w");
if (in == NULL) exit(EXIT_FAILURE);
if (out == NULL) exit(EXIT_FAILURE);
while ((read = getline(&line, &len, in)) != -1)
{
if(strcmp(line, "</head>\n")==0) break;
fprintf(out, "%s", line);
}
fprintf(out, "%s", toadd);
while ((read = getline(&line, &len, in)) != -1)
fprintf(out, "%s", line);
if(line)
free(line);
fclose(in);
fclose(out);
rename(tmpname, filename);
}
int
main(int argc, char *argv[])
{
int i;
for(i=1;i<argc;i++)
addtexttohtml(argv[i]);
return 0;
}
This program can easily be compiled with $ gcc addtoheader.c.
Then we can easily put the compiled program (by default it should be called a.out) with the HTML files and run:
$ a.out *.html
You can just change the macro for any text you want.

qt creator error: LNK 2019: unresolved external symbol “__declspec(dllimport) public: void__thiscall

I would like to know why I am getting these errors.I am using Qt 5.0.2 and msvc2010 compiler. It runs normally when i delete the blah function.
I'm not an expert programmer at all, please answer me as if i dont know anything, thank you!
Error:
http://puu.sh/3m6Qr.png
My codes below:
.pro
QT += core gui
QT += widgets
QT += network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = guangdong
TEMPLATE = app
SOURCES += main.cpp\
login.cpp
HEADERS += login.h
FORMS += login.ui
login.cpp
#include "login.h"
#include "ui_login.h"
#include <QtSql/QSql>
#include <QtSql/QSqlDatabase>
#include <QDebug>
#include <Query.h>
#include <QString>
#include <QtSql/QSqlQuery>
#include <QtNetwork/QNetworkInterface>
login::login(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::login)
{
ui->setupUi(this);
blah();
}
login::~login()
{
delete ui;
}
void login::blah()
{
// QSqlQuery query;
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("blah");
db.setDatabaseName("blah");
db.setUserName("blah");
db.setPassword("blah");
bool ok = db.open();
if ( ok ) {
ui->label->setText("databaseopen");
db.close();
}
else
ui->label->setText("Error opening");
}
main.cpp
#include "login.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
login w;
w.show();
return a.exec();
}
EDIT: I added Qt += sql and #include but now i get this error.
Error:
http://puu.sh/3maq2.png
The error messages say the linker cannot find the external symbols defined in the header <QtSql/QSqlQuery>. You need to link against QtSql library/module: http://qt-project.org/doc/qt-5.0/qtsql/qtsql-index.html
QT += core gui
QT += widgets
QT += network
QT += sql
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = guangdong
TEMPLATE = app
SOURCES += main.cpp\
login.cpp
HEADERS += login.h
FORMS += login.ui
Run qmake after you update your .pro file and also you are adding the widgets module twice and that can also cause troubles:
QT += core gui
//QT += widgets delete this line Qt4 doesn't have widgets and for Qt 5 the widgets are added at the last line
QT += network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
for more complicated stuff you can use *= operator to ensure that a value is added to the list of values in a variable only once.

Downloaded page source is different than the rendered page source

I'm planning to get data from this website
http://www.gpw.pl/akcje_i_pda_notowania_ciagle
(it's a site of the main stock market in Poland)
I've got a program written in C++ that downloads source of the site to the file.
But the problem is that it doesn't contain thing I'm interested in
(stocks' value of course).
If you compare this source of the site to the option "View element" ( RMB -> View element)
you can see that "View element" does contain the stocks' values.
<td>75.6</td>
<tr class="even red">
etc etc...
The downloaded source of the site doesn't have this information.
So we've got 2 questions
1) Why does source of the site is different from the "View element" option?
2) How to transfer my program so that it can download the right code?
#include <string>
#include <iostream>
#include "curl/curl.h"
#include <cstdlib>
using namespace std;
// Write any errors in here
static char errorBuffer[CURL_ERROR_SIZE];
// Write all expected data in here
static string buffer;
// This is the writer call back function used by curl
static int writer(char *data, size_t size, size_t nmemb,
string *buffer)
{
// What we will return
int result = 0;
// Is there anything in the buffer?
if (buffer != NULL)
{
// Append the data to the buffer
buffer->append(data, size * nmemb);
// How much did we write?
result = size * nmemb;
}
return result;
}
// You know what this does..
void usage()
{
cout <<"curltest: \n" << endl;
cout << "Usage: curltest url\n" << endl;
}
/*
* The old favorite
*/
int main(int argc, char* argv[])
{
if (argc > 1)
{
string url(argv[1]);
cout<<"Retrieving "<< url << endl;
// Our curl objects
CURL *curl;
CURLcode result;
// Create our curl handle
curl = curl_easy_init();
if (curl)
{
// Now set up all of the curl options
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer);
curl_easy_setopt(curl, CURLOPT_URL, argv[1]);
curl_easy_setopt(curl, CURLOPT_HEADER, 0);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);
// Attempt to retrieve the remote page
result = curl_easy_perform(curl);
// Always cleanup
curl_easy_cleanup(curl);
// Did we succeed?
if (result == CURLE_OK)
{
cout << buffer << "\n";
exit(0);
}
else
{
cout << "Error: [" << result << "] - " << errorBuffer;
exit(-1);
}
}
}
return 0;
}
Because the values are filled in using JavaScript.
"View source" shows you the raw source for the page, while "View Element" shows you the state the document tree is in at the moment.
There's no simple way to fix it, because you need to either execute the JavaScript or port it to C++ (and it would probably make you unpopular at the exchange).
When I save the page as an html file (file/save as), I get a file containing all data displayed in browser and which was not found in page source (I use Chrome).
So I suggest that you add one step in your code:
Download page from a javascript enabled browser that support command line or some sort of API (If curl can't do it, maybe wget or lynx/links/links2/elinks on linux can help you?).
Parse data.

How to use tcl apis in a c code

I want to use some of the functionalities(APIs) of my tcl code in another "c" code file. But i am not getting how to do that especiallly how to link them. For that i have taken a very simple tcl code which contains one API which adds two numbers and prints the sum. Can anybody tell me how can i call this tcl code to get the sum. How can i write a c wrapper that will call this tcl code. Below is my sample tcl program that i am using :
#!/usr/bin/env tclsh8.5
proc add_two_nos { } {
set a 10
set b 20
set c [expr { $a + $b } ]
puts " c is $c ......."
}
To evaluate a script from C code, use Tcl_Eval() or one of its close relatives. In order to use that API, you need to link in the Tcl library, initialize the Tcl library and create an interpreter to hold the execution context. Plus you really ought to do some work to retrieve the result and print it out (printing script errors out is particularly important, as that helps a lot with debugging!)
Thus, you get something like this:
#include <tcl.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
Tcl_Interp *interp;
int code;
char *result;
Tcl_FindExecutable(argv[0]);
interp = Tcl_CreateInterp();
code = Tcl_Eval(interp, "source myscript.tcl; add_two_nos");
/* Retrieve the result... */
result = Tcl_GetString(Tcl_GetObjResult(interp));
/* Check for error! If an error, message is result. */
if (code == TCL_ERROR) {
fprintf(stderr, "ERROR in script: %s\n", result);
exit(1);
}
/* Print (normal) result if non-empty; we'll skip handling encodings for now */
if (strlen(result)) {
printf("%s\n", result);
}
/* Clean up */
Tcl_DeleteInterp(interp);
exit(0);
}
I think i have sloved it out. You were correct. The problem was with the include method that i was using. I have the files tcl.h, tclDecls.h and tclPlatDecls.h included in the c code but these files were not existing in the path /usr/include so i was copying these files to that directory, may be it was not a proper way to do. Finally i have not copied those files to /usr/include and gave the include path while compiling. I have created executable and it is givingthe proper result on terminal. Thanks for your help.
Here is the exact c code i am using :
#include <tcl.h>
#include <tclDecls.h>
#include <tclPlatDecls.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char **argv) {
Tcl_Interp *interp;
int code;
char *result;
printf("inside main function \n");
// Tcl_InitStubs(interp, "8.5", 0);
Tcl_FindExecutable(argv[0]);
interp = Tcl_CreateInterp();
code = Tcl_Eval(interp, "source simple_addition.tcl; add_two_nos");
/* Retrieve the result... */
result = Tcl_GetString(Tcl_GetObjResult(interp));
/* Check for error! If an error, message is result. */
if (code == TCL_ERROR) {
fprintf(stderr, "ERROR in script: %s\n", result);
exit(1);
}
/* Print (normal) result if non-empty; we'll skip handling encodings for now */
if (strlen(result)) {
printf("%s\n", result);
}
/* Clean up */
Tcl_DeleteInterp(interp);
exit(0);
}
And to compile this code and to generate executable file i am using below command :
gcc simple_addition_wrapper_new.c -I/usr/include/tcl8.5/ -ltcl8.5 -o simple_addition_op
I have executed the file simple_addition_op and got below result which was proper
inside main function
c is 30 .......
My special thanks to Donal Fellows and Johannes

"unable to include mysql.h" in C program [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How to make #include <mysql.h> work?
I need to connect C and mysql
This is my program
#include <stdio.h>
#include <mysql.h>
#define host "localhost"
#define username "root"
#define password "viswa"
#define database "dbase"
MYSQL *conn;
int main()
{
MYSQL_RES *res_set;
MYSQL_ROW row;
conn = mysql_init(NULL);
if( conn == NULL )
{ `
printf("Failed to initate MySQL\n");
return 1;
}
if( ! mysql_real_connect(conn,host,username,password,database,0,NULL,0) )
{
printf( "Error connecting to database: %s\n", mysql_error(conn));
return 1;
}
unsigned int i;
mysql_query(conn,"SELECT name, email, password FROM users");
res_set = mysql_store_result(conn);
unsigned int numrows = mysql_num_rows(res_set);
unsigned int num_fields = mysql_num_fields(res_set);
while ((row = mysql_fetch_row(res_set)) != NULL)
{
for(i = 0; i < num_fields; i++)
{
printf("%s\t", row[i] ? row[i] : "NULL");
}
printf("\n");
}
mysql_close(conn);
return 0;
}
I got the error "unable to include mysql.h".
I am using windows 7, Turbo C, mysql and I downloaded mysql-connector-c-noinstall-6.0.2-win32-vs2005, but I don't know how to include it.
Wrong syntax. The #include is a C preprocessor directive, not a statement (so should not end with a semi-colon). You should use
#include <mysql.h>
and you may need instead to have
#include <mysql/mysql.h>
or to pass -I /some/dir options to your compiler (with /some/dir replaced by the directory containing the mysql.h header).
Likewise, your #define should very probably not be ended with a semi-colon, you may need
#define username "root"
#define password "viswa"
#define database "dbase"
I strongly suggest reading a good book on C programming. You may want to examine the preprocessed form of your source code; when using gcc you could invoke it as gcc -C -E
yoursource.c to get the preprocessed form.
I also strongly recommend enabling warnings and debugging info (e.g. gcc -Wall -g for GCC). Find out how your specific compiler should be used. Learn also how to use your debugger (e.g. gdb). Study also existing C programs (notably free software).
You should learn how to configure your compiler to use extra include directories, and to link extra libraries.
N.B. With a linux distribution, you'll just have to install the appropriate packages and perhaps use mysql_config inside our Makefile (of course you'll need appropriate compiler and linker flags), perhaps with lines like
CFLAGS += -g -Wall $(shell mysql_config --cflags)
LIBES += $(shell mysql_config --libs)
added to your Makefile.