Строка заключает в другую без присваивания, почему это? - PullRequest
2 голосов
/ 23 мая 2011

Ниже приведена функция из программы:

//read the specified file and check for the input ssn
int readfile(FILE *fptr, PERSON **rptr){
    int v=0, i, j;
    char n2[MAXS+1], b[1]=" ";

    for(i=0; i<MAXR; i++){
        j=i;
        if(fscanf(fptr, "%c\n%d\n%19s %19s\n%d\n%19s\n%d\n%19s\n%19s\n%d\n%d\n%19s\n\n",
                    &rptr[j]->gender, &rptr[j]->ssn, rptr[j]->name, n2, &rptr[j]->age, 
                    rptr[j]->job, &rptr[j]->income, rptr[j]->major, rptr[j]->minor,
                    &rptr[j]->height, &rptr[j]->weight, rptr[j]->religion)==EOF) {
            i=MAXR;
        }
        strcat(rptr[j]->name, b);
        //strcat(rptr[j]->name, n2);
        if(&rptr[MAXR]->ssn==&rptr[j]->ssn)
            v=j;
    }
    return v;
}

закомментированная строка похожа на это, потому что по какой-то причине массив 'b' содержит строку 'n2', несмотря на очевидное отсутствие присваивания. Это происходит до первого вызова strcat, но после / во время вызова fscanf.

он достигает желаемой цели, но почему n2 объединяется в конце b, особенно когда b имеет зарезервированное пространство только для 1 элемента массива?

Вот фрагмент определения переменных после вызова fscanf:

*rptr[j]->name = "Rob"

b = " Low"

n2= "Low"

Ответы [ 2 ]

3 голосов
/ 23 мая 2011

Это работает, потому что тебе повезло. b и n2 оказались рядом друг с другом в памяти в правильном порядке. C не выполняет проверку границ массивов и, к счастью, позволит вам переполнить их. Таким образом, вы можете объявить массив следующим образом:

char someArray[1] = "lots and lots of characters";

Компилятор C (конечно, старый) подумает, что это нормально, хотя в someArray явно недостаточно места для хранения такого количества символов. Я не уверен, что он определил, что он будет делать в этой ситуации (я подозреваю, что нет), но на моем компиляторе он ограничивает заполнение размером массива, поэтому он не выходит за границы (someArray=={'l'}) ,

Ваша ситуация такая же (хотя и менее экстремальная). char b[1] создает массив с достаточным пространством для хранения 1 байта. Вы помещаете пробел в этот байт, поэтому нет места для нулевого терминатора. strcat продолжает копировать память до тех пор, пока она не достигнет нулевого терминатора, следовательно, она будет продолжать работать до тех пор, пока не найдет его, даже если этого не произойдет до конца следующей строки (что и происходит в вашем случае).

Если бы вы использовали компилятор C ++, он бы выдал хотя бы предупреждение (или, скорее, ошибку), чтобы сообщить вам, что вы пытаетесь поместить слишком много элементов в массив.

2 голосов
/ 23 мая 2011

B должно быть размером 2, 1 для пробела, 1 для нуля.

...