Zeichenlängen in .txt erkennen
-
Moin liebe Community
Achtung! Das Hauptproblem wurde bereits gelöst! Zur Lösung gehe bitte auf Seite #2
Zunächst ein Verweis auf meinen Beitrag im IT-Forum (http://www.c-plusplus.net/forum/p2405654#2405654
Da schrieb ich über das Problem mit dem 255 Pfadlängenproblem und wie man es beheben könne.
Dies am Besten als OpenSource ... und naja ihr könnts ja lesen wenn es euch interessiertNun wollte ich parallel dazu euch fragen, wie man das in C-Code umwandelt.
Meine eigenen Kenntnisse begrenzen sich auf C bzw. PHP, wobei ich C auch nur Anfängerkenntnisse... (ehm keine Ahnung wie ich das beschreiben soll: wenn ich etwas programmiere muss ich mindestens eine stunde oder zwei nachschauen, was was bedeutet ... aber ich mache Fortschritte ^^)Um auf den Punkt zu kommen:
Ich hab mal angefangen ein paar Ideen dafür aufzustellen und schreibe euch das mal:#include <stdio.h> #include <stdlib.h> #include <string.h> #include 'alledateien.txt' int main() { // Anzahl der Zeilen im Dokument erfassen for (i = 0; i < x; i++) // for-schleife: i stellt hierbei die derzeitige position (zeile) dar und x (kommt aus der vorherigen funktion) die gesamte anzahl der zeilen // Innerhalb der for-schleife: anzahl der zeichen erfassen. //if-verzweigung: wenn (anzahl der zeichen > 255) printf("%d ist zu lang!!!", i); }
(Sorry, falls der Code etwas blöd aussieht ... muss mich erstmal dran gewöhnen, dass hier zu schreiben)
Nun kommt die Erklärung dazu:
#include <string.h> // Man könnte das ganze auch über Strings lösen (da Pfade ja nichts anderes sind, oder)
#include 'alledateien.txt' //Die CMD-Kommandozeile erzeugt eine Textdatei, die ich dann untersuche.
/*Hier fällt mir ein, dass ich euch garnicht geschrieben hab, wie ich die Textdatei erzeuge
=> (in cmd) dir /s /b /ad c:\Users\Vinni\Desktop\ > alledateien.txt
*/Jetz kommen wir zum eigentlichen Punkt ^^
Zunächst soll die Anzahl der Zeilen im Dokument gelesen und gespeichert werden.
Diese Zeilen könnten evtl als String gespeichert werden (einzeln). Dazu noch die Frage, ob man ein String-Array bauen kann, also ein Array, dass als Elemente Strings hat. (oder auch Pointer auf Strings ... weiß aber nich ob man das so umsetzen kann)Dann eine for-Schleife, die die Strings bzw. Zeilen abläuft und die Zeichen darin liest.
Mit der If-Verzweigung (auch innerhalb der Schleife) wird dann ausgegeben: String/Zeile x ist länger als 255 Zeichen oder es wird zurück zum Anfang der Schleife gegangen. (So zumindest die Theorie)Ich würde mich über ein paar Anregungen freuen.
Ihr müsst mir nicht komplette Codes schreiben, nur evtl ein paar Hinweise und Methoden ( readchar oder sowas hieß glaube ich eine Funktion),
die ich dann umsetzen kann
Will ja schließlich auch was lernen hier und nicht den ganzen Code vorgekaut bekommen.Beste Grüße wünscht
Lordakius :p
-
#include 'alledateien.txt'
Das ist lustig, geht aber so nicht.
Mit #include bindet man C-Quellcode-Dateien ein und keine Anwenderdateien.
Der beschriebene Weg über cmd > Datei > Datei zeilenweise lesen ist möglich aber umständlich.
Besser wäre die Verwendung der POSIX Funktion popen und dabei dann die WinApi Variante _popen, die die o.g. Sache für dich erledigt, also in etwa#include <stdio.h> #include <stdlib.h> int main() { char zeile[10000]; FILE *f = _popen("dir /s /b /ad c:\Users\Vinni\Desktop\","r"); if(!f) return 1; while( fgets(zeile,10000,f) ) if( strlen(zeile)>255 ) printf("\nPfad laenger als 255: \"%s\"",zeile); _pclose(f); return 0; }
-
Ich würde so beginnen:
Datei zum Lesen öffnen Eine Zeile einlesen while(Datei nicht zu Ende) { Zeilenanzahl um 1 erhöhen Zeilenlänge ermitteln Abhängig von der Zeilenlänge was auch immer machen Eine Zeile einlesen } Zeilenanzahl ausgeben (oder auch nicht)
-
Danke für die schnellen Antworten
@Wutz Habe es mal mit deinem Code versucht und MS Visual Studio Express 2013 gibt mir folgende Fehlermeldungen:
Zeile 7: Falsch formatierter universeller Zeichenname.FILE *f = _popen("dir /s /b /ad c:\Users\Vinni\Desktop\","r");
Zeile 7: Fehlende schließende Anführungszeichen
Zeile 7: Zu wenig Argumente im FunktionsaufrufNur zum verständnis:
FILE *f => Pointer *f auf einen FILE-Typ? Kenn Pointer nur mit int, float und co.Außerdem: Muss ich nicht beim Pfad noch die .txt datei angeben?
Sonst sucht er ja einfach in dem Verzeichnis nach einer FILE-Data oder?Mit besten Grüßen
Lordakius#Edit:
@Belli Toller Ansatz, werde es gleich bei mir verändern (vllt schreib ich die Version nochmal komplett selbst a.k.a. Übung macht den Meister)
-
Ja du hast recht, das muss für Windows
FILE *f = _popen("dir /s /b /ad c:\\Users\\Vinni\\Desktop\\","r");
heißen.
-
Da der \ eine Escapesequenz einleitet, muss er doppelt angegeben werden, wenn er selber gemeint ist.
\" ist eine gültige Sequenz, von daher erkennt der Compiler das " nicht als Abschluss vom Stringliteral.FILE *f = _popen("dir /s /b /ad c:\\Users\\Vinni\\Desktop\\","r");
Ist das in PHP nicht genau so?
Lordakius schrieb:
Nur zum verständnis:
FILE *f => Pointer *f auf einen FILE-Typ? Kenn Pointer nur mit int, float und co.Ja, lies ein Buch über C.
Lordakius schrieb:
Außerdem: Muss ich nicht beim Pfad noch die .txt datei angeben?
Sonst sucht er ja einfach in dem Verzeichnis nach einer FILE-Data oder?Das Kommando "erzeugt" deine Textdatei intern. Das dir ... wird ausgeführt und die Ausgabe davon wird gleich vom Programm gelesen.
Vielleicht machst du das in PHP, wenn du PHP besser kannst als C.
-
Wutz schrieb:
Ja du hast recht
Okay, dass mit dem Code hab ich korrigiert.
Was ist jedoch mit der .txt?
Muss ich die nicht noch irgendwo angeben?Wenn ja, wo?
Lordakius
-
DirkB schrieb:
Da der \ eine Escapesequenz einleitet, muss er doppelt angegeben werden, wenn er selber gemeint ist.
\" ist eine gültige Sequenz, von daher erkennt der Compiler das " nicht als Abschluss vom Stringliteral.Danke
DirkB schrieb:
Vielleicht machst du das in PHP, wenn du PHP besser kannst als C.
Hätte ich vielleicht erwähnen sollen: PHP lerne ich gerade erst ^^
-
So, der Code sieht zunächst gut aus, nach dem Debuggen kommen folgende Meldungen rein:
"Projekt7.exe" (Win32): "C:\Users\Vinni\Documents\Visual Studio 2013\Projects\Projekt7\Debug\Projekt7.exe" geladen. Symbole wurden geladen. "Projekt7.exe" (Win32): "C:\Windows\SysWOW64\ntdll.dll" geladen. PDB-Datei wurde nicht gefunden oder konnte nicht geöffnet werden. "Projekt7.exe" (Win32): "C:\Windows\SysWOW64\kernel32.dll" geladen. PDB-Datei wurde nicht gefunden oder konnte nicht geöffnet werden. "Projekt7.exe" (Win32): "C:\Windows\SysWOW64\KernelBase.dll" geladen. PDB-Datei wurde nicht gefunden oder konnte nicht geöffnet werden. "Projekt7.exe" (Win32): "C:\Windows\SysWOW64\msvcr120d.dll" geladen. PDB-Datei wurde nicht gefunden oder konnte nicht geöffnet werden. "Projekt7.exe" (Win32): "C:\Windows\SysWOW64\apphelp.dll" geladen. PDB-Datei wurde nicht gefunden oder konnte nicht geöffnet werden. "Projekt7.exe" (Win32): "C:\Windows\SysWOW64\cmd.exe" geladen. PDB-Datei wurde nicht gefunden oder konnte nicht geöffnet werden. "Projekt7.exe" (Win32): "C:\Windows\SysWOW64\cmd.exe" wurde entladen. Das Programm "[3376] Projekt7.exe" wurde mit Code 0 (0x0) beendet.
Meine eigene Schätzung wäre, dass ich noch einen Verweis auf die entsprechenden PDB-Dateien geben muss. Außerdem kam auch eine Fehlermeldung in cmd, die ich mir auch nicht erklären kann:
Der Befehl ""C:\Users\Vinni\AppData\Local\Temp\jgmqpdwcspniuccts.exe"" ist entweder falsch geschrieben oder konnte nicht gefunden werden.
sieht mir stark nach einem Befehl aus, der nicht mehr existiert, evtl. ein Virus, den ich gelöscht, wo aber noch was in der Registry übrig ist?
Diese Fehlermeldung erscheint auch, wenn ich einfach nur cmd ausführe (über windows + R)beste grüße
Lordakius#Edit: ich seh grad noch ne Warnung:
Warning C4013: 'strlen' undefiniert; Annahme: extern mit Rückgabetyp intmuss ich vllt doch string.h implementieren? fällt mir grad auf
-
Lordakius schrieb:
Was ist jedoch mit der .txt?
Muss ich die nicht noch irgendwo angeben?Wutz schrieb:
Der beschriebene Weg über cmd > Datei > Datei zeilenweise lesen ist möglich aber umständlich.
Besser wäre die Verwendung der POSIX Funktion popen und dabei dann die WinApi Variante _popen, die die o.g. Sache für dich erledigt, also in etwaLordakius schrieb:
Hätte ich vielleicht erwähnen sollen: PHP lerne ich gerade erst ^^
C kannst du ja auch nicht. Von daher spielt es dann keine Rolle womit du das programmierst.
(Du hast nur deine C-Fähigkeiten eingeschränkt.)
-
Lordakius schrieb:
#Edit: ich seh grad noch ne Warnung:
Warning C4013: 'strlen' undefiniert; Annahme: extern mit Rückgabetyp intmuss ich vllt doch string.h implementieren? fällt mir grad auf
Nein, implementieren musst du es nicht. Die Funktion gibt es schon in der C-Standardlibrary.
Aber damit der Compiler weiß, wie die Funktion aufgerufen wird, muss er die Deklaration der Funktion kennen.
Die steht in string.h.
Daher reicht es aus, wenn du ein#include <string.h>
am Anfang von deinem Code machst.Steht aber auch in dem C-Buch
-
Jo das einfügen der string.h hab ich auch gemacht,
(bissel C kann ich ja doch ^^)Allerdings hab ich keine Ahnung was mit den PDB-Dateien sein soll.
Sehen mir wie Standard Windows-befehle aus. Warum gibts also Fehler?#Edit:
http://msdn.microsoft.com/de-de/library/aa292304(v=vs.71).aspx
Heißt das, bei mir fehlen die Befehle?
lg Lordakius
-
Das ist die leidige Unsitte bei MS mit den vorcompilierten Headerdateien.
Die solltest du in den Projekteinstellungen abschalten.
-
Wutz schrieb:
Die solltest du in den Projekteinstellungen abschalten.
Wo finde ich die?
Ich weiß gerade nicht, ob ich es nicht schon gesagt habe, aber wenn beim ausführen die cmd geöffnet wird, passiert garnichts. Es wird weder eine neue Textdatei geschrieben, noch wird eine untersucht ( zumindest krieg ich nix zurück ... das kann aber auch daran liegen, dass ich nix über 255 zeichen hab)
Ich werde mal die grenze runtersetzen und schauen ob was passiert.#edit:
Okay, habs getestet und es gibt auch was in cmd aus.
An diesem Punkt: danke für eure Mühen
Jetz gibts noch 2 Probleme:
Einmal krieg ich in cmd ständig dieses "Der befehl wurde nicht gefunden" (habs ja oben schon geschrieben, auch wenn es wahrscheinlich systemseitig ist, nervt das ganz schön)
Und bei Visual Studio beim Debug-fenster mit den PDB dateien.#Edit²: Das mit der cmd-Fehlermeldung hat sich geklärt ^^
War der Überrest eines Virus ... Musste das System sowieso mal wieder neu aufsetzenHier noch einmal der "gefixte" Code für das Problem, falls noch jemand das Problem hat:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char zeile[10000]; FILE *f = _popen("dir /s /b /ad c:\\Users\\Vinni\\Desktop\\", "r"); if (!f) return 1; while (fgets(zeile, 10000, f)) if (strlen(zeile)>255) printf("\nPfad laenger als 255: \"%s\"", zeile); _pclose(f); system("PAUSE"); //Optional: Damit das CMD-fenster bleibt. return 0; }
#Edit²: da hab ich doch glatt noch meine 150 Grenze reingenommen
Beste grüße
Lordakius
-
Hey ihr Lieben
Jetzt sagt mir Visual Studio beim Release debuggen (nennt man den Vorgang so?),
dass die Funktion fopen unsicher sei und ich fopen_s nehmen sollte.Visual Studio schrieb:
error C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
Dazu folgende Help-Seite von Windows:
http://msdn.microsoft.com/en-us/library/ttcz0bys.aspxNun könnte ich natürlich fopen_s benutzen, beim Suchen nach der Syntax ist mir folgende Seite vor die Augen gekommen:
http://stackoverflow.com/questions/21873048/getting-an-error-fopen-this-function-or-variable-may-be-unsafe-when-complinEs wird gesagt, dass fopen_s nur unter MS Windows komaptibel ist . (so habe ich es zumindest verstanden :p )
Nun meine Frage:
Wie kann ich die Warning abschalten bzw. eine "sicherere" Funktion benutzen, die jedoch auch unter Linux zB kompatibel ist?Mit besten Grüßen
Lordakius
-
Das wurde dir doch bereits vom Compiler gesagt:
To disable deprecation, use _CRT_SECURE_NO_WARNINGS
Und auf der von dir verlinkten MS-Seite steht es ebenfalls:
To turn off CRT deprecation warnings, define _CRT_SECURE_NO_WARNINGS.
Ebenso auf SO. Da ist es sogar die akzeptierte Antwort!
-
Ja das war mir bereits aufgefallen ...
Hab ich wohl vergessen zu erwähnen, dass ich das bereits versucht habe es damals aber nicht geklappt hatte ... Gerade hats geklappt. Danke trotzdemNun aber zu der Frage einer "sicheren" Funktion:
Gibts sowas für alle OS? oder hab ich da was falsch verstanden mit der inkompatibilität? (was ein Wort).
#Neue Aufgabe :
Das Programm arbeitet jetzt auf Konsolenebene. Ich möchte nun aber eine GUI dafür entwickeln, habe sowas allerdings noch nie vorher gemacht. Ich hab mal bei den Foren durchgeschaut und da gibts auch ein Forum das heißt MFC (Visual Studio ++ (oder so ähnlich)) und darunter gibts ein Forum namens "andere GUI's".
Muss ich also für eine GUI eine komplett neue Programmiersprache lernen (und das Forum wechseln:p ).
Beste Grüße
Lordakius
-
Bei SO ist sogar noch eine zweite Möglichkeit mit
#pragma
genannt.#pragma warning(disable:4496)
Als erste Zeile in deinem Code.
-
DirkB schrieb:
Bei SO ist sogar noch eine zweite Möglichkeit mit
#pragma
genannt.#pragma warning(disable:4496)
Als erste Zeile in deinem Code.
Probiert und hat nicht geklappt . Von daher auch nicht in meine Beschreibung aufgenommen. (werd ich nächstes mal machen)
-
Nicht alle angemeckerten Funktion sind unsicher.
Viele davon sind nur unsicher, wenn man sie falsch benutzt. (NULL-Zeiger, fehlenden Angabe der Arraylänge, ...)Die "Ersatzfunktionen" brauchen (teilweise) mehr/andere Parameter und verhalten sich auch anders, als die originalen. Eine 1:1 Umsetzung ist also schwierig.
Die Security Features in the CRT kannst du nachlesen: http://msdn.microsoft.com/en-us/library/8ef0s5kh.aspx
Willst du etwas von Microsoft wissen, dann kannst du im MSDN suchen, oder google nach "MSDN Stichwort"
Willst du etwas über *ix wissen, dann schau in die man-Page, oder google nach "man Stichwort"Zur GUI.
Schau mal was darüber steht: "Frameworks"
Das sind keine Programmiersprachen. Sondern ~(lies es bei Wikipedia nach)~Welches Framework du nehmen kannst, hängt auch von deinen Zielen (Plattform, komplexität) ab.
Aber nur mit C wirst du nicht weit kommen.
-
Hey
Es geht anscheinend klar, wenn ich das Programm nicht visuell in nem Fenster darstelle.
Nun soll allerdings nicht nur der String (also der Pfad) kopiert und angezeigt werden, sondern, der int-Wert, der die Zeichenlänge gespeichert hat. Diese Werte sollen dann in einer *.csv ausgegeben werden. (wiki=http://de.wikipedia.org/wiki/CSV_%28Dateiformat%29)Also soll das Programm folgendes machen:
-Pfade auf eine textdatei schreiben (1 Zeile pro String; am besten gleich im csv-Format) -Pfadlänge lesen -Pfadlänge und dazugehörigen String in einer csv datei speichern -Speichern der csv datei.
Das csv-Format soll genommen werden, damit man sie einfach in Excel öffnen kann und nach den Pfadlängen ordnen kann.
Meine überlegung war:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char zeile[10000]; FILE *f = _popen("dir /s /b /ad C:\\", "r"); if (!f) return 1; printf("Loading ... Please Wait!\n"); FILE *datei; datei = fopen("AllData>255.csv", "w"); while (fgets(zeile, 10000, f)) { strlen(zeile); //Speicher die Ausgabe von strlen(zeile) vor dazugehörigen Pfad-String _pclose(f); system("PAUSE"); return 0; }
Soweit die Theorie
Habt ihr Verbesserungen zu meinem (halb-)pseudo-Code?
Ist meine Methode effizient oder gibt es bessere ?
Und wie funktioniert die Übergabe in eine *.csv? Hab mit diesem Datenformat nie
gearbeitet.#edit:
wichtig ist, dass die csv gespeichert wird !! Sie soll also nach Ende des Programms noch verfügbar sein.
#edit:
while (fgets(zeile, 10000, f)) { int len = (strlen(zeile)); fprintf(datei, "%i;", len "%s", zeile); //Error:C2059 Syntaxfehler:')' }
So sieht nun meine while-Schleife aus. er zeigt mir rot unterschtrichen "%s" an. Aber meines Erachtens fehlt da nix. Oder bin ich einfach nur blind? (soll ja auch mal vorkommen :p)
Außerdem fehlt mir immernoch meine Ausgabe in eine csv dateiBeste Grüße
Lordakius