Zum Inhalt springen

Empfohlene Beiträge

Geschrieben

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?

Geschrieben
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.

Geschrieben

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.

Geschrieben

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

Geschrieben

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.

Geschrieben

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?

Geschrieben


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 :)

Geschrieben

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.

Geschrieben

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.

Geschrieben

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.

Geschrieben

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?

Geschrieben

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.

Geschrieben

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.

Geschrieben

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.

Geschrieben

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?

Geschrieben
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.
Geschrieben
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?

Geschrieben
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.

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...