Hoe maak ik een array van strings in C?

Ik probeer een array van strings in C te maken. Als ik deze code gebruik:

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

gcc geeft me “waarschuwing: toewijzing van incompatibel aanwijzertype”. Wat is de juiste manier om dit te doen?

edit: ik ben benieuwd waarom dit een compilerwaarschuwing zou moeten geven, want als ik printf(a[1]);doe, wordt “hmm” correct afgedrukt.


Antwoord 1, autoriteit 100%

Als je de snaren niet wilt veranderen, kun je dat gewoon doen

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

Als je het zo doet, zal je een array van twee pointers toewijzen aan const char. Deze verwijzingen worden dan ingesteld op de adressen van de statische strings "blah"en "hmm".

Als u de daadwerkelijke tekenreeksinhoud wilt kunnen wijzigen, moet u iets doen als

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

Hierdoor worden twee opeenvolgende arrays van elk 14 chars toegewezen, waarna de inhoud van de statische strings erin wordt gekopieerd.


Antwoord 2, autoriteit 81%

Er zijn verschillende manieren om een reeks tekenreeksen in C te maken. Als alle tekenreeksen dezelfde lengte hebben (of op zijn minst dezelfde maximale lengte hebben), declareert u eenvoudig een 2-d array van char en wijst u deze toe indien nodig:

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");

Je kunt ook een lijst met initializers toevoegen:

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

Hierbij wordt ervan uitgegaan dat de grootte en het aantal tekenreeksen in de initializer overeenkomen met de afmetingen van uw array. In dit geval wordt de inhoud van elke letterlijke tekenreeks (die zelf een op nul eindigende array van char is) gekopieerd naar het geheugen dat is toegewezen aan strs. Het probleem met deze benadering is de mogelijkheid van interne fragmentatie; als je 99 strings hebt die 5 karakters of minder zijn, maar 1 string die 20 karakters lang is, zullen 99 strings minstens 15 ongebruikte karakters hebben; dat is zonde van de ruimte.

In plaats van een 2-d array van char te gebruiken, kunt u een 1-d array van pointers naar char opslaan:

char *strs[NUMBER_OF_STRINGS];

Merk op dat je in dit geval alleen geheugen hebt toegewezen om de pointers naar de strings te houden; het geheugen voor de strings zelf moet ergens anders worden toegewezen (hetzij als statische arrays of door gebruik te maken van malloc()of calloc()). U kunt de initialisatielijst gebruiken zoals in het eerdere voorbeeld:

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

In plaats van de inhoud van de tekenreeksconstanten te kopiëren, slaat u eenvoudig de verwijzingen ernaar op. Merk op dat stringconstanten mogelijk niet schrijfbaar zijn; u kunt de aanwijzer opnieuw toewijzen, zoals:

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

Maar het kan zijn dat u de inhoud van de string niet kunt wijzigen; d.w.z.

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

mogelijk niet toegestaan.

Je kunt malloc()gebruiken om de buffer dynamisch toe te wijzen aan elke string en naar die buffer te kopiëren:

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

BTW,

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

Declareert a als een 2-element array van pointers naar 14-element arrays van char.


Antwoord 3, autoriteit 41%

Akkoord! Constante tekenreeksen:

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

Als ik het me goed herinner.

O, en je wilt strcpygebruiken voor toewijzing, niet de = operator. strcpy_sis veiliger, maar niet in C89 noch in C99-normen.

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

Update:Thomaszegt dat strlcpyde juiste keuze is.


Antwoord 4, autoriteit 7%

Hier zijn enkele van uw opties:

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

Het voordeel van a2is dat je dan het volgende kunt doen met letterlijke tekenreeksen

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

En voor a3kunt u het volgende doen:

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

Voor a1moet je strcpy()gebruiken (beter nog strncpy()), zelfs bij het toewijzen van letterlijke tekenreeksen. De reden is dat a2en a3arrays van pointers zijn en dat u hun elementen (dwz pointers) naar elke opslag kunt laten wijzen, terwijl a1is een array van ‘array of chars’ en dus is elk element een array die zijn eigen opslag ‘bezit’ (wat betekent dat het wordt vernietigd wanneer het buiten bereik gaat) – je kunt alleen dingen naar zijn opslag kopiëren.

Dit brengt ons ook in het nadeel van het gebruik van a2en a3– omdat ze verwijzen naar statische opslag (waar letterlijke tekenreeksen worden opgeslagen) waarvan de inhoud niet betrouwbaar kan worden gewijzigd (nl. ongedefinieerd gedrag), als u niet-tekenreeksliteralen wilt toewijzen aan de elementen van a2of a3– moet u eerst voldoende geheugen dynamisch toewijzen en vervolgens laat hun elementen naar dit geheugen wijzen en kopieer de karakters erin – en dan moet je er zeker van zijn dat je de toewijzing van het geheugen ongedaan maakt als je klaar bent.

Bah – ik mis C++ nu al 😉

ps. Laat het me weten als je voorbeelden nodig hebt.


Antwoord 5, autoriteit 5%

Of je kunt een struct-type declareren, dat een teken arry(1 string) bevat, ze creëren een array van de structs en dus een array met meerdere 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 
 }

Een van de voordelen hiervan ten opzichte van elke andere methode is dat u hiermee rechtstreeks in de tekenreeks kunt scannen zonder dat u strcpyhoeft te gebruiken;


Antwoord 6, autoriteit 4%

Als de strings statisch zijn, ben je het beste af met:

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

Hoewel het geen onderdeel is van de basis-ANSI C, is de kans groot dat uw omgeving de syntaxis ondersteunt. Deze strings zijn onveranderlijk (alleen-lezen) en gebruiken dus in veel omgevingen minder overhead dan het dynamisch bouwen van een stringarray.

Bijvoorbeeld in kleine microcontrollerprojecten gebruikt deze syntaxis programmageheugen in plaats van (meestal) kostbaarder ram-geheugen. AVR-C is een voorbeeldomgeving die deze syntaxis ondersteunt, maar dat geldt ook voor de meeste andere.


Antwoord 7, autoriteit 4%

Als u het aantal tekenreeksen in de array niet wilt bijhouden en ze wilt herhalen, voegt u aan het einde gewoon een NULL-tekenreeks toe:

char *strings[]={ "one", "two", "three", NULL };
int i=0;
while(strings[i]) {
  printf("%s\n", strings[i]);
  //do something
  i++;
};

Antwoord 8, autoriteit 4%

In ANSI C:

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

Antwoord 9, autoriteit 4%

De letterlijke tekenreeksen zijn const char *s.

En je gebruik van haakjes is vreemd. Je bedoelt waarschijnlijk

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

die een array van twee verwijzingen naar constante tekens declareert en ze initialiseert om naar twee hardgecodeerde tekenreeksconstanten te wijzen.


Antwoord 10

Uw code maakt een reeks functiewijzers aan. Probeer

char* a[size];

of

char a[size1][size2];

in plaats daarvan.

Bekijk wikibooks voor arraysen pointers


Antwoord 11

hallo, je kunt deze balg proberen:

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

een mooi voorbeeld van het gebruik van een array van strings in c als je dat wilt

#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;
}

Antwoord 12

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");
}

Probeer dit eens!!!


Antwoord 13

Ik miste op de een of andere manier een meer dynamische reeks tekenreeksen, waarbij het aantal tekenreeksen kon worden gevarieerd, afhankelijk van de runtime-selectie, maar anders zouden tekenreeksen moeten worden opgelost.

Ik heb het codefragment als volgt gecodeerd:

#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** evpikt de aanwijzer op naar array-strings, en count pikt het aantal strings op met de functie _countof. (Vergelijkbaar met sizeof(arr) / sizeof(arr[0])).

En er is extra Ansi-naar-unicode-conversie met behulp van de A2T-macro, maar dat kan in jouw geval optioneel zijn.


Antwoord 14

Een goede manier is om zelf een string te definiëren.

#include <stdio.h>
typedef char string[]
int main() {
    string test = "string";
    return 0;
}

Het is echt zo simpel.

Other episodes