Strings in dynamisches array schreiben...



  • Hallo

    Ich möchte eigentlich etwas relativ simples, scheitere aber schon bei Arrayfunktionen.

    Also, man ruft das Programm auf und kann Parameter übergeben (muss mind. 1 sein)
    In einer Funktion validateArguments möchte ich nun überprüfen welche Argumente übergeben wurden, ob diese stimmen und diese als String-Array im Format {option1, value1, option2, value2, ...} zurückgeben.

    Hier der Code:

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <time.h>
    
    char * validateArguments(int argc, const char * argv[])
    {
    	char *returnarray = 0;
    	int i, j;
    
    	// Keine Parameter angegeben?
    	if (argc < 2) return;
    
    	// argc = parameteranzahl (erster parameter immer programmpfad) daher -1
    	// Rückgabeformat: {option, value} für jeden parameter daher x2
    	returnarray = (char *) malloc((argc - 1) * 2);
    	for (i=0; i<((argc - 1) * 2); i++)
    	{
    		returnarray[i] = (char *) malloc(sizeof(char) * 32);
    	}
    
    	j = 0;
    	for (i=1; i<argc; i++)
    	{
    		if (strcmp(argv[i],"-o") == 1 && argc > i)
    		{
    			returnarray[j] = "output";
    			returnarray[j+1] = (char *)argv[i+1];
    			j+=2;
    			i++;
    		}
    		else if (strcmp(argv[i],"-O") == 1 && argc > i)
    		{
    			returnarray[j] = "optimize";
    			returnarray[j+1] = argv[i+1];
    			j+=2;
    			i++;
    		}
    		else
    		{
    			printf("Parameter %d is invalid! Check usage for correct syntax.\n", j+1);
    			printUsage();
    			exit(1);
    		}
    	}
    	return returnarray;
    }
    
    int main (int argc, const char * argv[])
    {
    	char *appArguments = validateArguments(argc, argv);
    
    	int i;
    	int s = (sizeof appArguments)/(sizeof appArguments[0]);
    	for (i=0; i<s; i++)
    	{
    		printf("Argument %d is: %s\n");
    	}
    }
    

    Dieser Teil:

    // argc = parameteranzahl (erster parameter immer programmpfad) daher -1
    	// Rückgabeformat: {option, value} für jeden parameter daher x2
    	returnarray = (char *) malloc((argc - 1) * 2);
    	for (i=0; i<((argc - 1) * 2); i++)
    	{
    		returnarray[i] = (char *) malloc(sizeof(char) * 32);
    	}
    

    war ursprünglich mal:

    returnarray = (char *) malloc((argc - 1) * 2 * sizeof(char));
    

    Hat aber das selbe Problem ausgeworfen.

    Der Compiler (Nutze MinGW) gibt das zurück:

    test.c: In function 'validateArguments':
    test.c:23:18: warning: assignment makes integer from pointer without a cast
    test.c:32:19: warning: assignment makes integer from pointer without a cast
    test.c:33:21: warning: assignment makes integer from pointer without a cast
    test.c:39:19: warning: assignment makes integer from pointer without a cast
    test.c:40:21: warning: assignment makes integer from pointer without a cast
    C:\Users\****\AppData\Local\Temp\cciEPVzt.o:bfc.c:(.text+0x125): undefined reference to `printUsage'
    collect2: ld returned 1 exit status
    

    Das mit der fehlenden Funktion printUsage ist mir klar, soweit bin ich noch nicht, ich will erstmal rauskriegen was dieses "assignment makes integer from pointer without a cast" soll. Habe zwar über Google schon einiges gefunden, doch so recht verstehe ich nicht wo der Fehler liegt. Die Datentypen müssten doch stimmen und was z.B. an Zeile 32 falsch sein soll kann ich nicht verstehn. Ein Pointer bei einer Direkten Stringeingabe? huh?

    PS: Zeilenangaben stimmen mit den Fehlermeldungen überein.



  • Kurz: Die Datentypen stimmen nicht.

    returnarray[i] ist ein char und dem willst du ein Zeiger (char 😉 bzw. "output" zuweisen.



  • OK nach endlos langem brute-force ausprobieren sämtlicher pointer-cast-type kombinationen kam das hier ohne Beschwerden aus dem Compiler:

    int * testarray;
    	testarray = (int *) calloc(3, sizeof(int));
    	testarray[0] = (int) "string foo";
    
    	printf("%s, %d\n",testarray[0], sizeof(testarray[0]));
    

    Ist das so okay oder ist das eher murks? Eigentlich will ich ja nur ein ganz simples stringarray... Mich irritiert dass alles als integer gecastet sein muss.
    Warum muss sogar der "string foo" als integer konvertiert werden? Das macht doch garkeinen Sinn... Oder?



  • Ein char** würde einem string-array entsprechen, was du da treibst ist Schwachsinn.



  • Ganz, ganz großer Murks!

    So was sollte man durch überlegen lösen.

    Kein Wunder das der Compiler nicht mehr meckert. Mit dem ganzen gecaste sagst du dem Compiler "Ich weiß was ich tue." - Stimmt leider nicht. 😮

    _dp schrieb:

    testarray[0] = (int) "string foo";
    

    testarry ist ein Zeiger auf char, daraus folgt:
    testarray[0] ist ein char.
    "string foo" ist ein Zeiger auf char (Stringliteral)

    Du merkst selber was da hakt?

    Du willst ein string array, nimmst aber immer char arrays.
    Du brauchst das, was wie argv ist: Ein Array mit Zeigern auf char.
    Dann musst du aber für jedes char array den Speicher mit malloc besorgen.



  • const char ** validateArguments(int argc, const char * argv[])
    {
        const char **ra = calloc(1,sizeof*argv);
        int i=1;
        while( argc-- )
            if (!strcmp(*argv,"-o") )
            {
              ra=realloc(ra,(i+=2)*sizeof*ra);
              ra[i-3] = "output";
              ra[i-2] = *++argv;
              ra[i-1] = 0;
            }
            else if (!strcmp(*argv,"-O") )
            {
              ra=realloc(ra,(i+=2)*sizeof*ra);
              ra[i-3] = "optimize";
              ra[i-2] = *++argv;
              ra[i-1] = 0;
            }
            else
            {
              ++argv;
                /*printUsage();
                exit(1);*/
            }
        return ra;
    }
    
    int main()
    {
      const char *op[] = {"-foo","-o","minuso","bar","-O","minusO"},
      **test = validateArguments(sizeof op/sizeof*op,op);
    
      while( *test ) puts(*test++);
    
      return 0;
    }
    

    Du musst dir auch Gedanken machen, wie du die Größe deines Returnarrays im Aufrufkontext bestimmen kannst, hier beispielhaft NULL am Ende.



  • _dp schrieb:

    // argc = parameteranzahl (erster parameter immer programmpfad) daher -1
    

    Stimmt nicht, ist undefiniert.



  • Hi

    Danke für die vielen Posts, schaut aus als könnt ich da noch ne Menge lernen.

    Eine kleine Frage dazu:
    Wann benutze ich ** und wann * ?


Anmelden zum Antworten