2017-02-12 2 views
1

Sorry für meine Frage, ich weiß, es gibt viele Ähnlichkeiten, aber ich habe keine gefunden, die einfach sind, um mir zu helfen.Wie liest man Befehlszeilenargumente als Ganzzahlen anstelle von Strings?

Ich habe angefangen, in C zu codieren und versuche, eine einfache Übung zu lösen: Lies ein Integer-Array von der Kommandozeile, summiere die Elemente mit der Funktion array_sum und drucke das Ergebnis. (Eingabebeispiel Array von Elementen 3: 3 0 1 2)

int array_sum(int *array, size_t size); 
int main(int argc, char **argv){ 
    int sum=array_sum(argv, argc); 
    printf("array_sum: %i\n", sum); 
    return 0; 
} 

Mein Problem ist, dass ein argv char Array ist und die Funktion soll einen Integer-Array. Sollte ich Elemente einzeln in einem neuen int-Array konvertieren? Es gibt bessere Wege?

+2

'Soll ich Elemente einzeln in einem neuen int-Array konvertieren?' Ja. –

+0

@adev 3 0 1 2 ist eine Anordnung von vier Elementen, nicht wahr? –

+0

@VladfromMoscow das erste Element war die Länge des Arrays – adev

Antwort

4

argv ist ein Array von Zeigern auf C-Strings. Sie müssen zuerst die Zeichenfolgen in ganze Zahlen konvertieren. Sie können etwas tun:

int array_sum(int *array, size_t size); 
int main(int argc, char **argv){ 
    int *num_arr = malloc((argc - 1) * sizeof *num_arr); 

    for (int i = 0; i < argc - 1; ++i) 
     num_arr[i] = atoi(argv[i+1]); 

    int sum = array_sum(num_arr, argc - 1); 
    printf("array_sum: %i\n", sum); 

    free(num_arr); 
    return 0; 
} 

Der einzige Weg, den Code in main kürzer zu machen, ist durch die Umwandlung Schleife in eine separate Funktion zu bewegen, die den malloc ed Zeiger zurückgibt.

+0

Dank, es gibt keine Notwendigkeit, malloc zu verwenden, weil ich die Länge des Arrays kennen – adev

+1

@adev - Wenn Sie sich auf 'Argc' dann die Array-Länge ist variabel, und Sie sicherlich brauche 'malloc'. Obwohl Sie mit einem Array variabler Länge kommen können, wenn 'argc' nicht" zu groß "ist. – StoryTeller

+0

Der Aufruf von 'array_sum (argv, argc)' würde nicht kompiliert. Vermutlich hast du 'array_sum (num_arr, (size_t) argc-1)' gemeint. – Peter

0

Warum müssen Sie ein int Array als Argument an die Funktion übergeben? Keine Notwendigkeit, eine zusätzliche int Array erstellen, wenn Sie dies einfach tun:

int array_sum(char **argv, int argc){ 
    int sum = 0; 
    for(int i = 0;i < argc - 1;i++){ 
    sum += atoi(argv[i]) 
    } 
    return sum; 
} 
+0

Wahr, aber das ist nur dann sinnvoll, wenn die Anforderung, 'array_sum' zu verwenden, gelockert werden kann – StoryTeller

+0

ja @StoryTeller, ich muss die angegebene Funktion verwenden. Der Zweck der Übung denke ich ist die Schnittstelle – adev

0

Sie können atoi() Funktion verwenden char ** Array ** int zu konvertieren. Was ich hier sehe, ist jede Ganzzahl, die Sie in Zeichenfolge anstatt Char konvertieren.

2

In Ihrem Code ist char *argv[] ein Array von char* Zeigern, die über die Befehlszeile bereitgestellt werden. Um die gelieferten Nummern zu konvertieren, können Sie Folgendes verwenden:

  • atoi(), die String Argument in einen Integer-Typ konvertiert.
  • Oder strtol(), die den Anfangsteil einer Zeichenfolge in eine long int konvertiert, eine Basis gegeben.
  • Andere Sonderfunktionen von C99, von denen viele in dieser post beschrieben sind.
  • Da atoi() keine Fehlerprüfung hat, ist es am besten, strtol() zu verwenden, das umfangreiche Fehlerprüfung ermöglicht.

    Sie sollten diese konvertierten Zahlen in einem dynamisch zugeordneten int* Zeiger speichern, der auf dem Heap unter Verwendung von malloc() zugeordnet werden muss, was von @StoryTeller in seiner Antwort vorgeschlagen wurde. Sie können auch einfach ein Array auf dem Stack deklarieren, z. B. int arr[n]. Das Problem tritt auf, wenn Sie dieses Array in einer Funktion zurückgeben wollen, was nicht möglich ist. Die Verwendung eines Zeigers würde in diesem Fall mehr Flexibilität für die Abstraktion ermöglichen.

    malloc() ordnet Speicherblock auf der Halde, und gibt einen Zeiger darauf void*.

    Hinweis:malloc() sollte immer geprüft werden, da es NULL zurückkehren kann. Sie müssen auch diesen Zeiger am Ende free(). Hier

    ist einige Beispiel-Code:

    #include <stdio.h> 
    #include <stdlib.h> 
    
    #define BASE 10 
    
    /* Guessed that your function would look like this */ 
    int array_sum(int *array, size_t size) { 
        int sum = 0; 
    
        for (size_t i = 0; i < size; i++) { 
         sum += array[i]; 
        } 
    
        return sum; 
    } 
    
    int main(int argc, char *argv[]) { 
        int *arr = NULL; 
        char *endptr = NULL; 
        int check, sum; 
        size_t ndigits = (size_t)argc-1; 
    
        /* allocate pointer */ 
        arr = malloc(ndigits * sizeof *arr); 
        if (arr == NULL) { 
         fprintf(stderr, "Cannot %zu spaces for integers\n", ndigits); 
         exit(EXIT_FAILURE); 
        } 
    
        for (size_t i = 0; i < ndigits; i++) { 
    
         /* sufficient checking for strtol(), more can possibly be added here */ 
         check = strtol(argv[i+1], &endptr, BASE); 
         if (endptr != argv[i+1] && *endptr == '\0') { 
          arr[i] = check; 
         } 
        } 
    
        sum = array_sum(arr, ndigits); 
    
        printf("array_sum: %d\n", sum); 
    
        /* pointer is free'd */ 
        free(arr); 
        arr = NULL; 
    
        return 0; 
    } 
    

    Beispiel Eingabe:

    $ gcc -Wall -Wextra -std=c99 -o sumcommands sumcommmands.c 
    $ ./sumcommands 3 2 1 
    

    Ausgang:

    array_sum: 6 
    

    Hinweis: können Sie mehr Fehler verwenden Überprüfung auf strtol() auf die Man page.

    +0

    Dank für die Erklärung :) – adev

    Verwandte Themen