Как мы узнаем, что строковый элемент в C неинициализирован? - PullRequest
3 голосов
/ 31 января 2010

Есть ли способ узнать, имеет ли элемент в строке в C значение или нет? Я пытался использовать NULL, '' и '', но, похоже, они не работают. Мне нужно сдвинуть символы до индекса 0 без использования функций stdlib.

#include <stdio.h>

int main()
{  
   char literal[100];

   //literal[99] = '\0'
   literal[98] = 'O';
   literal[97] = 'L';
   literal[96] = 'L';
   literal[95] = 'E';
   literal[94] = 'H';

   int index = 0;

   while(literal[index] != '\0')
   {
      if(literal[index] == NULL)   // does not work
         printf("Empty");              

      else
         printf("%c", literal[index]);

      ++index;                  
   }

   getchar();
   return 0;

}

Ответы [ 7 ]

5 голосов
/ 31 января 2010

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

Вы можете инициализировать каждый элемент чем-то особенным и проверить это значение. например Вы можете изменить

char literal[100];

char literal[100] = {0};

для инициализации каждого элемента в 0. Вам нужно изменить проверку завершения цикла while на

while(index < 100) {
  if(literal[index] == 0) 
         printf("Empty"); 
   ...
  }
}

Это может быть неоптимальным, если вам нужно выполнить больше операций со строками в массиве, поскольку 0 теперь означает пустой элемент, а также «конец строки».

3 голосов
/ 31 января 2010

Нет, вы не можете этого сделать. Это потому, что будет иметь значение - просто невозможно узнать, что это за значение. Вот почему важно инициализировать вещи с известными значениями.

1 голос
/ 31 января 2010

Вам нужно установить конец строки на 0 (ноль) или '\ 0' - C делает это автоматически только для строковых литералов, а не локальных переменных в стеке

Попробуйте

memset(&literal, 0, 100);

Или просто раскомментируйте вашу строку, которая устанавливает литерал с индексом 99 равным '\ 0'

1 голос
/ 31 января 2010

Нет, нет способа узнать, какое значение имеет массив. Однако вы можете инициализировать его выбранным значением «по умолчанию» по своему выбору, а затем проверить его.

1 голос
/ 31 января 2010

C по умолчанию ничего не инициализирует. Следовательно, содержимое в вашей строке - это какой бы мусор не находился в этой памяти при последнем использовании его в стеке. Вам необходимо явно установить для каждого литерального значения значение, которое означает «unset» для вас.

0 голосов
/ 31 января 2010

Нет, это неопределенное поведение в качестве среды выполнения, хотя все, что нам нужно, может быть введено в несколько двоичных символов ASCII, вы действительно не хотите в это вдаваться. Лучший способ справиться с этим - использовать цикл for и выполнять итерацию по нему или использовать calloc, который инициализирует указатель, но устанавливает его в 0.

for (i = 0; i < 100; i++) literal[i] = '\0';

OR

char *literalPtr = (char*)calloc(100, sizeof(char)); // Array of 99 elements plus 1 for '\0'

Нет абсолютно никаких гарантий в этом. Следовательно, оно будет классифицировано как неопределенное поведение, поскольку оно зависит от компилятора и реализации времени выполнения.

Надеюсь, это поможет, С наилучшими пожеланиями, Том.

0 голосов
/ 31 января 2010

Строка c - это просто набор областей памяти и соглашение , которое '\0' отмечает конец. Нет принудительного применения компилятора и вложенных метаданных (если вы не строите структуру для их предоставления).

Каждая ячейка в памяти, всегда имеет значение, поэтому каждая строка всегда имеет значение, вы просто не можете гарантировать, что оно разумно или даже заканчивается в выделенном пространстве.

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

...