Создайте строковый массив с символами в C - PullRequest
2 голосов
/ 28 сентября 2011

Когда я делаю это

char *paths[10];
paths[0] = "123456";

printf(1,"%s\n",paths[0]);
printf(1,"%c\n",paths[0][2]);

Выход:

123456
3

Но когда я тебе это сделаю

char *paths[10];
paths[0][0]='1';
paths[0][1]='2';
paths[0][2]='3';
paths[0][3]='4';
paths[0][4]='5';
paths[0][5]='6';
printf(1,"%s\n",paths[0]);
printf(1,"%c\n",paths[0][2]);

Выход:

(null)
3

Почему в этом случае он равен нулю?
Как создать массив строк, используя символы в C? Я немного новичок в C и испытываю некоторые трудности в программировании на C

Ответы [ 5 ]

4 голосов
/ 28 сентября 2011

У вас есть много вариантов, предоставленных различными ответами, я просто добавляю несколько пунктов.Вы можете создать массив строк следующим образом:
I. Вы можете создать массив строк только для чтения следующим образом:

char *string_array0[] = {"Hello", "World", "!" };

Это создаст массив из 3 только для чтения строки.Вы не можете изменить символы строки в этом случае, т.е. string_array0[0][0]='R'; является недопустимым .
II.Вы можете объявить массив указателей и использовать их по мере необходимости.

char *string_array1[2]; /* Array of pointers */
string_array1[0] = "Hey there"; /* This creates a read-only string */
/* string_array1[0][0] = 'R';*/ /* This is illegal, don't do this */
string_array1[1] = malloc(3); /* Allocate memory for 2 character string + 1 NULL char*/
if(NULL == string_array1[1])
{
/* Handle memory allocation failure*/
}

string_array1[1][0] = 'H';
string_array1[1][1] = 'i';
string_array1[1][2] = '\0'; /* This is important. You can use 0 or NULL as well*/
...
/* Use string_array1*/
...
free(string_array1[1]); /* Don't forget to free memory after usage */

III.Вы можете объявить двумерный массив символов.

char string_array2[2][4]; /* 2 strings of atmost 3 characters can be stored */
string_array2[0][0] = 'O';
string_array2[0][1] = 'l';
string_array2[0][2] = 'a';
string_array2[0][3] = '\0';

string_array2[1][0] = 'H';
string_array2[1][1] = 'i';
string_array2[1][2] = '\0'; /* NUL terminated, thus string of length of 2 */  

IV.Вы можете использовать указатель на указатель.

char ** string_array3; 
int i;
string_array3 = malloc(2*sizeof(char*)); /* 2 strings */
if(NULL == string_array3)
{
        /* Memory allocation failure handling*/
}

for( i = 0; i < 2; i++ )
{
    string_array3[i] = malloc(3); /* String can hold at most 2 characters */
    if(NULL == string_array3[i])
    {
        /* Memory allocation failure handling*/
    }
}

strcpy(string_array3[0], "Hi");

string_array3[1][0]='I';
string_array3[1][1]='T';
string_array3[1][2]='\0';

/*Use string_array3*/

for( i = 0; i < 2; i++ )
{
    free(string_array3[i]);
}

free(string_array3);

Следует помнить:

  • Если вы создаете строку только для чтения, вы не можете изменить символ в строке.

  • Если вы заполняете массив символов, убедитесь, что у вас есть память для размещения символа NUL и убедитесь, что вы заканчиваете свои строковые данные символом NUL.

  • Если вы используете указатели и выделяете память, убедитесь, что вы проверили, правильно ли выделено память, и освободите память после использования.
  • Используйте строковые функции из string.h для манипуляции со строками.

Надеюсь, это поможет!
PS: printf(1,"%s\n",paths[0]); выглядит теневым

2 голосов
/ 28 сентября 2011
char *paths[10];
paths[0][0]='1';

paths - это массив указателей. paths ни к чему не инициализируется. Таким образом, он имеет значения мусора. Вы должны использовать выделение памяти, используя malloc. Вам просто не повезло, что эта программа на самом деле работала тихо. Подумайте, какое местоположение адреса paths[0][0] даст для присвоения 1 .

С другой стороны, это сработало, потому что -

char *paths[10];
paths[0] = "123456";

"123456" - строковый литерал, расположенный в месте только для чтения. Таким образом, он возвращает начальный адрес того местоположения, которое содержит paths[0]. Чтобы правильно объявить -

const char* paths[10];
2 голосов
/ 28 сентября 2011

paths - это массив из 10 указателей на char. Однако начальные элементы - это указатели, которые не могут быть разыменованы. Это либо wild (для массива в функции), либо NULL для статического массива. Дикий указатель является неинициализированным.

Я бы предположил, что у вас статичный, поскольку paths[0] это NULL. Однако это может быть совпадением.

Когда вы разыменовываете NULL или неинициализированный указатель, вы читаете или записываете в память, которой вы не владеете. Это вызывает неопределенное поведение, которое может включать в себя сбой вашей программы.

Тебе действительно повезло, что он не разбился. Вероятно, это связано с тем, что компилятор видит, что вы записываете константу в paths[0][2], и меняет printf для прямой печати константы. Вы можете не полагаться на это.

Если вы хотите иметь указатель, на который вам разрешено писать, выполните:

paths[0] = malloc(string_length + 1);

string_length - количество символов, которое вы можете написать. 1 дает вам место для NUL. Когда вы закончите, вы должны free это.

1 голос
/ 28 сентября 2011

Для вашего второго примера, если вы знаете размер каждой строки, вы можете написать, например,

char paths[10][6];
paths[0][0]='1';

...

paths[0][5]='6';

Таким образом, у вас есть 10 строк длиной 6 (и до сих пор используется только первая строка).

0 голосов
/ 25 мая 2014

Вы можете определить строку самостоятельно, сразу после

#inlcude <stdio.h>

как это

typedef char string[];

и в основном вы можете сделать это

string paths = "123456";
printf("%s\n", paths);
return 0;

чтобы ваш код выглядел следующим образом

#include <stdio.h>
typedef char string[];

int main() {
    string paths = "123456";
    printf("%s", paths);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...