it-swarm.com.de

Wie erstelle ich ein Array von Strings in C?

Ich versuche, ein Array von Strings in C zu erstellen. Wenn ich diesen Code verwende:

char (*a[2])[14];
a[0]="blah";
a[1]="hmm";

gcc gibt mir "Warnung: Zuweisung von inkompatiblem Zeigertyp". Was ist der richtige Weg, dies zu tun?

edit: Ich bin neugierig, warum dies eine Compiler-Warnung geben sollte, denn wenn ich printf(a[1]); mache, wird "hmm" korrekt gedruckt.

221
Charles

Wenn Sie die Zeichenfolgen nicht ändern möchten, können Sie dies einfach tun

const char *a[2];
a[0] = "blah";
a[1] = "hmm";

Wenn Sie es so machen, weisen Sie const char ein Array mit zwei Zeigern zu. Diese Zeiger werden dann auf die Adressen der statischen Zeichenfolgen "blah" und "hmm" gesetzt.

Wenn Sie den eigentlichen String-Inhalt ändern möchten, müssen Sie etwas tun

char a[2][14];
strcpy(a[0], "blah");
strcpy(a[1], "hmm");

Dadurch werden zwei aufeinanderfolgende Arrays von jeweils 14 chars zugewiesen, wonach der Inhalt der statischen Zeichenfolgen in sie kopiert wird.

199
Mikael Auno

Es gibt mehrere Möglichkeiten, ein Array von Strings in C zu erstellen. Wenn alle Strings die gleiche Länge haben (oder zumindest die gleiche maximale Länge haben), deklarieren Sie einfach ein 2-d-Array von char und weisen Sie es nach Bedarf zu:

char strs[NUMBER_OF_STRINGS][STRING_LENGTH+1];
...
strcpy(strs[0], aString); // where aString is either an array or pointer to char
strcpy(strs[1], "foo");

Sie können auch eine Liste von Initialisierern hinzufügen:

char strs[NUMBER_OF_STRINGS][STRING_LENGTH+1] = {"foo", "bar", "bletch", ...};

Dies setzt voraus, dass die Größe und Anzahl der Zeichenfolgen im Initialisierer mit den Array-Abmessungen übereinstimmen. In diesem Fall wird der Inhalt jedes String-Literal (das selbst ein nullterminiertes Array von char ist) in den Speicher kopiert, der strs zugeordnet ist. Das Problem bei diesem Ansatz ist die Möglichkeit einer internen Fragmentierung. Wenn Sie 99 Zeichenfolgen mit 5 oder weniger Zeichen, aber eine Zeichenfolge mit 20 Zeichen haben, werden 99 Zeichenfolgen mindestens 15 nicht verwendete Zeichen enthalten. das ist Platzverschwendung.

Anstelle eines 2-D-Arrays von Char können Sie ein 1-D-Array von Zeigern in Char speichern:

char *strs[NUMBER_OF_STRINGS];

Beachten Sie, dass Sie in diesem Fall nur Speicher für die Zeiger auf die Zeichenfolgen zugewiesen haben. Der Speicher für die Zeichenfolgen selbst muss an anderer Stelle zugewiesen werden (entweder als statische Arrays oder mithilfe von malloc () oder calloc ()). Sie können die Initialisierungsliste wie im vorherigen Beispiel verwenden:

char *strs[NUMBER_OF_STRINGS] = {"foo", "bar", "bletch", ...};

Anstatt den Inhalt der String-Konstanten zu kopieren, speichern Sie einfach die Zeiger darauf. Beachten Sie, dass String-Konstanten möglicherweise nicht schreibbar sind. Sie können den Zeiger wie folgt neu zuordnen:

strs[i] = "bar";
strs[i] = "foo"; 

Sie können den Inhalt der Zeichenfolge jedoch möglicherweise nicht ändern. d.h.

strs[i] = "bar";
strcpy(strs[i], "foo");

darf nicht erlaubt sein. 

Sie können malloc () verwenden, um den Puffer für jeden String dynamisch zuzuweisen und in diesen Puffer zu kopieren:

strs[i] = malloc(strlen("foo") + 1);
strcpy(strs[i], "foo");

BTW, 

char (*a[2])[14];

Deklariert a als 2-Element-Array von Zeigern auf 14-Element-Arrays von char. 

153
John Bode

Ack! Konstante Zeichenfolgen:

const char *strings[] = {"one","two","three"};

Wenn ich mich richtig erinnere.

Oh, und Sie wollen strcpy für die Zuweisung verwenden, nicht den Operator =. strcpy_s ist sicherer, aber weder in C89 noch in C99-Standards.

char arr[MAX_NUMBER_STRINGS][MAX_STRING_SIZE]; 
strcpy(arr[0], "blah");

Update:Thomas sagt, strlcpy ist der richtige Weg.

79
mpen

Hier sind einige Ihrer Möglichkeiten:

char a1[][14] = { "blah", "hmm" };
char* a2[] = { "blah", "hmm" };
char (*a3[])[] = { &"blah", &"hmm" };  // only since you brought up the syntax -

printf(a1[0]); // prints blah
printf(a2[0]); // prints blah
printf(*a3[0]); // prints blah

Der Vorteil von a2 ist, dass Sie mit String-Literalen Folgendes tun können

a2[0] = "hmm";
a2[1] = "blah";

Und für a3 können Sie Folgendes tun:

a3[0] = &"hmm";
a3[1] = &"blah";

Für a1 müssen Sie auch bei der Zuweisung von String-Literalen strcpy verwenden. Der Grund ist, dass a2 und a3 Arrays von Zeigern sind, und Sie können ihre Elemente (dh Zeiger) auf jeden Speicher zeigen lassen, während a1 ein Array von "Arrays von Zeichen" ist und jedes Element ein Array ist, das seine "besitzt" eigener Speicher (was bedeutet, dass er zerstört wird, wenn er nicht mehr verwendet wird) - Sie können nur Inhalte in den Speicher kopieren.

Dies bringt uns auch den Nachteil der Verwendung von a2 und a3 mit sich, da sie auf statische Speicherung (String-Literale) hinweisen, deren Inhalt nicht zuverlässig geändert werden kann (dh undefiniertes Verhalten), wenn Sie Nicht-String-Literale zuweisen möchten Zu den Elementen von a2 oder a3 müssen Sie zuerst ausreichend Speicherplatz dynamisch zuweisen und dann auf diese Speicherelemente zeigen und dann die Zeichen in diesen Speicher kopieren. Anschließend müssen Sie sicherstellen, dass der Speicher freigegeben wird.

Bah - ich vermisse C++ schon;)

p.s. Lassen Sie mich wissen, wenn Sie Beispiele brauchen.

11
Faisal Vali

In ANSI C:

char* strings[3];
strings[0] = "foo";
strings[1] = "bar";
strings[2] = "baz";
10
Noldorin

Oder Sie können einen Strukturtyp deklarieren, der eine Zeichenkette (1 String) enthält. Sie erstellen ein Array der Strukturen und somit ein Array mit mehreren Elementen

typedef struct name
{
   char name[100]; // 100 character array
}name;

main()
{
   name yourString[10]; // 10 strings
   printf("Enter something\n:);
   scanf("%s",yourString[0].name);
   scanf("%s",yourString[1].name);
   // maybe put a for loop and a few print ststements to simplify code
   // this is just for example 
 }

Ein Vorteil gegenüber allen anderen Methoden besteht darin, dass Sie direkt in den String scannen können, ohne strcpy verwenden zu müssen.

10
FutureSci

Wenn Sie nicht die Anzahl der Strings im Array verfolgen und über sie iterieren möchten, fügen Sie am Ende einfach NULL-String hinzu:

char *strings[]={ "one", "two", "three", NULL };

int i=0;
while(strings[i]) {
  printf("%s\n", strings[i]);
  //do something
  i++;
};
9
Sergey

Die String-Literale sind const char *s.

Und Ihre Verwendung von Klammern ist seltsam. Du meinst wahrscheinlich

const char *a[2] = {"blah", "hmm"};

dies deklariert ein Array aus zwei Zeigern auf konstante Zeichen und initialisiert es so, dass es auf zwei hartcodierte String-Konstanten zeigt.

8
dmckee

Wenn die Zeichenfolgen statisch sind, sind Sie am besten mit:

const char *my_array[] = {"eenie","meenie","miney"};

Sie gehört zwar nicht zum Basis-ANSI-C, die Umgebung wird jedoch wahrscheinlich von der Syntax unterstützt. Diese Zeichenfolgen sind unveränderlich (schreibgeschützt) und beanspruchen daher in vielen Umgebungen weniger Aufwand als das dynamische Erstellen eines Zeichenfolgenarrays. 

In kleinen Mikrocontrollerprojekten verwendet diese Syntax beispielsweise Programmspeicher anstelle von (normalerweise) wertvoller RAM-Speicher. AVR-C ist eine Beispielumgebung, die diese Syntax unterstützt, die meisten anderen jedoch auch.

8
Bryce

Ihr Code erstellt ein Array von Funktionszeigern. Versuchen

char* a[size];

oder

char a[size1][size2];

stattdessen.

Siehe Wikibooks zu Arrays und Zeigern

3
Dario

hallo, du kannst es unten versuchen: 

 char arr[nb_of_string][max_string_length]; 
 strcpy(arr[0], "Word");

ein schönes Beispiel für ein Array von Strings in c, wenn Sie möchten

#include <stdio.h>
#include <string.h>


int main(int argc, char *argv[]){

int i, j, k;

// to set you array
//const arr[nb_of_string][max_string_length]
char array[3][100];

char temp[100];
char Word[100];

for (i = 0; i < 3; i++){
    printf("type Word %d : ",i+1);
    scanf("%s", Word);
    strcpy(array[i], Word);
}

for (k=0; k<3-1; k++){
    for (i=0; i<3-1; i++)
    {
        for (j=0; j<strlen(array[i]); j++)
        {
            // if a letter ascii code is bigger we swap values
            if (array[i][j] > array[i+1][j])
            {
                strcpy(temp, array[i+1]);
                strcpy(array[i+1], array[i]);
                strcpy(array[i], temp);

                j = 999;
            }

            // if a letter ascii code is smaller we stop
            if (array[i][j] < array[i+1][j])
            {
                    j = 999;
            }

        }
    }
}

for (i=0; i<3; i++)
{
    printf("%s\n",array[i]);
}

return 0;
}
1
Aominé

Mir fehlte irgendwie ein dynamischeres Array von Strings, bei dem die Anzahl der Strings je nach Laufzeitauswahl variiert werden konnte, ansonsten sollten Strings jedoch fixiert werden.

Ich bin am Ende des Codierungs-Codeausschnitts wie folgt gelandet:

#define INIT_STRING_ARRAY(...)          \
    {                                   \
        char* args[] = __VA_ARGS__;     \
        ev = args;                      \
        count = _countof(args);         \
    }

void InitEnumIfAny(String& key, CMFCPropertyGridProperty* item)
{
    USES_CONVERSION;
    char** ev = nullptr;
    int count = 0;

    if( key.Compare("horizontal_alignment") )
        INIT_STRING_ARRAY( { "top", "bottom" } )

    if (key.Compare("boolean"))
        INIT_STRING_ARRAY( { "yes", "no" } )

    if( ev == nullptr )
        return;

    for( int i = 0; i < count; i++)
        item->AddOption(A2T(ev[i]));

    item->AllowEdit(FALSE);
}

char** ev nimmt den Zeiger auf Array-Zeichenfolgen und count erfasst die Anzahl der Zeichenfolgen mithilfe der _countof-Funktion. (Ähnlich wie sizeof(arr) / sizeof(arr[0])).

Außerdem gibt es eine zusätzliche Konvertierung von Ansi in Unicode mithilfe von A2T macro, dies kann jedoch für Ihren Fall optional sein.

0
TarmoPikaro
char name[10][10]
int i,j,n;//here "n" is number of enteries
printf("\nEnter size of array = ");
scanf("%d",&n);
for(i=0;i<n;i++)
{
    for(j=0;j<1;j++)
    {
        printf("\nEnter name = ");
        scanf("%s",&name[i]);
    }
}
//printing the data
for(i=0;i<n;i++)
{
    for(j=0;j<1;j++)
    {
        printf("%d\t|\t%s\t|\t%s",rollno[i][j],name[i],sex[i]);
    }
    printf("\n");
}

Hier versuchen Sie es !!!

0
Aditya