Size: 16646
Comment:
|
Size: 16641
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 3: | Line 3: |
@Johannes: Also das war so gedacht. Wenn ''--regularExpressionMatch == false'' dann sind ''^^^''und ''$'' und ''.'' Zeichen wie jede andere, sowohl im Muster als auch im Text. Wenn ''-regularExpressionMatch == true'' dann haben Sie die beschriebene Sonderbedeutung im pattern, egal an welcher Stelle sie dort stehen, siehe mein vorheriger Kommentar dazu. Letzteres bedeutet, dass man dann ein ''^'' und ein ''$'' im Text gar nicht exakt matchen kann (man müsste dann ''.'' im pattern schreiben, weil der matched ja alles). '''Hannah 14Jun10 13:59''' | @Johannes: Also das war so gedacht. Wenn ''--regularExpressionMatch == false'' dann sind ^ und ''$'' und ''.'' Zeichen wie jede andere, sowohl im Muster als auch im Text. Wenn ''-regularExpressionMatch == true'' dann haben Sie die beschriebene Sonderbedeutung im pattern, egal an welcher Stelle sie dort stehen, siehe mein vorheriger Kommentar dazu. Letzteres bedeutet, dass man dann ein ''^'' und ein ''$'' im Text gar nicht exakt matchen kann (man müsste dann ''.'' im pattern schreiben, weil der matched ja alles). '''Hannah 14Jun10 13:59''' |
Fragen und Kommentare zur 7. Vorlesung / zum 7. Übungsblatt
@Johannes: Also das war so gedacht. Wenn --regularExpressionMatch == false dann sind und ''$'' und ''.'' Zeichen wie jede andere, sowohl im Muster als auch im Text. Wenn ''-regularExpressionMatch == true'' dann haben Sie die beschriebene Sonderbedeutung im pattern, egal an welcher Stelle sie dort stehen, siehe mein vorheriger Kommentar dazu. Letzteres bedeutet, dass man dann ein '' und ein $ im Text gar nicht exakt matchen kann (man müsste dann . im pattern schreiben, weil der matched ja alles). Hannah 14Jun10 13:59 Ich habe nochmal eine Frage, darf ein $ auch in einem Pattern vorkommen und wenn ja, was passiert dann? Also ich meine (Johannes 14Jun10 13:45) @Sebastian: Gute Frage, daran habe ich gar nicht gedacht. Ich überlasse es Ihnen, würde aber vorschlagen dass, wie Sie auch sagen, Ihr Beispielpattern auf Ihrer Beispielzeile einen Treffer gibt. Hannah 14Jun10 12:25 @Johannes: Ojeoje, noch ein Fehler, ja, da habe ich Wie sollen wir eigentlich mit einem Pattern der Form umgehen - das funktioniert ganz normal, wenn die Zeile Ist in dem Kommentar nicht ein Fehler drin? Es müsste doch heißen with _caseInsensitiveMatch = True oder? (Johannes 14Jun10 11:05) @Fabian + Alle: Mea culpa, ich habe ein k vergessen, es aber jetzt noch nachträglich eingefügt und extra fett gemacht. Erstaunlich was ein Buchstabe für einen Unterschied machen kann ... Hannah 14Jun10 10:45 @Hannah: Sie widersprechen mit (Hannah 13Jun10 23:27) doch ihrer eigenen Spezifikation: Oder heißt bei ihnen "Treffer", dass isMatch false zurückgibt? Fabian 14Jun10 9:34 @Dario: Wenn man mit @Martin: So wie ich Fabian verstanden habe, ist sein Problem inzwischen gelöst (siehe sein Beitrag @Simson: Wenn ^ in einem regulären Ausdruck nicht an erster Stelle vorkommt, bedeutet das mit Sicherheit keinen Treffer und so sollte sich Hallo, kann jemand mir sagen was dies optarg z.B. _inputFileName = optarg; bedeutet? Dario 13Jun10 21:47 Ich habe das gleiche Problem wie Fabian 13Jun10 15:34. Was kann man da tun? MartinW 13Jun10 20:08 Soll man eigentlich irgendwie auf ^/& bei einem regulären Ausdruck reagieren, wenn diese nicht am Anfang/Ende stehen oder sollen die dann einfach als normales Zeichen verwendet werden? Simson 13Jun10 18:36 Problem hat sich erledigt - fclose(outputFile) muss an passender Stelle eingebunden werden! @Tina: So wie ich das verstehe, hat das wirklich nur 3 Argumente, du könntest ebensogut ./GrepMain --input-file=<filename> xyz schreiben. Und an der Stelle, wo du argv[1] = const_cast<char*>("--input-file=???") brauchst, willst du ja den Dateinamen parsen - d.h. an der Stelle ist in _inputFileName eben noch nichts gespeichert. Das wird ja grade erst durch das parsen gemacht. An der Stelle im Test musst Du also erst von Hand ein Testfile anlegen, z.B. mit Das kannst du dann als "--input-file=testfile.txt" parsen. Fabian 13Jan10 17:08 Ich habe noch eine Frage, die ganz unten schon mal gestellt wurde, aber ich habe die Antwort nicht ganz verstanden: wenn ich bei der parse-Funktion z.B. (nur) die Option --input-file testen möchte, muss argv[1] = const_cast<char*>("--input-file= ???") sein, wobei die ??? für den Optionsparameter <filename> stehen, den wir ja aber in _inputFileName gespeichert haben, oder? Wie geb ich das dann hier an? Und hat der Funktionsaufruf ./GrepMain --input-file <filename> xyz dann nur 3 Argumente, und nicht 4, obwohl Option und <filename> durch Komme getrennt wurden? Tina 13Jan10 15:58 Uhr Ich verzweifle grad: Die Datei testoutout existiert bei mir mit dem Inhalt: Jetzt versuche ich, diesen Inhalt zu testen, und zwar in der GrepTest.cpp mit folgendem Code: Ich bekomme folgendes: (Wobei die ? eigentlich ganz komische Zeichen sind, aber die mag das Wiki nicht..) Zum Testen hab ich noch eine Test.cpp ohne jegliches googleTest geschrieben mit folgendem Inhalt: Und diese Datei gibt mir, kompiliert, wunderbar und friedlich meine erste Zeile aus. Keine Fragezeichen. Warum??? Fabian 13Jun10 15:34 Sollen wir, wenn wir für --output-file<filename> eine Datei zum reinschreiben mit fopen öffnen, als Argument 'a' nehmen, damit der Text angehängt wird, oder 'w' das der Dateiinhalt falls vorhanden gelöscht bzw. überschrieben wird? Tina 13Jun10 14:57 @Dario: Sei meinen am Anfang in der Zeile Was heißt die -Wall am Ende der Make file datei? Dario 13Jun10 13:14 @MartinW bez. Testen von @fry: Danke für die Kommentare, stimmt beides genau. Wobei vielleicht noch ergänzen wäre, dass man @Martin: Wegen der @Martin + Fabian + Alle: Ja, das muss natürlich -- heißen, habe das gerade im SVN korrigiert, danke für den Hinweis. Hannah 13Jun10 00:44 Gibt es eine Möglichkeit im Test auf die Konstante MAXIMUM_LINE_LENGTH zuzugreifen? Zum Beispiel in dem die Definition nicht in der Grep.cpp sondern bei den Membervariabeln in der Grep.h festgelegt wird? Ich muss die Konstante lesen können, um den Test für das Überschreiten der maximalen Zeilenlänge zu schreiben. MartinS 12Jun10 21:36 Da hat sich wohl jemand verschrieben. Auf dem Aufgabenblatt steht's mit "--" und ich tippe mal schwer drauf, dass das stimmt. Fabian 12Jun10 18:28 Wieso muss eigentlich -regular-expression-match nur mit einem - aufgerufen werden, während alle anderen mit zwei -- aufgerufen werden (laut usage info). Und wie sag ich das dann getopt? Martin 12Jun10 18:24 PS: Wenn man das Ding mit ShortOps aufrufen können will müssen die, die ein Argument brauchen ein hinter sich":". Beispiel "i" und "o" brauchen ein Argument: fry (UTC+2:00) 1276356859 UTS @Martin das ganze funktioniert mit Beachte dabei dass wenn die Datei bereits vorhanden ist sie mit den neuen Werten überschrieben wird. Der Code drumrum hat da Ähnlichkeiten mit dem von FILE* inputFile... und ich glaub wenn der Pfad nicht angegeben ist wird standardmäßig der aktuelle Pfad des Programms benutzt. fry (UTC+2:00) 1276355745 UTS Ich habe noch eine Frage: Ich weiß leider noch nicht so richtig, wie ich meinem Programm sagen soll, dass es, falls die -o=file.txt Option angegeben ist, keine Standard ausgabe macht, sondern in die Datei file.txt schreibt. Geht das irgendwie mit fwrite? MartinW 12Jun10 15:50 Wie sollen wir eigentlich die input und output Optionen testen? Und: Sollen wir die findMatches Methode testen? Im ersten Teil gibt es ja eine Abbruchbedingung, aber ich wüsste nicht, wie man die mit ASSERT_DEATH testen soll. MartinW 12Jun10 15:40 @Fabian: Sie haben völlig Recht, habe ich vergessen, 1/2 Punkt Abzug für mich @Hannah: Noch eine Frage zu Ihrer Musterlösung zum letzten Blatt: Ist die Musterlösung const-korrekt? Meiner Meinung nach müsste hinter @Martin: Stimmt + super, dass Sie das rausgefunden haben, ein wirklicher gemeiner und schwer zu findender Bug, ich würde sagen das ist (mindestens) einen Bonuspunkt wert! Ich habe da beim Erklären nicht dran gedacht, weil man ja normalerweise die Kommandozeilen-Parameter nur einmal parsed. Aber bei mehreren Tests hintereinander halt öfter, und dann muss man Habe den Fehler durch merkwürdige Fehlermeldungen von GTest gefunden. Ich hatte in GrepTest die drei Tests mit Optionen als den für das input file, output file und case insensitive match hintereinander. Zuerst war der Fehler beim output file test. Nachdem ich den mal auskommentiert hatte war er im case insensitive match test. Dann habe ich mal die Reihenfolge vertauscht. Der Fehler trat also immer in dem Test nach dem ersten Test mit Option auf. Dies ließ sich dann beheben indem ich die Variable "optind" vor der while Schleife auf 1 gesetzt habe. optind ist eine externe Variable von getopt die auf den Index des nächsten zu prozessierenden Eintrags im Feld argv zeigt. Diese wird vom System standardmäßig auf 1 gesetzt und läuft hoch, wenn die Optionen geparsed werden (siehe man 3 getopt). Wenn man jetzt den nächsten Test aufruft, steht diese Variable immer noch auf dem letzten Element des argv Zeigers. Das hießt c wird gleich auf -1 gesetzt und verlässt die Schleife und setzt auch _outputFileName nicht. Es ist also sinnvoll vor jedem Durchlauf der Parsingschleife optind auf 1 zu setzen. Eine Lösung wäre also: Beim Aufruf machen "--output-file=out.txt" und "--output-file out.txt" keinen Unterschied. Sowohl im Test als auch beim Aufruf der GrepMain direkt. Es funktioniert beides. MartinS 10Jun10 11:21 In der Vorlesung wurde gesagt, dass die Parameterwerte mit einem = direkt an ihre Schalter angehaengt werden. Sollte dann richtig funktionieren. AxelLehmann 10Jun10 11:03 @Martin: Was passiert, wenn Sie in in Ihrem Test schreiben Läuft der Test dann durch? Hannah 10Jun10 10:39 Bin gerade dabei die parseCommandLineArguments Funktion mit den Optionen input-file und output-file zu testen. Hock' jetzt schon 'ne Weile dran und find' den Fehler nicht. Vielleicht hat jemand gerade mehr Gehirnschmalz, als ich. Hier das Codestück in der Grep.cpp (Ich hoffe, dass ist OK, wenn ich das hier rein Stelle, ist ja nicht wirklich viel mehr als das von der Vorlesung): Mein Test: Fehlermeldung: Den Test für das input file hab' ich im Prinzip analog dazu gemacht. Der funktioniert. MartinS 10Jun10 10:34 @Simson: Indeed, da fehlt ein Punkt, danke für den Hinweis! Habe ihn jetzt gerade noch zugefügt und die neue Version committed. Machen Sie einfach Sollte isMatch("This is just a line", "a..ne$") wirklich wahr zurückgeben? Fehlt da nicht ein . ? Simson 10Jun10 00:09 asd$ ff$
oder
asd$ ff
^^^^^^asdf$$$$$
// Of course, any combination of values for _caseSensitiveMatch and
// _regularExpressionMatch should work. For example, with _caseSensitiveMatch
// == true and _regularExpressionMatch == true, the following calls to isMatch
// should return true:
// isMatch("This is just a line", "^THis")
// If _regularExpressionMatch == true, the characters ^ and $ and . have a
// special meaning. Namely, the ^ matches only at the beginning of the line,
// the $ matches only at the end of the line, and the . matches any character.
FILE* testInputFile = NULL;
testInputFile = fopen("testfile.txt", "w");
fprintf("Testzeile 1\n");
(...)
fclose(testInputFile);
This is line 1.
This is line 3 and the line is too long because it has too many characters: This
FILE* outFile = NULL;
outFile = fopen("testoutput", "r");
if (outFile != NULL)
{
char* line = new char[MAX_LINE_LENGTH + 1];
fgets(line, MAX_LINE_LENGTH + 1, outFile);
printf("Line: %s\n", line);
ASSERT_EQ('1', line[13]);
fgets(line, MAX_LINE_LENGTH + 1, outFile);
}
Line: ??,@??,@?
GrepTest.cpp:334: Failure
Value of: line[13]
Actual: '?' (4, 0x4)
Expected: '1'
Which is: '1' (49, 0x31)
#include <stdio.h>
int MAX_LINE_LENGTH = 80;
int main()
{
FILE* outFile = NULL;
outFile = fopen("testoutput", "r");
if (outFile != NULL)
{
char* line = new char[MAX_LINE_LENGTH + 1];
fgets(line, MAX_LINE_LENGTH + 1, outFile);
printf("Line: %s\n", line);
fclose(outFile);
}
}
static struct option options[] =
{
{"input-file" , 1, NULL, 'i'},
{"case-insensitive-match" , 0, NULL, 'c'},
{"output-file" , 1, NULL, 'o'},
{"regular-expression-match", 0, NULL, 'r'},
{NULL , 0, NULL, 0 }
};
optind = 1;
int c = 0;
while ((c = getopt_long(argc, argv, "i:co:r", options, NULL)) != -1)
fprintf(yourfile, "The string to be added")
Ich habe es jetzt im SVN korrigiert. Hannah 10Jun10 14:31
optind = 1;
while (true)
{
int c = getopt_long(argc, argv, "ioc", options, NULL);
if (c == -1) break;
switch (c)
...
argv[0] = const_cast<char*>("");
argv[1] = const_cast<char*>("--output-file=out.txt");
argv[2] = const_cast<char*>("P");
int argc = 3;
char* argv[3];
argv[0] = const_cast<char*>("");
argv[1] = const_cast<char*>("--output-file=out.txt");
argv[2] = const_cast<char*>("P");
// First parse the options.
struct option options[] =
{
{"input-file" , 1, NULL, 'i'},
{"output-file" , 1, NULL, 'o'},
{"case-insensitive-match", 0, NULL, 'c'},
{NULL , 0, NULL, 0 }
};
while (true)
{
int c = getopt_long(argc, argv, "ioc", options, NULL);
if (c == -1) break;
switch (c)
{
case 'i':
_inputFileName = optarg;
break;
case 'c':
_caseSensitiveMatch = false;
break;
case 'o':
_outputFileName = optarg;
break;
default:
printUsage();
exit(1);
}
Grep grep;
int argc = 4;
char* argv[4];
argv[0] = const_cast<char*>("");
argv[1] = const_cast<char*>("--output-file");
argv[2] = const_cast<char*>("out.txt");
argv[3] = const_cast<char*>("P");
grep.parseCommandLineArguments(argc, argv);
ASSERT_EQ(0, grep._inputFileName[0]);
ASSERT_EQ('P', grep._pattern[0]);
ASSERT_EQ(0, grep._pattern[1]);
ASSERT_EQ('o', grep._outputFileName[0]);
ASSERT_EQ('u', grep._outputFileName[1]);
ASSERT_EQ('t', grep._outputFileName[2]);
ASSERT_EQ('.', grep._outputFileName[3]);
ASSERT_EQ('t', grep._outputFileName[4]);
ASSERT_EQ('x', grep._outputFileName[5]);
ASSERT_EQ('t', grep._outputFileName[6]);
Value of: grep._outputFileName[0]
Actual: '\0' (0, 0x0)
Expected: 'o'
Which is: 'o' (111, 0x6F)
Hannah 10Jun10 00:14