C Bin ich blöd oder mache ich was falsch ?

DRMCW

Cadet 3rd Year
Registriert
Nov. 2009
Beiträge
59
Tag Leute,

ich habe folgendes Problem, und komme nicht auf die Lösung. Es handelt sich hier bei um eine Übungsaufgabe.
Per While schleife soll ich soll ich per Scanf den Variablen werte zuweisen soweit so gut.

ptr2wert ist ein Array, der seine eigene form hat, per Typedef und Struct. Messwerte.

Mein problem hier bei ist die Eingabe. Der Erste durchgang geht wunderbar. Ich kann werte eingeben, kein Problem. Wenn ich aber dann noch neue werte eingeben möchte, im zweite durchgang geht das nicht. Ich dachte es leigt am Tastaturpuffer, deswegen ja fflush(stdin). Aber selbst damit bekomme ich keine möglichkeit eine neue eingabe zu machen das programm springt an die Letzte frage. ich kann dann aber was eingeben aber ergeht dann nicht raus. Selbst n oder ein j geht nicht. ich denke mal das der Tastaturpuffer mit \n gesetzt ist. Wie bekomme ich den jetzt frei ?
C:
    while(buchstabe != 'n'){
        
        ptr2wert[i].messnr = i;
        printf("Neuer Messwert? ");
        fflush(stdin);
        scanf("%lf", &ptr2wert[i].messwert);
      
        ptr2wert[i].objekt.objektNr = i;
        printf("Neue Objektbezeichnung? ");
        fflush(stdin);
        scanf("%19s", ptr2wert[i].objekt.bezeichnung);
        
        
        printf ("Möchten sie Noch ein Messwert eingeben?");
        fflush(stdin);
        scanf("%c ", &buchstabe);
        i++;
        fflush(stdin);
        
    }
 
Zuletzt bearbeitet:
Kannst du mal bitte den ganzen Code posten
 
Wollte ich auch grad fragen, vor allem die struct Definition
 
struct Messwerte und Messojekt sind so vorgeben und typedef auch.


C:
#include <stdio.h>
#include <stdlib.h>

struct Messobjekt{
    int objektNr;
    char bezeichnung[20];
    
};

typedef struct Messobjekt Mymessobjekt;
typedef struct Messwert   Mymesswert;

struct Messwert{
    struct Messobjekt objekt;
    int messnr;
    double messwert;
    
};





int main(int argc, const char * argv[]) {
    char buchstabe= 'j';
    int i = 0;
    Mymesswert *ptr2wert;
    
    
    ptr2wert = (Mymesswert *)malloc(sizeof( Mymesswert *) *10);
    
    if (ptr2wert == NULL){
        
        return 0;
    }
    
    while(buchstabe != 'n'){
        
        ptr2wert[i].messnr = i;
        printf("Neuer Messwert? ");
        fflush(stdin);
        scanf("%lf", &ptr2wert[i].messwert);
      
        ptr2wert[i].objekt.objektNr = i;
        printf("Neue Objektbezeichnung? ");
        fflush(stdin);
        scanf("%19s", &ptr2wert[i].objekt.bezeichnung);
        
        
        printf ("Möchten sie Noch ein Messwert eingeben?");
        fflush(stdin);
        scanf("%c ", &buchstabe);
        i++;
        fflush(stdin);
        
    }
    printf("Jetzt sind die Messwerte eingebeben!");
    
    
    
    int x = 0;
    
    for (;x < i; x++ ){
        printf("%d\n ",ptr2wert[x].messnr);
        printf("%f\n ",ptr2wert[x].messwert);
        printf("%s\n ",ptr2wert[x].objekt.bezeichnung);
        printf("%d\n ",ptr2wert[x].objekt.objektNr);
        
    }
    
    
    
    
    
    
    free(ptr2wert);
}
 
Poste mal bitte die Ausgabe deines Programms bis zu dem Punkt, an dem es nicht mehr weitergeht.

Auf welchem OS bist du unterwegs ? fflush(stdin) unter Linux funktioniert nicht wie gewünscht
 
Hi,


ich würde grundsätzlich mal das was du in Buchstabe eingelesen hast vor Ende der Schleife nochmal ausgeben um sicherzugehen was drinnen steht und somit als Vergleich für die Schleife hergenommen wird.

Arbeitest du in einer Windows Umgebung? Den nur dort funktioniert fflush(stdin).

Bezüglich dem \n im stdin:
https://stackoverflow.com/questions...th-a-while-loop-to-input-two-separate-strings

Nicht ganz dein Thema aber in den Kommentaren und Lösungen wird auf das \n Problem hingewiesen.
Eine der Lösungen verwendet getchar(); nach dem scanf um das \n wegzubekommen.

LG
 
Denke das Problem ist der Tastaturpuffer, entferne den flush und im scanf machst du eine zweite Variable Temp (die hat dann den ASCII-Code 10 (Line Feed lf)
scanf("%c ", &buchstabe) wird zu scanf("%c%c", &buchstabe, &temp);

temp natürlich auch als char deklarieren
 
ich Programmiere auf Mac OS 10.14

Die Whileschleife geht er einmal durch und kann die Sachen eingeben, möchte ich aber Neue Messwerte überspringt er alles, als würde er Scanf selber setzten.



C:
#include <stdio.h>
#include <stdlib.h>

struct Messobjekt{
    int objektNr;
    char bezeichnung[20];
    
};

typedef struct Messobjekt Mymessobjekt;
typedef struct Messwert   Mymesswert;

struct Messwert{
    struct Messobjekt objekt;
    int messnr;
    double messwert;
    
};





int main(int argc, const char * argv[]) {
    char buchstabe= 'j';
    int i = 0;
    Mymesswert *ptr2wert;
    
    
    ptr2wert = (Mymesswert *)malloc(sizeof( Mymesswert *) *10);
    
    if (ptr2wert == NULL){
        
        return 0;
    }
    
    while(buchstabe != 'n'){
        
        ptr2wert[i].messnr = i;
        printf("Neuer Messwert? ");
        fflush(stdin);
        scanf("%lf", &ptr2wert[i].messwert);
      
        ptr2wert[i].objekt.objektNr = i;
        printf("Neue Objektbezeichnung? ");
        fflush(stdin);
        scanf("%19s", &ptr2wert[i].objekt.bezeichnung);
        
        
        printf ("Möchten sie Noch ein Messwert eingeben?");
        fflush(stdin);
        scanf("%c ", &buchstabe);
        i++;
        fflush(stdin);
        
    }
 
my € 0.02: scanf() rausschmeissen und durch die Kombination fgets()/sscanf() ersetzen. Alles andere mag auf einem System irgendwie mal gehen, auf dem anderen aber wieder nicht. scanf() ist böse!

/edit: ich habe einige winzige Änderungen an Deinem Code vorgenommen, das hier sollte jetzt immer funktionieren:
C:
#include <stdio.h>
#include <stdlib.h>

struct Messobjekt {
  int objektNr;
  char bezeichnung[20];
};

struct Messwert {
    struct Messobjekt objekt;
    int messnr;
    double messwert;
};

typedef struct Messobjekt Mymessobjekt;
typedef struct Messwert   Mymesswert;

int main(int argc, const char * argv[])
{
char buchstabe = 'j';
int i = 0;
Mymesswert *ptr2wert;

ptr2wert = (Mymesswert *)malloc(sizeof(Mymesswert) * 10); // !! * falsch
if (ptr2wert == NULL) {
     return 0;
}

while (buchstabe != 'n') {
     char buf[128];
     ptr2wert[i].messnr = i;

     printf("Neuer Messwert (real): ");
     fgets(buf, sizeof(buf), stdin);
     sscanf(buf, "%lf", &ptr2wert[i].messwert);
     ptr2wert[i].objekt.objektNr = i;

     printf("Neue Objektbezeichnung (string): ");
     fgets(buf, sizeof(buf), stdin);
     sscanf(buf, "%19s", &ptr2wert[i].objekt.bezeichnung);

     printf("Möchten sie noch einen Messwert eingeben? [j/n]:");
     fgets(buf, sizeof(buf), stdin);
     sscanf(buf, "%c", &buchstabe);
     i++;
}
Zeile 24| war bei Dir falsch. Kannst Du mir erklären warum? ;)
 
Zuletzt bearbeitet:
Wurde zwar schon genannt, aber nochmal ganz explizit, denn das wird immer falsch gemacht und ist sehr wichtig: fflush(stdin); ist undefined behavior!
Also niemals verwenden, auch wenn manche Compiler das unterstützen, ist das unglaublich schlechter Code und es gibt viele andere Möglichkeiten das Problem zu lösen ohne den input stream zu flushen.

Gruß
BlackMark
 
Jetzt hab ich mir das Problem angeschaut, nur um kurz vorm Posten zu sehen, dass @Pille1002 eh schon eine korrekte Lösung gepostet hat. Ich hätte "buchstabe" als char array definiert, und das letzte scanf mit "%2s" aufgerufen. (Dann natürlich auf (buchstabe[0] != 'n' abgefragt). Aber die Lösung von Pille1002 ist eh in Ordnung. Was lernt man daraus? Scanf ist nicht verwendbar ;). Diese fflush Versuche sind aber auch nicht sinnvoll.
 
Hmm, gestern abend hab ich nur rasch versucht, das Problem irgendwie zu lösen. Heute hab ich mir die Beschreibung zu scanf ein wenig genauer angeschaut. Du bekommst das gewünschte Ergebnis, wenn Du folgende scanf Formate verwendest: (Leerzeichen beachten!)

C:
scanf(" %lf", &ptr2wert[i].messwert);
...
scanf("%19s", &ptr2wert[i].objekt.bezeichnung);
...
scanf(" %c", &buchstabe);

Die Variante von @blöderidiot (kein scanf, sondern fgetss/sscanf) ist natürlich auch gut, wenn allerdings die Aufgabenstellung ist, dass man scanf verwenden muss, dann ist das vermutlich keine gültige Lösung.
Das ist keine leichte Aufgabe ;)
 
danke jetzt geht es. Danke für eure hilfe.


Kennt ihr euch auch mit Calloc aus ?

da die nächste aufgabe heißt
setze in der Struct Messwert das Messojekt von objekt auf *objekt.

und ich muss mit Calloc weiteren speicher allokieren.
 
Klar kennen wir uns mit calloc aus (besser als mit scanf zumindest). Aber jetzt wirkt das ganze schon ein bisserl nach Hausaufgaben lösen. Wenn Du eine konkrete Verständnisfrage hast, dann solltest Du diese stellen.
 
Das sind keine Hausaufgaben, sind aufgaben für das Verstädnis für C die wir für die Vorlesung zum verständinis brauchen. Es gibt dann noch die weitere Praktikumsaufgaben.

ich habe das große problem ein FiFo selber zuerstellen. da habe ich wirklich verständissprobleme. Da wir dort alles selber restellen sollen und keine Listen etc. benutzten sollen. Also verkettete Listen.
 
@DRMCW

Ich kann dir nur "C - Programmieren von Anfang an" von Erlenkötter empfehlen. Hat mir damals für die C Vorlesungen sehr geholfen. Klein, smart, gut. :)
 
@_killy_ danke. Habe mir schon das Buch C++ Für SpieleEntwicklung oder so mir besorgt. Leider bin ich dazu noch nicht gekommen das Durchzuarbeiten immer nur kleine Sachen, aber C ist da halt nicht wirkich beschrieben. Meist ist das immer ein Problem, beim Programmieren das ich erst nach mehrmaligen ausprobieren und drüber schlafen erst eine Lösung bekomme und nicht sofort eine Lösung bekomme. Da wir meist nur ein Paar Tage zum verstehen habe.

Dann Programmiere ich auch noch auf Windows per Netbeans und Mac Xcode und dann nebenbei in Java
da muss man auch ettliche sachen um und einstellen etc, da gibt es auch weitere unterschiede, bsw fflsuh(stdin) das steht im keinem Buch das das nicht orderntlich funktioniert, und das Problem hat micht wahnsinnig gemacht, und diese kleinigkeiten sind das was mich aufregt.
 
DRMCW schrieb:
@_killy_ [...] bsw fflsuh(stdin) das steht im keinem Buch das das nicht orderntlich funktioniert
Da muss ich jetzt aber die Bücher in Schutz nehmen. In meinem C-Buch (Kernighan/Ritchie The C Programming Language) steht das genau drinnen: "On an output stream, fflush causes any buffered but unwritten data to be written; on an input stream, the effect is undefined". Im C11 Standard steht das inhaltlich genauso drinnen. Dass fflush einen reset Effekt bei einem Input-Stream haben könnte ist eine - ich sage einmal so - kreative Idee.
 
Zuletzt bearbeitet: (typo)
Zurück
Oben