2016-11-06 3 views
2

Я не могу узнать причину неправильного поведения приведенного ниже кода. Это простой код для приема символов до тех пор, пока не будет введен ни один из них, либо пока не будет достигнут размер массива, а затем напечатайте символы, считанные с клавиатуры. Похоже, что часть чтения в порядке. Также, если я ввещу * до того, как будет достигнут размер массива, все будет в порядке. Но если я не вхожу * и дождался, пока размер массива не достигнут в части чтения, у меня возникнут проблемы. Во время печати он печатает символы, которые читаются, но после этого печатается какой-то мусор. Отлаживается через отладчик, но цикл не прерывается, когда индекс равен 3 или более.while loop не нарушается

int main() 
{ 
    char myStr [3]; 
    unsigned int index=0; 
    printf("Enter Single characters. Enter * to stop\n"); 
    do 
    { 
     scanf(" %c",&myStr[index]); 
     index++; 
    } while ((myStr[index-1]!='*')&&((index)<(sizeof(myStr)/sizeof(myStr[0])))); 

    index=0; 

    while ((myStr[index]!='*')&&(index<(sizeof(myStr)/sizeof(myStr[0])))) 
    { 
     printf("%c",myStr[index]); 
     index++; 
    } 
    printf("\n"); 

    return(0); 
} 
+0

Размер мифа фиксируется объявлением его [3], возможно? В таком случае ваш фактор не будет представлять количество фактических символов в массиве? –

+0

@JeremyKahan: Выполнение 'sizeof (myStr)/sizeof (myStr [0])' в массиве вполне допустимо для вычисления числа элементов. – alk

+0

@alk да, но я был обеспокоен тем, что есть три элемента, был ли пользователь введен три. Но теперь я вижу, что это не имеет значения, поскольку либо пользователь входит в звезду, либо должен ввести три. –

ответ

2

Код выполняется в непредсказуемое поведение на последней итерации в printf передачи контура здесь

while ((myStr[index]!='*')&&(index<(sizeof(myStr)/sizeof(myStr[0])))) 
    { 
     ... 

, как это на самом деле делает

while ((myStr[3] .... 

с myStr[3] доступа myStr вне пределов.

Чтобы исправить это сделать:

while ((index < (sizeof(myStr)/sizeof(myStr[0]))) && (myStr[index] != '*')) 

Boolean short-circuiting будет заботиться о myStr[3] не выполняется.

+0

Благодарим вас за хороший анализ. Переходя к неопределенному поведению значений, отличных от границ: я понимаю, что myStr [4] может быть значением для мусора. Но все-таки это должно иметь определенную ценность (я думал), потому что это указывает на определенную память. В этом случае первая часть может оцениваться как TRUE или FALSE. В таком случае код должен вести себя корректно. Но я никогда не знал, что простое чтение памяти, которая не является существенной, может привести к полному неправильному поведению приложения. Я могу понять неопределенное поведение системы, если я пишу в память, которая не связана. – Rajesh

+0

Чтобы уточнить: когда index = 3 while цикл все равно не войдет, потому что вторая часть становится FALSE. Итак, printf() не попадает в картину правильно? – Rajesh

+0

Исправлено индексирование от 4 до 3 ...:} – alk

0

Вы манипулируете строками, ведьма должна быть нулевой. Вы должны использовать fgets (3), чтобы получить свою строку, а затем strlen (3), чтобы получить длину. Тогда вы можете двигаться в строке по время (ул [я]! = «*» & & я < StrLen (ул)) удачи

+2

"* Вы управляете строками ... *" нет, OP использует 'char'-array, вот и все. Не существует C-«строк» ​​или никаких функций, полагающихся на 'char'-массивы, используемые в качестве строки C-. – alk

+0

My bad, я видел char * – Glick

+0

Как бы указатель на символ 'char' (' char * ') что-то изменил? – alk