Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Empfohlene Antworten

Veröffentlicht

Hallo,

Ich habe ein fertiges C++ Programm, welches ich jetzt komfortabler gestalten möchte. Das Programm dien zur Umwandlung von Binärdaten in lesbare Daten. Der Dateiname wird automatisch erzeugt.

Es geht mir jetzt darum, das ganze etwas komfortabler zu gestalten. Bisher erfolgt immer noch eine Abfrage des Dateinamens der Binärdatei. Dies möchte ich umgehen, um Fehler, die bei der Eingabe entstehen können, zu vermeiden. Ich hatte dabei an Drag & Drop gedacht. Sprich der Anwender soll die gewünschte Datei einfach auf das Programmicon ziehen, und dieses damit automatisch starten.

Bin ich da hier an der richtigen Adresse?

Bin ich da hier an der richtigen Adresse?
Bestimmt, aber was ist deine Frage?

Willst du wissen, ob das mit Drag&Drop funktioniert? Willst du wissen wie es funktioniert? Werd mal etwas präziser.

  • Autor

Ich möchte gerne wissen, wie es funktioniert. Das es funktioniert, darüber bin ich mir ja recht sicher, da ich das schon bei Programmen gesehen hab. Aber in die kann man leider nicht reinschauen, um zu sehen, wie das entsprechende Skript aufgebaut sein muss.

Windows übergibt afaik beim D&D den Pfad der "gedroppten" Datei als Parameter.

=> probiers mal mit nem testprogramm, welches dir einfach alle parameter ausgibt und schau was passiert

  • Autor

Kannst Du mir da vielleicht noch einen kleinen Tip zum Einstieg geben?

Ich muss doch sicherlich erst einmal eine Routine haben, dass, das Testprogramm überhaupt erst einmal auf den Drop reagiert.

Bisher passiert nämlich nichts, wenn ich eine Datei per D&D auf mein Programm ziehe. Also es öffnet sich nicht einmal. In meinen C++ Grundlagen-Büchern steht dazu leider auch nichts. Und im Forum hier habe ich über die Suche auch nichts derartiges Gefunden, Also einen Befehl, oder ein Skript, was D&D für mein Programm überhaupt erst einmal ermöglicht.

  • Autor

Ich möchte die datei auf das Symbol meiner Anwendung ziehen, und dann soll diese starten und die Umwandlung vornehmen. So weit bin ich bisher:


#include <iostream.h> // cin, cout
#include <fstream.h> // ifstream, ofstream
#include <stdlib.h> // exit, rand
#include <iomanip.h> // setw
#include <conio.h> // getch
#include <sys/stat.h> // stat
#include <time.h> // ctime, time
#include <stdio.h>


void main(const char* argv[64])
{

char filewrite[64];
char partner[64];
char rep;
const Max = 16;

struct ausgabeT
{
short blocka;
short lengtha;
int timea;
short werta1; // hier geht es noch weiter, ist aber für mein Problem belanglos
};
ausgabeT Tab[Max];
ifstream ifl(argv[64], ios::in|ios::binary);

struct stat buf;
stat(argv[64], &buf);
int groesse = buf.st_size;

long zeit;
ifl.seekg(2*sizeof(short), ios::beg);
ifl.read((char*)&zeit, sizeof(int));

time_t timer;
struct tm *tblock;
tblock = localtime(&zeit);
sprintf(filewrite,"CUT %02d %02d% 04d.txt ",tblock->tm_mday,tblock->tm_mon+1,tblock->tm_year+1900);

[/PHP]

Das Programm wird jetzt gestartet, stürzt aber sofort mit diversen Fehlermeldungen ab.

[code] Die Anweisung in "0x00401036" verweist auf Speicher in "0x00000102". Der Vorgang "read" konnte nicht auf dem Speicher durchgeführt werden. Die Ausnahme "unknown software exception" (0xc0000027) ist in der Anwendung an der Stelle 0x77e76153 aufgetreten. [/code]

Das deutet ja meines Wissens darauf hin, dass ich den Speicher nicht korrekt reserviert habe. Ich erkenne jedoch keinen Fehler. Ich hoffe, dass jemand von Euch diesen sieht. Muss eventuell mein [b][color=Red]argv[64][/color][/b] vorher definiert werden?


void main(const char* argv[64])
[/PHP]

das ist so falsch.

main ist entweder als

[PHP]
int main()

oder als


int main (int argc, char* argv[])
[/PHP]

definiert.

Im zweiten Fall steht in argc die Anzahl der Parameter und in argv die Parameter selber drin. Wobei der erste Parameter immer der Aufruf der Anwendung selber ist.

Das Ganze gehört aber eher ins API Forum weil das mit dem Drag&Drop bestimmt nicht zum C Standard gehört :)

  • Autor

Kannst Du das mit den Parametern bitte etwas genauer erläutern?

Ich habe in einem anderen Forum einen Ansatz gefunden, und diesen dann weiterverarbeitet. Es ging dort um eine Möglichkeit, Dateien zu löschen. Ich poste mal den Code:


#include <stdio.h>

#include <stdlib.h>				// exit, rand

#include <conio.h>				// getch


void main(int argc, const char* argv[])

{

    if (argc != 2)

    {

        printf("start the program with \"%s filename\"\n", argv[0]);

        printf("or drag and drop a file\n");

        exit(0);

    }


    if (remove(argv[1]) == -1)

          perror("Could not delete file");

    else

          printf("Deleted %s\n", argv[1]);

    getch();

}

Dieses Programm läuft bei mir Problemlos. Nur mit dem Zusammenmischen von beiden komme ich nicht hin. Der Haken ist sicherlich klein, aber ausschlaggebend. Vielleicht hast Du ja eine Meinung dazu.

  • Autor

Habe mein Problem schon im C/C++ Forum gepostet, und wurde von dort an Euch verwiesen. Ich hoffe Ihr könnt mir jetzt weiterhelfen.

Ich habe ein Programm in C++ geschrieben, mit dem ich datensätze auslesen und schreiben kann. Bisher erfolgte der Start und die Auswahl der auszulesenden Datei von hand. Ich suche jetzt eine Lösung, die mir das Eingeben des Dateinamens erspart (Drag&Drop). Ich poste hier auch mal meinen bisherigen Code:


#include <iostream.h> // cin, cout
#include <fstream.h> // ifstream, ofstream
#include <stdlib.h> // exit, rand
#include <iomanip.h> // setw
#include <conio.h> // getch
#include <sys/stat.h> // stat
#include <time.h> // ctime, time
#include <stdio.h>


void main(const char* argv[64])
{

char filewrite[64];
char partner[64];
char rep;
const Max = 16;

struct ausgabeT
{
short blocka;
short lengtha;
int timea;
short werta1; // hier geht es noch weiter, ist aber für mein Problem belanglos
};
ausgabeT Tab[Max];
ifstream ifl(argv[64], ios::in|ios::binary);

struct stat buf;
stat(argv[64], &buf);
int groesse = buf.st_size;

long zeit;
ifl.seekg(2*sizeof(short), ios::beg);
ifl.read((char*)&zeit, sizeof(int));

time_t timer;
struct tm *tblock;
tblock = localtime(&zeit);
sprintf(filewrite,"CUT %02d %02d% 04d.txt ",tblock->tm_mday,tblock->tm_mon+1,tblock->tm_year+1900);
[/PHP]

Wenn ich eine Datei auf mein Programmicon ziehe und loslasse, startet das Programm zwar, aber es Stürzt sofort ab und gibt folgende Fehlermeldungen aus:

[code] Die Anweisung in "0x00401036" verweist auf Speicher in "0x00000102". Der Vorgang "read" konnte nicht auf dem Speicher durchgeführt werden. Die Ausnahme "unknown software exception" (0xc0000027) ist in der Anwendung an der Stelle 0x77e76153 aufgetreten. [/code]

Ich hoffe jemand von Euch sieht den Fehler, der sich bei mir eingeschlichen hat.

  • Autor

int main(int argc, char* argv[])

Die Namen der Parameter sind egal, aber du darfst den int-Parameter nicht weglassen.

Wenn ich die Zeile so übernehme, erhalte ich einen Fehler beim Compilieren:

Warning W8057 C:\Auswertung\C++\CUT datkonvert 1.5.2.cpp 611: Parameter 'argc' is never used in function main(int,const char * *)

Also muss ich den int-Parameter später doch noch irgendwie einsetzen, um das Programm zum Laufen zu bekommen.

  • Autor

OK, soweit ist das klar. Trotzdem bleibt es immer noch dabei, dass das Programm nach dem Start abstürzt. Ich gehe immer noch davon aus, dass ich den Speicher für irgendeine vorher Variable nicht richtig reserviert habe (ich denke mal, das es mein char* argv ist).

Oder habe ich noch etwas anderes nicht beachtet?

Ich habe vorher nicht so genau reingeschaut. Wie kommst du auf die Idee, argv[64] zu benutzen? Es ist ziemlich unwahrscheinlich, dass dein Programm mit 64 Parametern gestartet wird. In argv[0] steht der Name deines Programms, also steht der erste Kommandozeilenparameter in argv[1]. Generell solltest du für argv keinen größeren Index als argc - 1 benutzen.

  • Autor

OK, da hast Du mich darauf gestossen. Ich bin davon ausgegangen, dass ich eine Dateinamenlänge von 64 Zeichen habe und habe char argv[64] gewählt.

Jetzt stürzt das Programm auch nicht ab.

Hast Du denn eine übersicht, welche Parameter in welcher Reihenfolge übergeben werden können, bzw. wo ich etwas dazu finde? Vielleicht kann ich noch ein paar weitere von diesen übernehmen.

wie meinst du das?

wenn du dein programm (bsp. mit dem namen test.exe) folgendermaßen aufrufst:

test.exe arg1 arg2 arg3

dann hast du in argc 4 drin stehen und in argv:

argv[0] = "test.exe"

argv[1] = "arg1"

argv[2] = "arg2"

argv[3] = "arg3"

windows ruft deine programm beim drag&drop einfach auf und übergibt den namen der gedroppten Datei als ersten Parameter mit.

  • Autor

Also ich habe mein Programm jetzt folgendermassen angepasst:


#include <iostream.h> // cin, cout
#include <fstream.h> // ifstream, ofstream
#include <stdlib.h> // exit, rand
#include <iomanip.h> // setw
#include <conio.h> // getch
#include <sys/stat.h> // stat
#include <time.h> // ctime, time
#include <stdio.h>


int main(int argc, const char* argv[])
{
if (argc != 2)
{
printf("start the program with \"%s filename\"\n", argv[1]);
printf("or drag and drop a file\n");
getch();
exit(0);
}
cout << "\nFolgende Datei wird verarbeitet : " << argv[1];
getch();

char filewrite[64]; // Dateiname der Auszugebenden Datei
char partner[64];

char rep; // Kontrollvariable
const Max = 16;

struct ausgabeT
{
short blocka;
short lengtha;
int timea;
short werta1;
short werta2;
short werta3;
short werta4;
short werta5;
short werta6;
short werta7;
short werta8;
short werta9;
};
ausgabeT Tab[Max];
ifstream ifl(argv[1], ios::in|ios::binary); //öffnen der Datei zur Eingabe im Binärmodus
if (!ifl) // Fehler beim öffnen der Datei
{
cerr << "\nFehler beim oeffnen der Datei! " << argv[1];
cout<< "\nDas Programm wird nach Tastendruck geschlossen.";
getch();
exit (1);
}

struct stat buf;
stat(argv[1], &buf);
int groesse = buf.st_size;

long zeit;
ifl.seekg(2*sizeof(short), ios::beg);
ifl.read((char*)&zeit, sizeof(int));

time_t timer;
struct tm *tblock;
tblock = localtime(&zeit);
sprintf(filewrite,"CUT %02d %02d% 04d.txt ",tblock->tm_mday,tblock->tm_mon+1,tblock->tm_year+1900);
sprintf(partner,"Extern %02d %02d% 04d.txt ",tblock->tm_mday,tblock->tm_mon+1,tblock->tm_year+1900);

cout << "\nDateiname : " << filewrite;
ofstream ofl(filewrite, ios::out);
// schreiben der Kopfzeile
// erster Datenblock
ofl << setfill(' ') << setw(14) << "Block"; // Blocknummer
ofl << setfill(' ') << setw(14) << "Werte"; // Anzahl der Werte im Block
[/PHP]

und dann geht die Umwanlung los. So weit so gut. Leider werden jetzt aber keine neuen Dateien mehr geschrieben, obwohl mir die Ausgabe:

cout << "\nDateiname : " << filewrite;

den Namen richtig ausgibt. In meiner ersten Version, wo ich den Namen der Umzuwandelnden Datei noch von Hand eingegeben habe, hat es jedoch funktioniert. Liegt es eventuell daran, dass ich den kompletten Pfad über argv[1] mit übergebe?

Leider werden jetzt aber keine neuen Dateien mehr geschrieben,
Ich denke, die werden durchaus geschrieben, nur nicht dort, wo du es erwartest. Wenn sie in dem Verzeichnis erstellt werden sollen, in dem auch die Quelldatei liegt, musst du den Pfad aus argv[1] extrahieren und vor die Dateinamen der Ausgabedateien setzen.
  • Autor
Wenn sie in dem Verzeichnis erstellt werden sollen, in dem auch die Quelldatei liegt, musst du den Pfad aus argv[1] extrahieren und vor die Dateinamen der Ausgabedateien setzen.

OK, das werde ich probieren. Wenn ich generell einen ganz neuen, und für alle Files festen Pfad haben möchte, muss ich da noch irgendwelche Attribute beachten, dass auch neue Ordner und verzeichnisse erstellt werden? Oder geschieht das automatisch, wenn man als Benutzer schreib und Leserechte auf dem PC bzw. Laufwerk hat?

  • Autor
Du musst die Verzeichnisse selbst erstellen.

Das heisst ich muss wenn die Verzeichnisse noch nicht vorhanden sind, diese über einen Befehl erstellen. Habe folgendes versucht:



sprintf(filewrite,"C:\\Messdaten\\Auswertung\\CUT\\%02d %02d% 04d.txt ",tblock->tm_mday,tblock->tm_mon+1,tblock->tm_year+1900);
sprintf(partner,"C:\\Messdaten\\Auswertung\\Cut\\Extern\\%02d %02d% 04d.txt ",tblock->tm_mday,tblock->tm_mon+1,tblock->tm_year+1900);
cout << "\nDateiname : " << filewrite; // Kontrolle des Dateinamens
ofstream ofl(filewrite, ios::out);

[/PHP]

Die Ordner Messdaten\Auswertung\CUT etc. wurden jedoch nicht erstellt. Und somit auch die Textfiles nicht in diese geschrieben. Wenn ich die Ordner vorher von Hand erstelle, landen auch die Daten dort, wo Sie hinsollen.

Ich muss also mein Programm nur noch dazu bewegen, Ordner selbstständig nach von mir gewählten Parametern anzulegen, bzw. zu überprüfen, ob diese schon vorhanden sind, und gegebenenfalls neue Ordner (z.B. für jeden Monat) zu erstellen. Ich hoffe ich finde dazu eine Referenz hier im Forum. Falls jemand schon eine kennt, wäre es nett, den Link hier noch einmal zu posten.

Erstelle ein Konto oder melde dich an, um einen Kommentar zu schreiben.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.