Frage zu String einlesen

Gast #2251377
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 ?
Gast #2251398
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.
Gast #2251404
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.
Gast #2251425
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
Gast #2251433
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.
#2251452
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.
#2251833
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.
#2251888
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.
Gast #2252444
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
#2253290
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.
#2253312
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.
Gast #2253763
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
}
#2253823
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.
Gast #2253876
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
}
Gast #2254253
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren