C - zwei Strings einlesen

Frank

Anfänger
Hallo,

ich möchte zwei Strings sicher nach einander einlesen.
Das Problem ist das '\n' das in der stdin bleibt.

Mein erster Ansatz:
Code:
#include <stdio.h>
#include <string.h>

#define BUF 4

void myFgets(char *str) {
    fgets(str, BUF, stdin);
}


int main(int argc, char **argv) {
    char stringA[BUF];
    char stringB[BUF];
    char *p;
    printf("StringA eingeben: ");
    //fgest liest das \n Zeichen mit ein
    //zB: 12<enter> =>12\n\0  <-- string ist drei Zeichen lang
    myFgets(stringA);

    printf("%i\n", strlen(stringA));
    
    // hier '\n' abschneiden loest mein Problem natrrlich nicht
    // fflush(stdin) geht nach meinem jetzigen Wissensstand nicht
    // da nur fuer output streams
    if((p = strchr(stringA, '\n')) != NULL)
        *p = '\0';
    // string 12<enter> ist jetzt nur noch zwei Zeichen lang
    // 12\0

    printf("%i\n", strlen(stringA));

    printf("StringB eingeben: ");
    myFgets(stringB);
    printf("string: %s", stringA);
    printf("string: %s", stringB);
    return 0;
}

Mein Problem:
Wenn der erste String (stringA) länger ist als BUF, dann liest er automatisch
den zweiten Stiring (stringB) mit ein.
Beispiel:
StringA eingeben: 1234
stringA = 123
stringB = 4

Ich habe auch noch mit getchar .. != '\n' rumgespielt.

Bisher bin ich bei folgender Lösung:
Code:
#include <stdio.h>
#include <string.h>
const int STR_SIZE = 5;

void myFgets(char* str) {
    printf("Bitte string eingeben (max Laenge %i): ", STR_SIZE-2);
    if (fgets(str, STR_SIZE, stdin) != NULL) {
        char *nl = strchr(str, '\n');
        if (nl == NULL) {
            /**
             *  Newline not found, input string too long for target buffer.
             *  Repeatedly read from input stream into a dummy buffer
             *  until newline is seen or fgets() returns EOF or error.  
             */
            char dummy[STR_SIZE];
            char *r;
            printf("Warning - input string longer than expected, ignoring excess characters\n");
            do {
                r = fgets(dummy, sizeof dummy, stdin);
            } while (r != NULL && strchr(dummy, '\n') == NULL);
        }
        else {
              /**
               *      * Input string is okay, remove newline character
               */
            *nl = 0;
        }
    }
    else {
           /**
            * EOF or error detected on read; handle that here
            */
    }
}

int main() {
    char strA[STR_SIZE];
    char strB[STR_SIZE];
    myFgets(strA);
    myFgets(strB);
    printf("%s\n", strA);
    printf("%s\n", strB);
    return 0;
}

Was haltet Ihr davon?
Geht das eleganter und oder sicherer?

Gruß Frank
 
Du wirst wohl nicht darum herumkommen, dass immer einen temporaeren Buffer fuellst und dann den nach dem '\n' durchsuchst. Im Grunde machst du das ja in der 2. Loesung.
 
sbuf(9) ist Dein Freund. Lass' Dich nicht durch Sektion 9 irritieren, das klappt auch im Userspace. :)

Einen Blick in subr_sbuf.c zu riskieren bietet ein gutes Beispiel als Startpunkt, um eine abgeleitete Eigenimplementierung zu realisieren, falls erforderlich.
 
Zuletzt bearbeitet von einem Moderator:
Hier ein Beispiel (quick and dirty) bzgl. Umgang mit sbufs:
Code:
#include <stdio.h>
#include <sys/sbuf.h>

#define BUF_LEN 5

struct sbuf *my_fgets(FILE *fp, int len);

struct sbuf *  
my_fgets(FILE *fp, int len)
{
	struct sbuf *tmp;
        int max_len;
        int c; 	

	tmp = sbuf_new(NULL , NULL, len, SBUF_FIXEDLEN);
	if (tmp) {		
                max_len = tmp->s_size - 1;
		
                (void)printf("Bitte String eingeben (max Laenge %i): ", max_len);

                c = getc(fp);
		while (tmp->s_len < max_len) {
			if (c == EOF)
				break;
		
			if (c == '\n')
				break;
				
			(void)sbuf_putc(tmp, c);	
			c = getc(fp); 
		}
		
		sbuf_finish(tmp);
                (void)fpurge(fp);		
	}
	
	return(tmp);
}


int 
main(void)
{
	struct sbuf *s;
	
	s = my_fgets(stdin, BUF_LEN);
	if (s) {
		(void)printf("%s\n", sbuf_data(s));
		sbuf_delete(s); 
	}	
	return(0);
}
mit
Code:
cc -lsbuf etc.pp.
kompilieren.
 
Zuletzt bearbeitet von einem Moderator:
Danke für Eure Tipps.
Teste sie gerade ausgiebig.

sbuf kannt ich nicht, danke.

getline wollte ich erst nicht nehmen, da es nicht ansi c ist und die
Länge des einzulesen Speicher ertsmal nur ein Vorschlag ist und getline den
Speicher auf die erforderliche Größe ausdehnt.
 
Zurück
Oben