C- duplicate case value

Hallo!

Ich habe ein merkwürdiges Problem. Hier ich mein Code:

Ganz ein simpler Übungs-Code. Es werden in einer Datei Zeile, Wörter oder Buchstaben gezählt. Ja nachdem ob man l, c oder w mitgibt.

#include<stdio.h>


int main(int argc, char * argv[]){

    char mode = *argv[2];
    FILE *fp = fopen(argv[1], "r");
    int lc = 0, wc = 0, cc = 0;
    int item = 0;    
    
    if(mode == 'l'){
        while((item = fgetc(fp)) != EOF){
            if(item == '
'){
                lc++;
                    }
                        }
    printf("lines: %d 
", lc);
            }

    if(mode == 'c'){
        while((item = fgetc(fp)) != EOF){
            switch(item){
                case !('\0'): cc++; //line 23
                    break;
                case !(' '): cc++;
                    break;
                case !('
'): cc++;  //line 27
                    break;
                }
                        }
            printf("characters: %d 
", cc);
            }

    if(mode == 'w'){
        while((item = fgetc(fp)) != EOF){
            if(item == ' ' || item == '
'){
                wc++;
                            }
                        }
    printf("words: %d 
", wc);
            }
fclose(fp);
return 0;
}
```Der Compiler sagt: 

wc.c: In function ‘main’:
wc.c:27: error: duplicate case value
wc.c:23: error: previously used here

Ich habe die beiden Zeilen dazukommentiert. Das eigenartige nun: es scheint nicht von den Werten abzuhängen, denn ich habe probehalber die cases vertauscht - mit gleichbleibendem Fehler.  Auch eine Darstellung als hex-Zahlen hat  nicht gebracht.

Compiliert habe ich mit gcc -Wall -std=c99 -pedantic

Seht ihr  vielleicht den Fehler?

Grüße

Evgeni

dass der Code so grauenhaft aussieht, tut mir leid.

Aber irgendwie krieg ich den nicht besser hin!

also was mich wundert ist deine switch case Darstellung
mach die ! dann könnte es passen, weil die hab ich noch nie in einem switch case gesehen

        while((item = fgetc(fp)) != EOF){
            switch(item){
                case '\0': cc++; //line 23
                    break;
                case ' ': cc++;
                    break;
                case '
': cc++;  //line 27
                    break;
                }
            }

Hi!

Das ! ändert nichts an der Compilier-Beschwerde, hab ich schon probierts. Und reingetan hab ichs deswegen, weil die drei Zeichen eben nicht mitgezählt werden sollen.
Ich habe es so angeschrieben:



    if(mode == 'c'){
        while((item = fgetc(fp)) != EOF){
            switch(item){
                case '\0': ; 
                    break;
                case ' ':  ;
                    break;
                case '
': ;  
                    break;
               default: cc++;
                }


Hat auch nichDachts gebracht.

EDIT. nichts gebracht* natürlich

Tipp schreibs so

case '\0':
case ' ':
case '
':
  break;

dann schreib mal statt ‘\0’ direkt die 0 und statt ’
’ die 10, das sind die ASCII Werte dafür

Hilft alles nichts.

Aber wareum gibt es überhaupt denFehler, kannst du es dir erklären? Die cases sich doch auf keinen Fall gleich!

jo das geht eigentlich nicht, setzt mal nur die ASCII Werte ein 0, 20, 10

Das ! hat schon Einfluß darauf. Man könnte grundsätzlich sagen: Das geht bei switch eben nicht. Etwas… „fundierter“ würde klingen: Jeder Wert != 0 wird in C als ‚true‘ angesehen, und !true gibt ‚false‘ - also 0. Wenn die Ausrufezeichen dastehen, hat er also vermutlich zwei mal eine 0 dort stehen (und einmal einen Wert != 0, weil 0 ja false ist, und durch das ! zu einem Wert wird, der nicht 0 ist - zu welchem auch immer … vermutlich 0xFFFFFFFF :wink: ).

Das hier…

[QUOTE=Evgeni]Hi!



    if(mode == 'c'){
        while((item = fgetc(fp)) != EOF){
            switch(item){
                case '\0': ; 
                    break;
                case ' ':  ;
                    break;
                case '
': ;  
                    break;
               default: cc++;
                }

[/QUOTE]
Müßte aber funktionieren - zumindest schluckt der gcc das bei mir anstandslos - oder eben


              switch(item){
                  case '\0': //line 23
                  case ' ': 
                  case '
':  //line 27
                      break;
                  default: cc++;
              }

Im Notfall hast du … (es geht ja nur um drei Werte) … ja immernoch die Option
if (item!=’\0’ && item!=’ ’ && item!=’
') cc++;
:wink:

Ok, jetzt funktioniert das mit default. Allesdings immernoch nicht richtig.

Ich habe ein Test-file das ih übergebe. Drin steht das: text

Nicht mehr und nicht weniger. Aber er zählt immer 5 chars. Das \0 fang ich ab. Newline auch.

Wenn ich

text
text

schreibe, gibts 10 chars. Also kann EOF auch nicht da reinspielen.

Keine Ahnung.

Ratlos

du hast wahrscheinlich \r vergessen :wink:

Hilft nicht :frowning:

dann lass dir mal alle Zeichen ausgeben die du zählst

Ich hatt mal ein ähnliches Problem unter Windows. Ursache war, dass am Anfang der Datei ein unsichtbares Steuerzeichen stand, welches meinen Parser ständig auf Fehler laufen ließ. Die Datei mit einem Hex-Editor betrachten bringt Klarheit, was wirklich drin steht.