C returne char[][] („String“-Array)

OP #7115054
Hallo,
ich hatte nach langer Zeit mal wieder Lust auf C und ich diesmal dabei, 
eine Headerdatei zu schreiben, die ich in zukünftige Projekte einbauen 
kann, um es einfacher zu haben. Ich will einige Funktionen haben, die 
ich aus dem .NET-Framework kenne, und die es einem einfacher machen.

Mein derzeitiges Problem besteht darin, dass ich in der Headerdatei eine 
Funktion split() habe, die einen String (ja, ich weiß, es gibt in C 
keine Strings per se) anhand von einem Trennzeichen aufsplittet. Ich 
möchte, dass die Funktion mir ein zweidimensionales Char-Array 
zurückgibt (also ein „String-Array“). Bei der Rückgabe habe ich 
Schwierigkeiten.
Ich habe heute schon Einiges probiert:

https://stackoverflow.com/questions/36535898/pass-a-struct-to-a-function

https://stackoverflow.com/questions/4085372/how-to-return-a-string-array-from-a-function

https://www.quora.com/How-do-you-create-a-function-that-returns-an-array-of-strings-in-C


Wenn ich die Quellcodes kopiere, gibt es entweder Compilerfehler, oder 
ich kann den zurückgegebenen **Pointer nicht auslesen.

Ich kompiliere das Projekt in x64. Ich schreibe das Programm in Visual 
Studio 2019 CE. Es ist ein C++-Konsolenprojekt, allerdings habe ich 
eingestellt, dass nur als C-Code kompiliert wird.
1
char StringToSplit[] = { "This is - www.tutorialspoint.com - website" };
2
char deli[2] = "-";
3
char *Test = split(StringToSplit, deli);
–––
1
char* split(char* StringToSplit, char* delimiters)
2
{
3
    static char temp[10][20]={'\0'};
4
    int i = 0;
5
    char* token;
6
    /* have a look first */
7
    token = strtok(StringToSplit, delimiters);
8
    /* walk through tokens */
9
    while (token != NULL)
10
    {
11
        strcpy(temp[i], token);
12
        i++;
13
        printf(" %s\n", token);
14
        token = strtok(NULL, delimiters);
15
    }
16
    return *temp;
17
}
Gast #7115101
Ich habe schon seit Jahren keine Lust mehr auf die char * Rechnerei.
Ich nehme nur noch std::string. Und wenn ich Vektoren davon brauche, 
dann noch mal std::vector davon.
Die Probleme mit char * (Nullptr Zugriff, zeigen ins Nirvana ...) sind 
drastisch gesunken.
Wenn du C++ hast, verwende es einfach. Das hätte dir den Post hier 
erspart.
#7115137
die Antwort steht doch schon im 2. Stackoverflow Link. Das statisch 
angelegte Array ist ein zweidimensionales Feld von char, und nicht ein 
Array von Zeigern. Genau das brauchst du aber und das muss dann 
dynamisch angelegt werden.
1
#include <stdio.h>
2
#include <string.h>
3
#include <stdlib.h>
4

5
char** split(char* StringToSplit, char* delimiters)
6
{
7
    //static char temp[10][20]={'\0'};
8
    int i = 0;
9
    char* token;
10

11
    // allocate string memory
12
    char ** temp = malloc(10 * sizeof(char*));
13
    for (int i =0 ; i < 10; ++i) {
14
        temp[i] = malloc(20 * sizeof(char));
15
        temp[i][0] = 0;
16
    }
17
    
18
    /* have a look first */
19
    token = strtok(StringToSplit, delimiters);
20
    /* walk through tokens */
21
    while (token != NULL)
22
    {
23
        strcpy(temp[i], token);
24
        printf("%d:  %s\n", i, token);
25
        i++;
26
        token = strtok(NULL, delimiters);
27
    }
28

29
    return temp;
30
}
31

32

33
int main()
34
{
35
    char StringToSplit[] = { "This is - www.tutorialspoint.com - website" };
36
    char deli[2] = "-";
37
    char **Test = split(StringToSplit, deli);
38
    
39
    printf("Test: %s\n", Test[0]);
40
    printf("Test: %s\n", Test[1]);
41
    printf("Test: %s\n", Test[2]);
42
    printf("Test: %s\n", Test[3]);
43

44
    return 0;
45
}

kann man auch schön in https://www.onlinegdb.com/ testen.
Der code ist allerdings übel mit so fixen Längen, ich bevorzuge auch 
Stringklassen.
Oder nur ein Array mit Zeigern auf die Teilstrings füllen, ohne die 
Strings nochmal zu kopieren.
Gast #7115147
Bartosz B. schrieb:

> ich hatte nach langer Zeit mal wieder Lust auf C

Du bist wohl eine kleiner Masochist? Lust auf C? Das benutzt man, wenn's 
partout nicht anders geht oder der Aufwand ohne die Verwendung von C 
extrem wachsen würde. Sonst niemals.

> und ich diesmal dabei,
> eine Headerdatei zu schreiben, die ich in zukünftige Projekte einbauen
> kann, um es einfacher zu haben. Ich will einige Funktionen haben, die
> ich aus dem .NET-Framework kenne, und die es einem einfacher machen.

Tja, es ist wirklich nicht leicht, den Luxus echter Hochsprachen in 
einen aufgedonnerten Macro-Assembler zu übertragen. Ich wünsche noch 
viel "Spaß" dabei...
OP #7115202
@J. S. Vielen Dank! Habs nur nochmal mit anderen Worten gebraucht. Ich 
übergebe des Weiteren nun "by reference" einen Integer, welcher in der 
split-Funktion beschrieben wird. So weiß ich, wenn split geendet hat, 
wie viele Teilstrings es gibt, und kann mit 'ner for-Schleife die 
Teilstrings drucken.

Und free nicht vergessen :)
Gast #7116526
Wieso nutzt man nicht den eigentlichen String weiter und übergibt direkt 
die Pointer?
1
    while (token != NULL)
2
    {
3
        temp[i++] = token;
4
        token = strtok(NULL, delimiters);
5
    }

somit arbeitet man nur mit dem String und Pointern, strtok ersetzt sogar 
den Delimiter durch ein '\0'..  da braucht man dann auch nix kopieren.
Gast #7117025
Rolf M. schrieb:
> C mit Assembler verwechselt?

Nö. Da gibt es fast nix zu verwechseln... bis auf den Umstand, daß man 
beim Assembler genau das kriegt, was man geschrieben hat (und nicht, was 
man gemeint hat) während man bei C das kriegt, was der Compiler meint, 
daß man es gemeint haben könnte. Mahlzeit.

W.S.
Gast #7117040
W.S. schrieb:
> . Da gibt es fast nix zu verwechseln... bis auf den Umstand, daß man
> beim Assembler genau das kriegt, was man geschrieben hat (und nicht, was
> man gemeint hat) während man bei C das kriegt, was der Compiler meint,
> daß man es gemeint haben könnte. Mahlzeit

Ah, deshalb kommt von dir so grauenhaft lesbarer C Coder immer mal 
wieder. Bisher dachte ich immer, das seit 80er Pascal Style auf 2010er 
Hardware in C angewendet.

Nimm das bitte nicht all zu Ernst, das ist ein Witz. Ich bin aber glaube 
nicht der Einzige, dem das in Sinn kam ;)
Gast #7117269
Ach so, das ist es also, was die "Lernbetty" so unerträglich macht -- 
dieser üble Leichengeruch nach Pascal, der tötesten aller Leersprachen.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 4 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.