2012-04-15 14 views
0

Meine Aufgabe besteht darin, zwei Ziffernfolgen zu lesen und sie in verschiedenen Arrays zu speichern. Ich habe mich für die scanf-Funktion entschieden, aber das Programm kann nur die erste Zeichenfolge lesen. Das ist mein schlechter Code.Scanf und zwei Strings

int main() 
{ 

    int firstArray[50], secondArray[50], i, j; 

    /* fill an array with 0 */ 
    for(i=0; i<50; ++i) 
    { 
     firstArray[i]=secondArray[i]=0; 
    } 

    i=j=0; 

    while((scanf("%d", &firstArray[i]))== 1) { ++i; } 
    while((scanf("%d", &secondArray[j]))== 1) { ++j; } 

    /* Print this. */ 
    for(i = 0; i < 20; ++i) 
    { 
     printf("%d ", firstArray[i]); 
    } 
    putchar('\n'); 

    for(j = 0; j < 20; ++j) 
    { 
     printf("%d ", secondArray[j]); 
    } 

    return 0; 
} 

Ich verstehe einfach nicht, wie scanf Funktion funktioniert. Kann mir bitte jemand erklären?

+0

Wie sieht die Eingabe für 'scanf' aus? –

+0

#first line 123 54 34 54 3455 [Ende der Zeile; oder \ n]. Und die # zweite Zeile ist das gleiche/ – Ascelhem

+0

@ user1334306 Lesen Sie diesen Kommentar nur jetzt, um meine Antwort zu aktualisieren! – ShinTakezou

Antwort

0

Sie können scanf nicht verwenden, um dies zu tun.

Lesen Sie die documentation.

Beobachtungen:

  1. mit scanf, wenn Sie eine Ziffer der Schleife eingeben läuft immer
  2. gibt keine Überprüfung auf die Größe Ihrer Arrays 50 Limit ist
  3. wenn Sie return drücken Sie dann ignoriert er diese Linie, weil stimmt nicht mit Ihrem Muster überein
  4. Wenn Sie einen Buchstaben eingeben, stimmt das Muster nicht überein und die Schleife wird unterbrochen

Verwenden Sie also eine andere Funktion, z. B. gets, atoi oder strtol. Und denken Sie daran, die Größe 50 Ihrer Arrays zu überprüfen.

+0

scanf wird nicht für immer laufen, wenn Nummer eingegeben wird, wird er diese Nummer lesen und wenn nächste Lese nicht eine Zahl oder leer ist brechen Sie die While-Schleife. Ein Brief wird nicht zu einer Ausnahme führen. Es wird einfach nicht gelesen und beide While-Schleifen werden beendet. – Morpfh

+0

Wenn es nicht Nummer ist, haben Sie einen Fehler, wenn Sie leer eingeben, überspringt diese Zeile und setzt die Schleife fort. Versuch es. – dash1e

+0

Wenn es * keine Zahl * oder * kein Leerzeichen ist, bricht es die While-Schleife. Wenn es keine Nummer ist, ist es kein Fehler. Er prüft, ob scanf in 1 gelesenen Gegenstand resultiert. Wenn also eine nicht leere oder nicht nummerierte Zahl vorhanden ist, gibt scanf 0 zurück und die while-Schleife bricht ab. Keine Ausnahme oder Fehler. – Morpfh

0

scanf ignoriert leere Zeichen (einschließlich neuer Zeile). Daher wird Ihr Scan die gesamte Eingabe in firstArray lesen, wenn Sie kein "nicht leeres" Trennzeichen haben.

Wenn die Datei/Daten ; am Ende der ersten Zeile hat, wird es die Lese in firstArray dort zu stoppen, und nie etwas in secondArray lesen - wie Sie nie die ; verbrauchen.

/* This will never be 1 as ; is blocking */ 
while((scanf("%d", &secondArray[i])) == 1) { 

Also: Wenn Sie mit d trennen ; Sie lesen müssen/Check für diese, bevor Sie in secondArray lesen.

Man könnte auch so etwas wie hinzufügen:

char c; 

/* this can be done more tidy, but only as concept */ 
while((scanf("%d", &firstArray[i])) == 1 && i < max) { 
    ++i; 
    if ((c = getchar()) == '\n' || c == ';') 
     break; 
} 

auch anstelle Array 0 durch Schleife initialisieren kann man sagen:

int firstArray[50] = {0}; /* This set every item to 0 */ 

auch zur Kenntnis nehmen Sie über Ihre 50 gehen nicht, um sicherzustellen, Grenze.

0

Tatsächlich gibt es einen besonderen Punkt in C-Arrays.

Obwohl Sie die Größe eines Arrays deklarieren. sagen int arr[5]; Sie können Werte über die Größe von speichern. Es zeigt keinen Fehler an, führt aber zu undefiniertem Verhalten (Überschreiben anderer Variablen).

Bitte beachten Sie diese Frage: Array size less than the no. of elements stored in it

In Ihrem Fall, das war das Problem. Der Compiler war nie über die ersten while-Anweisungen hinausgegangen. Sie haben also keine Ausgabe erhalten. Tatsächlich hat es noch nicht einmal den ganzen Code kompiliert!

while((scanf("%d", &firstArray[i]))== 1) { ++i; }

So konnten Sie diese while-Anweisung wie folgt schreiben:

while( scanf("%d", &firstArray[i]) ==1 && i<50) 
    i++; 

oder auch:

while(i<50) 
{ 
     scanf("%d", &firstArray[i]);    
     i++; 
} 

oder auch:

for (i=0; i<50; i++) 
    scanf("%d", &firstArray[i]); 
+0

Ihre Beispiele sind falsch. Sie vergleichen den Zeiger des Arrays mit '1'. Weiter erhöhen Sie "i", auch wenn keine Nummer gelesen wird. Und Ihr zweites und drittes Beispiel bricht nie, wenn die gelesenen Elemente "! = 1" sind. – Morpfh

+0

@Rune Sieh sie dir jetzt an! Eigentlich habe ich nur kopiert von dem, was er schrieb und vergessen, diese zu löschen. – Surya

+0

Besser, aber auf den zwei letzten Beispielen validieren Sie nicht lesen, und als Muster ändert sich nicht, wenn es etwas anderes als ein Leerzeichen (Leerzeichen, Tab, newline) Sie versuchen weiter zu lesen, kommen aber nie weiter. ZB wenn Sie 1 4 8 eingegeben haben; 3 6 5 Sie werden 1,4 und 8 in firstArray [0], [1] und [2] lesen - dann versuchen Sie, die nächste Zahl zu lesen, bis i 50 ist - aber als nächstes Zeichen ist ';' Sie werden nie voraus. – Morpfh

0

Sie stri sagen Zahlen von Ziffern und Sie lesen %d. Das Format scannt die Eingabe nach der längsten Sequenz, die einen ganzzahligen (signierten) Wert darstellt. Zwei "Ziffernfolgen" werden von der ersten While-Schleife verbraucht.

BEARBEITEN Anstelle von "Ziffernfolgen" sollten Sie "ganze Zahlenfolgen" sagen. In diesem Fall ist es ein wenig subtiler, da die erste while alle Ganzzahlen konsumieren kann, es sei denn, sie sind durch etwas getrennt, das eine mögliche ganze Zahl ist (z. B. ;).

Damit das Folgende funktioniert, müssen Sie die beiden "Zeilen" mit etwas trennen, das nicht als Ganzzahl und analysiert werden kann, was nicht als "weißes Zeichen" gilt. Nicht die bessere Lösung, sondern eine mögliche.

#include <stdio.h> 
#include <ctype.h> 

int main() 
{ 

    int firstArray[50] = {0}; 
    int secondArray[50] = {0}; 
    int i, j, l1, l2; 
    int tmp; 

    i = j = 0; 

    // read integers, but not more than size of array 
    while(scanf("%d", &firstArray[i]) == 1 && i < sizeof(firstArray)) { 
    ++i; 
    } 

    // consume non digits 
    for(tmp = getchar(); tmp != EOF && !isdigit(tmp); tmp = getchar()); 
    // on EOF you should exit and stop processing; 
    // we read one more char, push it back if it was a digit 
    if (isdigit(tmp)) ungetc(tmp, stdin); 

    while(scanf("%d", &secondArray[j]) == 1 && j < sizeof(secondArray)) { 
    ++j; 
    } 

    l1 = i; // preserve how many ints were read 
    l2 = j; 

/* Print this. */ 
    for(i = 0; i < l1; ++i) 
    { 
    printf("%d ", firstArray[i]); 
    } 
    putchar('\n'); 

    for(j=0; j < l2; ++j) 
    { 
    printf("%d ", secondArray[j]); 
    } 

    return 0; 
} 

EDIT Eine Lösung, die vielleicht Ihren Bedarf passt besser ist es, die Linien (eine pro Zeit) in einen Puffer und sscanf dem Puffer zu lesen.