[C] Leerzeile hat einen komischen ASCII Wert

OP #3376886
Lesenswert?
• ▲
▼
Moin,

ich schreibe gerade ein Programm,
welches eine Txt Datei einliest und dann jeweils zählt,
wie häufig jeder Buchstabe vorkommt.
Dafür gehe ich die Zeilen des Textes immer zeichenweise durch
und vergleich sie mit einem Array in welchem ich das ALphabet 
gespeichert
habe. Dann addiere ich zu den jeweiligen Buchstaben Zählern einen hinzu.
Das klappt auch solagen ich keine Leerzeilen habe. Dann nämlich addiert
er mir gerne mal ein oder zwei zusätzlich hinzu.
Ich bin da mit meinem Latein ziemlich am Ende und nach 7 Std Suchen auch 
ziemlich gefrustet^^ Vielleicht ist es ja eine Fehler den einer von euch 
sofort sieht, wäre toll!

Vielen Dank schon mal,

Patrick
1
#include <stdio.h>
2
#include <string.h>
3
#define LNAME 31
4
#define LLINE 81
5

6
int main (void)
7
{
8
  char alphabet[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
9
  int alphcnt[26] = {0};
10

11
  int cnti = 0;
12
  int cntj = 0;
13
  FILE *pin, *pout;
14
  char name_in[LNAME], name_out[LNAME];
15
  char line[LLINE];
16
  memset( line, NULL, 80 ); //Setzt die ersten 80 Zeichen von line auf NULL
17

18
  do
19
  {
20
    printf("Enter name of input file : ");
21
    scanf("%30s", name_in);
22
    pin = fopen(name_in, "r");
23
  } while(pin == NULL);
24

25

26

27
  while(1)
28
  {
29

30
    fgets(line, LLINE, pin);     
31
   
32
    printf("%s", line);
33

34
    for(cntj = 0; cntj < 26; cntj++)
35
    {
36
        for(cnti = 0; cnti < LLINE; cnti++)
37
        {
38
            if(line[cnti] == alphabet[cntj])
39
               {
40
                    alphcnt[cntj]++;
41
                    printf("%d \n", alphcnt[cntj]);
42
               }
43
        }
44
    }
45

46

47
if(feof(pin)) break;
48
  }
49

50

51

52
 fclose(pin);
53

54
 system("PAUSE");
55
  return 0;
56
}
#3376902
Lesenswert?
• ▲
▼
Obiges Programm analysiert den Lesepuffer line[] unabhängig davon, wie 
lang der eingelesene Text ist. Somit werden z.B. bei Leerzeilen fast 
alle Zeichen aus der zuvor eingelesenen Zeile solange weitergezählt, bis 
die nächste Zeile aus der Datei keine Leerzeile mehr ist.

Das Programm sollte beim Auftreten der Null-Terminierung bzw. des 
Zeilenendes im Lesepuffer die Zählschleifen verlassen und mit der 
nächsten Zeile aus der Datei fortfahren.

Eine Leerzeile in einer TXT-Datei enthält nur das Zeilenende-Zeichen, 
i.d.R. die 2 ASCII-Codes 13 (Carriage Return) und 10 (Line Feed).
Gast #3376903
Lesenswert?
• ▲
▼
Die innere Schleife hat nicht auf die maximale Länge des Arrays begrenzt 
zu sein, sondern auf die Länge der aktuell gelesenen Zeile. Sonst werden 
laufend Speicherüberreste aus vorigen Zeilen mit einbezogen. Da fgets 
"bis zu" Zeichen holt, d.h. auch weniger, scheitert die Codelogik 
bereits, wenn nachfolgende Zeilen kürzer als vorhergehende sind. Eine 
Leerzeile ist dabei definitiv kürzer.
#3376905
Lesenswert?
• ▲
▼
mal abgesehen davon: ist das ganze Prinzip mit dem Alphabet im Array 
nicht eh sehr suboptimal? warum nutzt man nicht aus, das 'a' == 97, 'b' 
== 98,...?

also sowas wie
for(cnti...)
    alphcnt[line[cnti] - 97]++

eventuell noch mit Abfrage, ob ein Buchstabe zwischen 'a' und 'z' 
vorliegt...
Gast #3376908
Lesenswert?
• ▲
▼
Warum liest du eine ganze Zeile ein, wenn du jedes Zeichen einzeln 
untersuchst?
fgetc statt fgets.

Warum mit jedem Zeichen im Alphabet einzeln überprüfen?
Feststellen ob das eingelesene Zeichen >= 'a' und <= 'z' ist.
(Dafür gibt es die Funktion islower() aus der ctype.h)

Wenn das Zeichen ein Kleinbuchstabe ist, dann kannst du es als Index im 
Array nutzen.
alphcnt[zeichen-'a']++;

Aber warum auf Kleinbuchstaben einschränken?
1
  unsigned int alphcnt[256] = {0};
2

3
  int c;
4

5
 ... Datei öffnen 
6

7
  while((c=fgetc(pin)!=EOF)
8
  { 
9
      alphcnt[c]++
10
  }
11

12
  fertig
13
  Datei schließen

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