K & R Übung: Mein Code funktioniert, aber Feels Stinky; Tipps für die Bereinigung?

8

Ich arbeite am K & R-Buch. Ich habe weiter gelesen, als wenn ich Übungen gemacht habe, meistens aus Zeitmangel. Ich hole auf und habe fast alle Übungen aus Kapitel 1 gemacht, das ist das Tutorial.

Mein Problem war Übung 1-18. Die Übung soll:

  

Schreiben Sie ein Programm, um nachgestellte Leerzeichen zu entfernen und   Tabs aus der Eingabezeile und vollständig leere Zeilen löschen

Mein Code (unten) macht das und funktioniert. Mein Problem damit ist die Trimmmethode, die ich implementiert habe. Es fühlt sich ... falsch ... irgendwie an. Wenn ich in einem Code-Review ähnlichen Code in C # sehe, würde ich wahrscheinlich verrückt werden. (C # ist eine meiner Spezialitäten.)

Kann mir jemand Ratschläge geben, wie man das aufräumt - mit dem Haken, dass dieser Ratschlag nur das Wissen aus Kapitel 1 von K & amp; R. (Ich weiß, es gibt unzählige Möglichkeiten, dies mit der vollen C-Bibliothek zu beseitigen; wir reden hier nur von Kapitel 1 und von grundlegender stdio.h). Kannst du mir auch erklären, warum es hilft, wenn du den Rat gibst? (Ich versuche schließlich zu lernen! Und wer könnte besser als die Experten hier lernen?)

%Vor%

EDIT: Ich schätze all die hilfreichen Tipps, die ich hier sehe. Ich möchte die Leute daran erinnern, dass ich immer noch ein N00b mit C bin, und speziell noch nicht auf Zeiger gekommen bin. (Erinnere dich an den Abschnitt über Ch.1 von K & amp; R - Ch.1 macht keine Zeiger.) Ich "irgendwie" bekomme einige dieser Lösungen, aber sie sind immer noch ein bisschen fortgeschritten für wo ich bin .. .

Und das meiste, wonach ich suche, ist die Trim-Methode selbst - speziell die Tatsache, dass ich 3 Male durchlaufe (was sich so schmutzig anfühlt). Ich habe das Gefühl, wenn ich nur ein bisschen schlauer wäre (auch ohne das fortgeschrittene Wissen von C), hätte das sauberer sein können.

    
John Rudy 02.10.2008, 11:49
quelle

9 Antworten

5

Es gibt keinen Grund, zwei Puffer zu haben, Sie können die Eingabezeile an Ort und Stelle trimmen

%Vor%

Indem Sie die Zeilenlänge zurückgeben, können Sie Leerzeilen eliminieren, indem Sie nach Zeilen mit einer Länge ungleich Null suchen

%Vor%

EDIT: Sie können die while-Schleife noch einfacher machen, vorausgesetzt, ASCII-Codierung.

%Vor%     
Ferruccio 02.10.2008, 12:06
quelle
9

Wenn Sie bei Kapitel 1 bleiben, sieht das ziemlich gut aus. Hier ist, was ich von einem Code-Review-Standpunkt empfehlen würde:

Wenn Sie die Gleichheit in C überprüfen, setzen Sie die Konstante immer zuerst

%Vor%

Auf diese Weise werden Sie niemals versehentlich so etwas tun:

%Vor%

Sie können damit in C # nicht durchkommen, aber es kompiliert sich gut in C und kann ein echter Teufel zum Debuggen sein.

    
Eric Z Beard 02.10.2008 11:56
quelle
1

trim () ist zu groß.

Was ich denke, dass Sie brauchen, ist eine Strichen-Funktion (gehen Sie voran und schreiben Sie es int stringlength (const char * s)).

Dann brauchen Sie eine Funktion namens int scanback (const char * s, const char * Übereinstimmungen, int start), die beim Start beginnt, bis z herunterfährt, solange das Zeichen bei s id in Übereinstimmungen gescannt wird letzter Index, in dem eine Übereinstimmung gefunden wird.

Dann brauchen Sie eine Funktion mit der Bezeichnung int scanfront (const char * s, const char *), die bei 0 beginnt und vorwärts scrollt, solange das in s gescannte Zeichen in Übereinstimmungen enthalten ist und den letzten Index mit einer Übereinstimmung zurückgibt gefunden wird.

Dann brauchen Sie eine Funktion namens int charinstring (char c, const char * s), die nicht Null zurückgibt, wenn c in s enthalten ist, sonst 0.

Sie sollten in der Lage sein, trim in Bezug auf diese zu schreiben.

    
plinth 02.10.2008 12:39
quelle
1

Persönlich für während konstruiert:

Ich bevorzuge Folgendes:

%Vor%

zu:

%Vor%

Sie sehen beide gegen! = 0, aber der erste sieht etwas sauberer aus. Wenn das Zeichen irgendetwas anderes als 0 ist, wird der Schleifenkörper ausgeführt, andernfalls wird er aus der Schleife ausbrechen.

Auch für "for" -Aussagen finde ich Folgendes, obwohl es syntaktisch gültig ist:

%Vor%

sieht für mich einfach 'seltsam' aus und ist tatsächlich eine potentielle Albtraumlösung für potentielle Fehler. Wenn ich diesen Code überprüfen würde, wäre es wie eine glühende rote Warnung. Normalerweise möchten Sie for-Schleifen verwenden, um eine bekannte Anzahl von Wiederholungen zu durchlaufen. Andernfalls können Sie eine while-Schleife verwenden. (Wie immer gibt es Ausnahmen von der Regel, aber ich habe festgestellt, dass dies im Allgemeinen gilt). Das obige für die Aussage könnte werden:

%Vor%     
TK. 02.10.2008 12:19
quelle
0

Vor allem:

  

int main (void)

Sie kennen die Parameter von main (). Sie sind nichts. (Oder argc & amp; argv, aber ich denke nicht, dass das Material von Kapitel 1 ist.)

Stilistisch können Sie K & R-Klammern ausprobieren. Sie sind viel einfacher im vertikalen Bereich:

%Vor%

(Auch Kommentare hinzugefügt und einen Fehler behoben.)

Ein großes Problem ist die Verwendung der MAXLINE-Konstante - main () verwendet sie ausschließlich für die Zeile und out Variablen; trim (), das nur an ihnen arbeitet, muss die Konstante nicht verwenden. Sie sollten die Größe (n) als Parameter übergeben, genau wie in getline ().

    
aib 02.10.2008 12:26
quelle
0

Persönlich würde ich einen solchen Code schreiben:

%Vor%

in eine separate Funktion (oder sogar ein definiertes Makro)

    
ilitirit 02.10.2008 13:29
quelle
0
  1. trim sollte in der Tat nur einen Puffer verwenden (wie @ Ferruccio sagt).
  2. trim muss aufgebrochen werden, wie @plint sagt
  3. trim muss keinen Wert zurückgeben (wenn Sie nach einem leeren String suchen möchten, testen Sie Zeile [0] == 0)
  4. für extra C Geschmack, verwenden Sie lieber Zeiger als Indizes

-go bis zum Ende der Zeile (beendet 0; - Wenn nicht am Anfang der Zeile und das aktuelle Zeichen Leerzeichen ist, ersetzen Sie es durch 0. - Zurück von einem Char

%Vor%     
Arkadiy 02.10.2008 13:42
quelle
0

Ein anderes Beispiel, das Gleiche zu tun. Habe einen kleinen Verstoß mit C99-spezifischen Sachen gemacht. das wird nicht in K & amp; R gefunden werden. nutzte auch die Funktion assert (), die Teil der stardard-Bibliothek ist, aber wahrscheinlich nicht im ersten Kapitel von K & R behandelt wird.

%Vor%     
Frederico 02.10.2008 19:03
quelle
0

Hier ist mein Stich bei der Übung, ohne zu wissen, was in Kapitel 1 oder K & amp; R. Ich nehme Zeiger an?

%Vor%     
orj 02.10.2008 13:21
quelle

Tags und Links