2014-01-04 3 views
1

Мне нужно сделать некоторые манипуляции с строкой (например, добавлять буквы в определенные места). Я не знаю, каков будет его размер, это зависит от ввода.Строка произвольной длины в C

Как определить строку без указания ее размера? Я хочу, чтобы он адаптировался к любому содержимому, которое я вложил внутрь.

И почему я не могу просто передать пустой char * методу? Компилятор этого не допускает.

Согласно ответам, я понимаю, что я не могу создать строку неограниченного размера. Но, например, когда я попытался создать char arr[100], а длина строки была всего 8 символов, когда я напечатал arr У меня появилось больше писем, которые я хотел. Некоторые из них даже не были частью струны. Как это возможно?

+0

Можете ли вы быть более конкретным? Вы можете увеличивать 'char *' до тех пор, пока не будет '== '\ 0'' –

+0

Что вы подразумеваете под« пустым »символом' char * '? – merlin2011

+0

Самый простой способ - передать указатель на эту строку. Затем он может быть перераспределен, если строка должна расти. Что касается ввода, вы, вероятно, можете установить максимальный размер, используя что-то вроде fgets. Если вы memset до 0 до fgets и строка слишком длинная, последний символ после fgets не будет null. – cup

ответ

15

Короткий ответ

Вы не можете определить строку с неизвестного размера. Но при необходимости вы можете сделать строку больше и больше. Для всех строковых и I/O-функций необходимо получить уже выделенную строку для работы, поэтому вам нужно немного поиграть с распределением и быть осторожным, чтобы не превышать выделенную емкость.

Однако, если у вас есть постоянная верхняя граница длины строки, просто выделите строку этой длины, и вы будете в безопасности. Изменение размера является более сложным, поэтому избегайте его, если он вам не нужен.

Что строка в C

Строки является частью массива символов, останавливала \0. Строковые функции перестают считывать массив, когда они сталкиваются с первым символом \0. Помните, что strlen возвращает количество символов перед первым \0, поэтому, даже если массив заканчивается сразу после первого \0, длина строки строго меньше, чем основная длина массива. В частности, в этом случае длина массива равна strlen + 1. Это важно при назначении строки; всегда выделяйте пространство для завершающего \0!

E.g.

char w[7] = "Hello"; 

такое же, как

char w[7] = {'H', 'e', 'l', 'l', 'o', '\0', '\0'}; 

При использовании в качестве строки, первый \0 является конец строки и все, что после того, как она игнорируется (не читается строковых функций). Даже если вы перепишете последний элемент массива символов примера печатным символом (например, w[6] = '!';, в результате получив {'H', 'e', 'l', 'l', 'o', '\0', '!'}), puts(w); напечатает Hello (не Hello! или что-нибудь подобное).

При воспроизведении со строками как с массивами символов обязательно указывайте на своем конце \0, как иначе потенциально нераспределенную память после считывания массивом строковыми функциями, что приводит к segfault.

Почему строка неизвестного размера не может быть определена

Как я уже писал, строка является частью массива полукокса. Каждый массив должен иметь фиксированный размер. Вы можете использовать только часть его (эффективно уменьшая его), но он должен быть выделен, и распределитель (malloc, calloc) должен знать, сколько памяти требуется.

Если вы используете массив размером больше, чем выделено, программа, скорее всего, сбой будет segfault в лучшем случае. Если вам очень не повезло, программа не будет разбиваться и будет просто использовать часть памяти сразу после массива, создавая странные результаты.

С C99 вы можете опустить спецификацию длины массива, если она может быть inferred from initializer: char w[] = "Hello"; - тот же результат, что и char w[6] = "Hello";. Однако это не поможет вам, потому что вы указываете инициализатор во время компиляции, и вам нужно динамически изменять длину строки во время выполнения.

Как имитировать произвольную длину строки

Для обработки строк неограниченной длины, вы можете создать массив фиксированной длины и каждый раз, когда его длина слишком мала, выделить новый массив в два раза длиннее и скопировать оригинальное содержимое к новому. (И free - старый). Вы можете использовать realloc для выполнения этой работы для вас, с дополнительным преимуществом более высокой скорости, когда массив не нужно перемещать и его можно просто сделать на месте.

+1

хорошо, есть также 'realloc', который сделает это для вас, более эффективно, избегая копирования, когда это возможно. – user4815162342

+0

Я могу узнать, какова максимальная длина этой строки, но когда я создал, например, arr [100] и использовал ее, когда я ее распечатал, у меня появилось больше писем, которые я хотел. – Michael

+0

@Sefi: Это потому, что вы забыли добавить «\ 0», чтобы отметить конец строки. –

4

Строка в C - это не что иное, как массив символов с символом \0, чтобы определить его конец.

Поскольку это массив, он требует хранения, и поэтому вы не можете «определить» его без хранения.

0

Вы можете выделить память для вашей строки с помощью malloc():

int n = 100; 
char * str = malloc(n); 
// assign characters to your string, finish last one with 0. 
// ... 

Однако, не забудьте освободить выделенную память с помощью free():

free(str); 
-4

Попробуйте символьную строку, как указатель.

char *strng ; 

Я думаю, что это решит проблему

+2

Вам нужно выделить память –

-3

Просто дайте строку разумной длины и убедитесь, что пользователь не выходит за пределы этих границ.

Возможно, вы должны иметь представление о верхней границе для ввода пользователей?

например.

телефонный номер до 20 символов Первая строка адреса находится под 30 МОГ в большинстве

Люди набрав более сделали ошибку

+0

Да, но я не получаю желаемый результат, когда я печатаю этот массив, я получаю сумасшедшие буквы после строки. – Michael

+1

@Sefi: Это потому, что вы забыли добавить маркер конца строки '\ 0'. –

Смежные вопросы