Forum: Compiler & IDEs Frage zu String einlesen


von Gerd (Gast)


Lesenswert?

Hallo,

ich lese mit dieser Funktion eine Zeile aus einer Datei:
1
int ReadLine (char* line, unsigned char len, int fd)
2
{
3
  int nbBytes=0, j=0;
4
  unsigned long Pos;
5
6
  Pos = getpos(fd);//Position merken
7
  nbBytes = read(fd, line, len);
8
  if(nbBytes == EMPTY) return (EMPTY);
9
  
10
  do
11
  {
12
    if(j > len) return (FAILED);
13
  }while(line[j++] != '\n');//Zeilenende suchen
14
  
15
  line[j-2] = '\0';
16
  seek(fd,Pos+j,FS_SEEK_SET); //An die Position nach der Zeile springen
17
  return (j);
18
}
19
//Aufruf
20
status = ReadLine(line,55,file);

hat jemand einen schnelleren code oder Tips für diese Aufgabe ?

von Peter II (Gast)


Lesenswert?

Gerd schrieb:
> hat jemand einen schnelleren code oder Tips für diese Aufgabe ?

auf jeden Fall die Datei nicht 2mal lesen. Du hast doch schon alle 
zeichen gelesen warum dann noch mal lesen?

von Gerd (Gast)


Lesenswert?

wo lese ich die Datei 2mal?

Die Datei hat unterschiedlich lange Zeilen.

Ich lese in einen buffer die maximale Länge einer Zeile im Beispiel 55 
Zeichen.
Nach dem lesen sollte der Zeiger der Datei am Anfang der nächsten Zeile 
stehen.

von Peter II (Gast)


Lesenswert?

Gerd schrieb:
> wo lese ich die Datei 2mal?

da hatte ich mich wohl verkuckt. Ich dachte das Readline steht noch in 
der funktion und es eine art Rekursion.

Aber das mit dem dem Seek macht für mich keinen sinn. Du müsstest doch 
automatisch auf der nächste zeile stehen wenn du das \n eingelesen hast.

von Klaus W. (mfgkw)


Lesenswert?

Gerd schrieb:
> Nach dem lesen sollte der Zeiger der Datei am Anfang der nächsten Zeile
> stehen.

Tut er das nicht nach dem Lesen sowieso?

Ein Zeichen suchen (z.B. das \n) kann man auch mit strchar().

von Rosa-Kleidchen (Gast)


Lesenswert?

Moin,

schau Dir mal fgets an!

char *fgets(char *puffer, int n, FILE *datei);

Die Funktion liesst entweder n Zeichen oder bis \n je nachdem, was als 
erstes anschlägt. Dann brauchst Du nicht blockweise lesen und das 
nochmalige durchlaufen des Strings entfällt.

Rosa

von Gerd (Gast)


Lesenswert?

ich lese von sd Karte.

Die Funktion um ein einzelnes Zeichen zu lesen gibt es, ist aber 
langsamer wie eine feste Länge an Zeichen zu lesen:

read(fd, line, len);

ich bräuchte die Funktion getline, der obige code ist mein Ansatz dazu.

von Gerd (Gast)


Lesenswert?

Hallo Rosa Kleidchen,

ja das wäre die richtige Funktion, leider gibt es die nicht in meiner sd 
Karte library.

von abc123 (Gast)


Lesenswert?

Äh... zufällig gleiches Problem oder gleiche Person?
Beitrag "Textfile zeilenweise von SD-Karte lesen"

von Klaus W. (mfgkw)


Lesenswert?

Gerd schrieb:
> Die Funktion um ein einzelnes Zeichen zu lesen gibt es, ist aber
> langsamer wie eine feste Länge an Zeichen zu lesen:

Du glaubst wirklich, die längere Laufzeit zum Lesen einzelner Zeichen 
ist irgendwie relevant im Vergleich zum ersten Zugriff auf eine 
SD-Karte?

Wenn die Funktionenn nicht vollkommen debil implementiert sind, lesen 
sie einen Sektor oder mehr auf einmal.
Das kostet beim ersten Mal mehr Zeit; egal ob mit read() oder 
zeichenweise.
Ab dann wird aus dem vorhandenen Puffer gelesen; da wäre read() 
schneller - aber das fällt nicht auf im Vergleich zum Lesen des Puffers 
von der Karte.

von Klaus W. (mfgkw)


Lesenswert?

abc123 schrieb:
> Äh... zufällig gleiches Problem oder gleiche Person?

Vielleicht beide in der gleichen Klasse? :-)

von Karl H. (kbuchegg)


Lesenswert?

Klaus Wachtler schrieb:
> Gerd schrieb:
>> Die Funktion um ein einzelnes Zeichen zu lesen gibt es, ist aber
>> langsamer wie eine feste Länge an Zeichen zu lesen:
>
> Du glaubst wirklich, die längere Laufzeit zum Lesen einzelner Zeichen
> ist irgendwie relevant im Vergleich zum ersten Zugriff auf eine
> SD-Karte?

@Gerd

Abgesehen davon, ist die Funktion sowieso falsch.

Und was Laufzeit anbelangt: Na dann warte mal ein bischen, bis bei dir 
das erste mal das Satzende knapp vor einem Sektorwechsel zu liegen 
kommt.


Warum glaubt eigentlich jeder Anfänger, er könne Funktionen mit seinem 
begrenzten Wissen und begrenzter Übung besser implementieren, als 
derjenige der eine Library gebaut hat und damit schon dokumentiert hat, 
dass er Ahnung von der Sache hat.

von P. S. (Gast)


Lesenswert?

Tip: Erst mal zeichenweise sauber implementieren, dann ueber 
Optimierungen Gedanken machen.

von Karl H. (kbuchegg)


Lesenswert?

Peter Stegemann schrieb:
> Tip: Erst mal zeichenweise sauber implementieren, dann ueber
> Optimierungen Gedanken machen.

Wobei der erste Schritt darin besteht, sich zu fragen:
Ist das schnell genug?
Wenn man die Antwort nicht weiß, dann müssen Zahlen her. Meist gewinnt 
man die mit einem Profiler. Wenn sich dann rausstellt, dass die bewusste 
Routine lediglich ein paar Prozent im einstelligen Prozentbereich 
verbraucht, kann man getrost davon ausgehen, dass sie schnell genug ist 
und sein Optimierungspotential erst mal an anderer Stelle austoben. 
Dort, wo Optimierungen dann auch tatsächlich was bringen.

von Rosa-Kleidchen (Gast)


Lesenswert?

>Warum glaubt eigentlich jeder Anfänger, er könne Funktionen mit seinem
>begrenzten Wissen und begrenzter Übung besser implementieren, als
>derjenige der eine Library gebaut hat und damit schon dokumentiert hat,
>dass er Ahnung von der Sache hat.
Woher weisst Du, dass derjenige, der die Lib implementiert, auch Ahnung 
von der Sache hat? Auch der hat mal klein angefangen genauso, wie Du! Es 
fällt kein Meister vom Himmel, wie Du weisst...
An Gerd: Schau Dir doch einfach die Implementierung von fgets an. 
Vielleicht kannst Du Teile davon wiederverwenden.
Rosa

von Gerd (Gast)


Lesenswert?

Hallo Rosa,

wo findet man diese Implementierung?

von Karl H. (kbuchegg)


Lesenswert?

Rosa-Kleidchen schrieb:
>>Warum glaubt eigentlich jeder Anfänger, er könne Funktionen mit seinem
>>begrenzten Wissen und begrenzter Übung besser implementieren, als
>>derjenige der eine Library gebaut hat und damit schon dokumentiert hat,
>>dass er Ahnung von der Sache hat.
> Woher weisst Du, dass derjenige, der die Lib implementiert, auch Ahnung
> von der Sache hat?

Weil man eine SD Library nicht einfach so schreibt.

Wer in der Lage ist, einen lauffähigen Verbrennungsmotor zu bauen, dem 
traue ich ohne näher hinzusehen ohne Weiteres zu, dass er mit Säge und 
Feile umgehen kann.

> Auch der hat mal klein angefangen genauso, wie Du!

Hat er. Ganz sicher sogar. Aber du kannst ohne mit der Wimper zu zucken 
davon ausgehen, dass eine SD-Library nicht seine erste 
Programmieraufgabe ist.

von Karl H. (kbuchegg)


Lesenswert?

Gerd schrieb:
> Hallo Rosa,
>
> wo findet man diese Implementierung?

Wie heißt denn deine Funktion zum Einzelzeichenlesen in der SD-Library?
Ich nehme mal an, die heißt getc
1
int gets( char * buffer, int n, int fd )
2
{
3
  char c = getc( fd );
4
  int  charsRead = 0;
5
6
  while( c != '\n' && n > 0 ) {
7
    *buffer++ = c;
8
    charsRead++;
9
    c = getc( fd );
10
  }
11
12
  *buffer = '\0';
13
14
  return charsRead;
15
}

Die Verwaltung der Blöcke und weiterschalten in den nächsten Block 
überlasst du sinnvollerweise der getc() Funktion.

von Gerd (Gast)


Lesenswert?

DANKE

so hab ichs jetzt:
1
int GetLine(int fd, char *buf, unsigned char n)
2
{
3
  char charsRead=0;
4
5
  if (fd < 0) return (-1);
6
7
  nav_select( fd );
8
9
  if ( file_eof() )  return(-1);
10
11
  char readChar=file_getc();
12
13
  while(readChar != '\n' && n > charsRead)
14
  {
15
    *buf++ = readChar;
16
    charsRead++;
17
    readChar = file_getc();
18
  }
19
20
  *buf = '\0';
21
22
  return charsRead;
23
}

von Karl H. (kbuchegg)


Lesenswert?

Deine eof Behandlung ist noch falsch.
Auch während des Einlesens kann nach jedem Versuch ein Zeichen zu lesen 
ein eof-Fall auftreten.

Und die Behandlung des Falles, das der Buffer voll geworden ist, ist 
denke ich auch noch falsch. In Buffer dürfen nicht mehr als n Zeichen, 
inklusive dem abschliessenden '\0' geschrieben werden. (Das hab ich 
allerdings in der Vorlage auch verbockt)


Und weil das oft (auch in Büchern) falsch gemacht wird:
eof wird erst dann true, wenn ein Leseversuch gescheitert ist. C 
versucht nicht, wie andere Sprachen, in die Zukunft zu schauen. Du 
machst einen Aufruf einer Lesefunktion, der hat nichts mehr zum Lesen 
und erst danach wird eof gesetzt. eof ermöglicht einem also im 
Nachhinein festzustellen, ob der Leseversuch geklappt hat und nicht im 
vorhinein festzustellen, ob der nächste Leseversuch klappen wird.
Ich hoffe mal, dass deine SD-Library in dieser Hinsicht auch korrekt 
programmiert ist.

von Gerd (Gast)


Lesenswert?

OK Danke für die Hinweise

Ich hoffe so passt es:
1
int GetLine(int fd, char *buf, unsigned char n)
2
{
3
  char charsRead=0;
4
5
  if(n==0) return (-1);
6
  if (fd < 0) return (-1);
7
8
  nav_select( fd );
9
10
  if ( file_eof() )  return (-1);
11
12
  U16 readChar=file_getc();
13
14
  while(readChar != '\n' && (n-1 > charsRead))
15
  {
16
    if(readChar == FS_EOF)  return (-1);
17
18
    *buf++ = readChar;
19
    charsRead++;
20
    readChar = file_getc();
21
  }
22
23
  *buf = '\0';
24
25
  return charsRead;
26
}

von Rosa-Kleichen (Gast)


Lesenswert?

Soso, Karl Heinz Buchegger, soso, Verbrennungsmotor, tssss.
Jeder kleine Freak baut Dir irgendeine Lib, aber bestimmt keinen 
Verbrennungsmotor. Äpfel und Birnen kann sogar ein Bauer vergleichen.
Rosa

von Karl H. (kbuchegg)


Lesenswert?

Ach weißt du was Rosa .....

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.