Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Tekstitiedoston haku internetistä

Sivun loppuun

mika132 [12.11.2013 20:55:43]

#

Eli voisiko joku selittää kun olen noita enklannin kielisiä juttuja selaillut niin yksinkertaistetumman ohjeen, että miten voin katsoa, esim netistä jonkun tiedoston (.txt) sisällön C++. Kaikkia socketteja yms tarvitaan, mutta kun kaikissa paikoissa neuvotaan erillailla. Esim winapina ja socketeilla ja kaikkea, niin olisiko liikaa pyydetty sellainen tiivistetympi opas? Voisi olla ohjelmointiputkassa muutenkin hyödyllinen. :)

mika132 [12.11.2013 21:31:46]

#

Se etten osaa, enkä ole löytänyt opasta. Yritän tehdä updateria. Joka katsoo netissä olevasta tekstitiedostosta päivityksen version ja vertaa sitä pelin sisäiseen tekstitiedostoon, että pitääkö päivittää ja sit päivity sohjelma etsii setup.exe tiedoston ja lataa sen.

Deffi [12.11.2013 22:14:31]

#

URLDownloadToFilellä tiedoston lataus onnistuu helposti, jos haluat mennä naimisiin WinAPIn kanssa.

#include <windows.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    /* Ohjelma ottaa parametriksi URLin. */
    if (argc != 2) {
        printf("käyttö: %s <url>\n", argv[0]);
        return 1;
    }

    /* Etsi URLDownloadToFile, ku se ei löydy MinGW:n kirjastoista :( */
    WINAPI HRESULT (*URLDownloadToFile)(LPUNKNOWN pCaller, LPCTSTR szURL,
            LPCTSTR szFileName, DWORD dwReserved, LPVOID lpfnCB);
    URLDownloadToFile = (void *)GetProcAddress(LoadLibrary("urlmon.dll"),
            "URLDownloadToFileA");
    if (!URLDownloadToFile) {
        fprintf(stderr, "urlmon.URLDownloadToFileA kadoksissa :o\n");
        return 2;
    }

    /* Luo tiedostopolku väliaikaistiedostoon. */
    char tmp_path[MAX_PATH], tmp_fn[MAX_PATH];
    GetTempPath(sizeof(tmp_path), tmp_path);
    GetTempFileName(tmp_path, "get", 0, tmp_fn);

    /* Lataa. */
    printf("ladataan \"%s\"\n", argv[1]);
    if (URLDownloadToFile(NULL, argv[1], tmp_fn, 0, NULL) != S_OK) {
        fprintf(stderr, "fail, ehkä \"%s\" on huono url\n", argv[1]);
        return 3;
    }

    /* Kirjoita ladatun tiedoston sisältö stdout-virtaan. */
    FILE *file;
    if (!(file = fopen(tmp_fn, "rb"))) {
        fprintf(stderr, "tiedosto \"%s\" ei aukea\n", tmp_fn);
        return 4;
    }
    do {
        char buf[512];
        fread(buf, 1, sizeof(buf), file);
        fwrite(buf, 1, sizeof(buf), stdout);
    } while (!feof(file));
    fclose(file);

    /* Ole kiva ja poista väliaikaistiedosto. */
    DeleteFile(tmp_fn);

    return 0;
}

mika132 [12.11.2013 22:16:05]

#

Onko jokin muukin mahdollisuus sitten kuin winapi?

Deffi [12.11.2013 22:27:26]

#

mika132 kirjoitti:

Onko jokin muukin mahdollisuus sitten kuin winapi?

Voit tietysti tehdä käsin soketeilla, mutta se on huomattavasti työläämpi ja virhealttiimpi ratkaisu, joka ei myöskään porttaudu ihan nätisti. Socket-rajapinnoissa on eri käyttöjärjestelmien välillä pieniä eroja.

Kolmas vaihtoehto on käyttää jotain ulkopuolista kirjastoa, kuten libcurlia. Sillä tiedoston lataaminen muistiin onnistuu näin. Hyvinä puolina helppo käyttö ja porttautuvuus, mutta riippuvuus ulkoisista kirjastoista on joskus vitusta.

Metabolix [12.11.2013 22:33:53]

#

Kokeilepa syöttää hakuun sanat C++ tiedosto netistä. Saatat jopa löytää koodivinkin.

Rox [15.11.2013 11:36:58]

#

UrlDownloadToFile, UrlDownloadToCacheFile, libcurl, winsock taikka wininet.

Koita googletella noista jokin, kaikki oikeastaan aika helpohkoja, paitsi noista soketeista en tiedä kun en oo ikinä tutustunut.

Teuro [26.11.2013 20:17:21]

#

SFML:ä onnistuu myös lataaminen. Alla pieni esimerkki aiheesta. Tässä käytetään http:ä yhdistämiseen vain sen takia, että kapsin palvelimelle ei saa otettua ftp-yhteyttä. ftp:ä tämä olisi toki miellyttävämpi tehdä.

#include <SFML/network.hpp>
#include <iostream>
#include <fstream>

void Lataa_tiedosto(const std::string& isanta, const std::string& palvelimella, const std::string& levylla, unsigned int portti = 0) {
	sf::Http http;
	sf::Http::Request pyynto;
	unsigned int tiedoston_koko = 0;

	http.setHost(isanta, portti);
	pyynto.setUri(palvelimella);

	sf::Http::Response sivu = http.sendRequest(pyynto);

	tiedoston_koko = sivu.getBody().size();

	if (tiedoston_koko > 0) {
		std::string tmp_tiedosto = sivu.getBody();
		std::ofstream tiedosto(levylla.c_str(), std::ios::out | std::ios::binary);
		tiedosto.write(tmp_tiedosto.c_str(), tiedoston_koko);
		tiedosto.close();
	} else {
		std::cout << "Osoitteeseen: " << isanta << palvelimella << " ei saada yhteyttä" << std::endl;
	}
}

int main(int kpl, char** argumentit) {
	std::string isanta 	= "isanta/";
	std::string tiedosto 	= "kansio/jossa/ladattavaa.zip";
	std::string paikallinen	= "levylle.zip";

	switch (kpl) {
		case 4:
			paikallinen 	= std::string(argumentit[3]);
		case 3:
			tiedosto 	= std::string(argumentit[2]);
		case 2:
			isanta 		= std::string(argumentit[1]);
	}

	Lataa_tiedosto(isanta, tiedosto, paikallinen, 80);

	return 0;
}

Kääntyy gcc:ä komennolla g++ main.cpp -o ohjelma.exe -lsfml-network -lsfml-system


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta