2016-12-05 4 views
1

Функция aquire_marks предназначена для того, чтобы принимать 5 номеров, введенных пользователем, и хранить их в marks. При запуске цикл for работает как ожидалось с j=0, а затем, как и ожидалось, для j=1, но тогда j никогда не увеличивается до 2 и остается в 1, оставив функцию в бесконечном цикле. Если цикл помещен внутри main, эта проблема не возникает, но я предпочел бы иметь ее внутри отдельной функции, если это возможно. Вы знаете, что здесь происходит?Счетчик циклов, не увеличивающий

#include<stdio.h> 

void aquire_marks(char marks[], char names[][11]){ // 11 - max name length + 1 
    char j, mark; 

    for(j=0; j<5; j++){ 
     printf("Enter mark for %s: ", names[j]); 
     scanf("%d", &mark); 
    } 
} 

int main() { 
    char names[5][11] = {"a", "b", "c", "d", "e"}; 
    char marks[5]; 

    aquire_marks(marks, names); 
} 
+1

Почему^а 'char', а затем используется в качестве индекса в цикле? –

+2

'scanf ("% c ", &mark);'? Не является символом 'char'? Или он должен быть' int'. – Prajwal

+1

Вы передали 'marks []', но проигнорировали его. –

ответ

6

Вы объявили mark как char, но в scanf вызова вы используете спецификатор d преобразования, которая ожидает его соответствующий аргумент имеет тип int *, не char *. Использование неправильного спецификатора преобразования приводит к неопределенному поведению.

Я собираюсь предположить, что mark и j являются смежными в памяти, и что в процессе чтения целочисленное значение для mark (который может где-нибудь от 2-х до 4 байт в ширину) значение j становится перезаписаны. (90, 75 и т. Д.)? Если это так, измените тип mark от char до int.

Если mark должна представлять собой буквенную (A, B и т.д.), а затем изменить scanf вызов

scanf(" %c", &mark); // note leading whitespace 
+0

nah Я выбрал char специально, так как мне нужны только номера меньше 128 – ACarter

+1

@ACarter: Лучше использовать 'int' и делать свою собственную проверку диапазона, но все в порядке. Если вы хотите читать * числовые * значения и хранить их в типе 'char', тогда используйте'% hhd' в качестве спецификатора преобразования вместо '% d', поэтому' scanf' будет читать правильное количество байтов. –

0

Я хотел бы изменить декларацию J к int.

char mark; 

for(int j=0; j<5; j++){ 
    printf("Enter mark for %s: ", names[j]); 
    scanf("%d", &mark); 
} 
+0

Это не решает проблему (или даже упоминает об этом). –

3

Вы передаете адрес 1 byte переменной (char) на функцию, которая будет угроза его как int указатель.

Если мы предположим, что int является 4 bytes, scanf перезаписать 3 byte стека рядом с mark переменной.

Первый, предположительно, j;

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