In C Sie haben Zeicheneingabe orientierte Funktionen (zB getchar
, fgetc
), haben Sie formatierte Eingabe Funktionen (zB die scanf
Familie) und dann hast du Zeilenorientierte Eingabe Funktionen. (z.B. fgets
und POSIX getline
). Wenn Sie Zeilen Daten, Zeile orientierte Eingabe Funktionen lesen, sind das richtige Werkzeug für den Job. (Unter Benutzereingabe mit scanf
hat viele Fallen, die neue (und auch nicht so neu) C-Programmierer in den Herbst)
Alle Linie orientierte Funktionen lesen und schließen die '\n'
im Puffer sie zu füllen. Sie können und sollten den Zeilenumbruch aus dem resultierenden Puffer entfernen, wenn er später in Ihrem Code verwendet wird. Eine einfache
size_t n = strlen (buf);
if (buf[n-1] == '\n')
buf[--n] = 0;
ist alles, was Sie das hintere '\n'
mit einem nul abbreche Zeichen zu überschreiben müssen. Wenn Sie die Zeile sofort drucken und nicht für die spätere Verwendung speichern, lohnt es sich nicht, den Zeilenumbruch zu entfernen (berücksichtigen Sie dies in Ihrer Ausgabe Formatstring).
zusammen die Stücke Einlochen, können Sie jede Zeile lesen, verarbeiten die erste, indem sie es einfach ausgegeben wird, und für jede verbleibende Leitung, analysieren die Zeit (vermutliche einige verstrichene Zeit) aus der vollständigen Zeichenfolge gelesen von fgets
mit sscanf
und Formatieren Sie die Ausgabe wie angegeben. Z.B.
#include <stdio.h>
#define MAXC 64 /* define constants, don't use magic number in code */
int main (int argc, char **argv) {
char buf[MAXC] = ""; /* buffer to hold each line -- size as reqd */
int line = 1;
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
while (fgets (buf, sizeof buf, fp)) { /* read each line in file */
char et[MAXC] = ""; /* buffer for holding time */
if (line == 1) /* if 1st line, just print */
printf ("%d : %s", line, buf); /* note: \n included by fgets */
else {
if (sscanf (buf, "%s", et) != 1) { /* parse up to first whitespace */
fprintf (stderr, "error: invalid conversion, line %d\n", line);
return 1;
}
printf ("%d : %s\n", line, et); /* output elapsed time only */
}
line++; /* increment line count */
}
if (fp != stdin) fclose (fp); /* close file if not stdin */
return 0;
}
Anmerkung: Sie gegen Puffer auf Parse überrannt schützen sollen einen Feldbreite Bezeichnern in dem sscanf
Format-String, indem (zsscanf (buf, "%63s", et)
, und das ist ein Ort, der alles, was Sie magische Zahlen umfassen tun können in Ihrem Code, weil es keine Möglichkeit gibt, direkt eine variable Breite Spezifizierer für sscanf
angeben - es sei denn, Sie kreativ sprintf
verwenden, um die Format-String voraus zu erstellen Zeit - aber das ist für einen anderen Tag ..
Beispiel Eingabedatei
$ cat dat/et.txt
My test file
00:19.1 123456
00:35.4 testing whitespace end
Beispiel Verwendung/Output
$ ./bin/et <dat/et.txt
1 : My test file
2 : 00:19.1
3 : 00:35.4
Schauen Sie die Dinge über und lassen Sie mich wissen, wenn Sie weitere Fragen haben.
(Hinweis: Ich nehme den Dateinamen als erstes Argument für das Programm, oder lesen von stdin
, wenn kein Dateiname angegeben ist. C bietet für Befehlszeilenargumente - verwenden Sie sie. Es ist in Ordnung, um Eingabe bei Bedarf, andernfalls , seine viel einfacher, nur Argumente auf der Kommandozeile angeben :)
Hat Ihr Compiler die 'getline' Funktion haben: http://en.cppreference.com/w/c/experimental/dynamic/getline –
Drop the' & 'in' scanf ("% s", & filechar); '-' scanf() 'erwartet ein' char * 'und Sie übergeben ein' char (*) [50] ', das ein anderer Typ ist (obwohl der Wert passiert so, dass es nur "filechar" ist, also kommst du damit durch. –
Benutze entweder ['fgets()'] (http://pubs.opengroup.org/onlinepubs/9699919799/ Funktionen/fgets.html) oder POSIX ['getline()'] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/getline.html) um Zeilen zu lesen. Dann verwenden Sie 'strchr()' oder ähnliches, um das erste Leerzeichen zu finden. Oder lesen Sie die erste Zeile mit einem dieser beiden, lesen Sie dann die folgenden ersten Felder mit 'scanf ("% s% * [^ \ n]% * c ", erstes_Feld);' - siehe ['scanf()'] (http : //pubs.opengroup.org/onlinepubs/9699919799/functions/scanf.html) für eine Erklärung. Im Großen und Ganzen würde ich für zeilenbasierte Eingabe und 'strchr()' gehen; Sie könnten 'strtok()' oder 'sscanf()' verwenden. –