Что означает «у» в выводе в C? - PullRequest
6 голосов
/ 15 ноября 2009

У меня проблема, я строю строку в цикле, и вывод этой строки в stout отображает строку и символ 'y' с двумя точками над ним как последний символ.

Что это?

Я создаю строку в этой функции:

char get_string(char *buf, int ble, FILE *fp, char del)
{
    int i = 0;
    int c;
    char    result;

    memset(buf, 0, BUFLEN);

    do {

        c = fgetc(fp);

        if (c == del) {
            buf[i] = '\0';
            result = c;
            break;
        } else if(c == '\n') {
            buf[i] = '\0';
            result = '\n';
            break;
        } else {
            buf[i] = c;
            i++;
        }

    } while (c != EOF);

    return result;
}

, а затем используйте buf и результат в следующей функции:

char    pair[BUFLEN];
char    end;

do {

        end = get_string(pair, BUFLEN, fp, ';');
        printf("Result: %s\n",pair);

} while (pair != NULL);

Последняя итерация вышеприведенного Выводит "Result: y", я понятия не имею, почему.

Ответы [ 6 ]

9 голосов
/ 15 ноября 2009

Вы используете цикл do - while, что означает, что вы выполняете тело цикла перед тестированием на EOF, так что в итоге вы также помещаете EOF в свой буфер. Значение EOF -1 переводится в диапазон символов, где оно соответствует ÿ. Я бы порекомендовал вам просто переключиться на более обычный цикл while, потому что он обрабатывает это условие более естественно.

8 голосов
/ 15 ноября 2009

ÿ - это символ для символа, который (в Unicode и многих кодировках ISO-8859-) имеет порядковое значение 0xFF. Это значение, также известное в десятичном виде как 255, также используется в некоторых контекстах как «символ конца файла» (он же EOF) - хотя не существует стандарта, определяющего символ как таковой (AFAIK ) значение -1 - это то, что возвращается во многих языках (например, C), когда вы пытаетесь прочитать больше из файла, который исчерпан ("в конце файла").

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

2 голосов
/ 15 ноября 2009

'y' с двумя точками над ним является символом 0xFF (в латинице 1 - кодовая страница по умолчанию для консоли).

0xFF в качестве 8-битного значения со знаком равно -1.

Найдите места, где вы печатаете -1 как символ (или используете -1 как символ, а затем печатаете его).

1 голос
/ 15 ноября 2009

Ваше if -статирование, которое заканчивается положением символа в буфер, имеет два недостатка:

  1. Не отфильтровывает EOF специальный "символ", который обозначает конец потока
  2. Он не проверяет переполнение буфера, сравнивая i со значением BUFLEN.

Первая проблема - причина вашего символа,, когда поток заканчивается, вы добавляете символ EOF в буфер, а затем цикл завершается.

Исправление заключается в том, чтобы поместить в ваш оператор if-else предложение, чтобы отфильтровать его, например:

} else if (c != EOF) {
    buf[i] = c;
    i++;
}

Вторая проблема, которую вы должны решить, как решить перед исправлением, но она должна быть исправлена.

1 голос
/ 15 ноября 2009

Когда вы «строите свою строку в цикле», вы не забываете правильно завершить ее с помощью '\0'?

Если цикл присваивает символы массиву символов, последний элемент массива должен быть '\0'.

Хорошо, увидев код, вы заканчиваете строку.

EDIT

Похоже, вы включили символ EOF в вашу строку. Это один из случаев, когда строка не заканчивается правильно. Вы должны проверить EOF в своей структуре if-else и правильно обработать ее.

Еще одна вещь, которую я заметил:

Вы присваиваете int c для char result при выходе из своей функции. Компилятор должен был предупредить вас, что вы пытаетесь поместить больший тип данных в меньший тип данных. В зависимости от цели возвращаемого значения я мог бы подумать об изменении типа возвращаемых данных на int.

0 голосов
/ 15 ноября 2009

Вы неправильно завершаете строку. Если чтение из fp никогда не вернет "del" или "\ n" и вы достигнете EOF, нулевой терминатор не будет Вам нужно исправить свой код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...