Как мне предотвратить этот бесконечный цикл - PullRequest
0 голосов
/ 18 февраля 2020

Когда я запускаю следующий код, иногда он успешно завершается, а иногда он вводит бесконечный l oop, если самый высокийNum равен 255. Я понимаю, что это происходит из-за опрокидывания, когда 255 увеличивается и становится равным 0. Я Я понимаю, почему это происходит, но я хотел бы посоветовать остановить это. Должен ли я поставить оператор if в конце, чтобы проверить, равно ли я максимальному числу, а затем разбить в конце? это похоже на плохой стиль и кое-что, что легко забыть исправить, если я увеличил размер переменных.

    // delete all the files
    for (unsigned char i = 0; i <= highestNum; i++){
        rc = snprintf(formatString, sizeof(formatString), "x%u", i);
        if (rc < 0){
            perror("snprintf in delete");
        }
        rc = unlinkat(directoryFD, formatString, 0);
        if (rc == 0){
            printf("file unlinked\n");
        }
    }

Ответы [ 3 ]

1 голос
/ 18 февраля 2020

Вы можете использовать более широкий тип (например, unsigned int), чтобы сделать это с минимальным изменением кода. Другой вариант - использовать различные l oop варианты, такие как do..while:

int highestNum = 255;
{
    unsigned char i = 0;
    do {
        printf("%u\n", i);
        ++i;
    } while (i <= highestNum && i != 0);
}

. Это имеет область видимости, аналогичную вашей for l oop, в этом i не «экранирует» блок, в котором он объявлен, и проверка на i против нуля ловит случай обращения (что более сложно в for l oop, так как проверяет условие в начало каждой итерации, а не конец).

Обратите внимание, что нет проверки, гарантирующей, что highestNumber равен нулю или более, поэтому по крайней мере один файл всегда будет удален. Если вы хотите, чтобы возможность не указывать файлы (например, вы должны установить highestNumber в -1, если нет файлов должны быть удалены), вы можете добавить простую предварительную проверку:

int highestNum = 255;
if (highestNumber >= 0) {
    unsigned char i = 0;
    do {
        printf("%u\n", i);
        ++i;
    } while (i <= highestNum && i != 0);
}
1 голос
/ 18 февраля 2020

Используйте вместо типа unsigned char тип unsigned int. :) В противном случае, когда i равно максимальному значению для типа, равному 255 (UCHAR_MAX is equal to 255), тогда следующее значение после приращения i будет снова 0 и вы получите бесконечное l oop.

Таким образом, любое значение переменной самая высокаяNum, равное или большее UCHAR_MAX, приводит к бесконечному l oop.

0 голосов
/ 18 февраля 2020

Одним из способов избежать этого может быть объявление i как int, а затем приведение его к char в l oop, где он используется.

for (unsigned int i = 0; i <= highestNum; i++){
    rc = snprintf(formatString, sizeof(formatString), "x%u", (unsigned char) i);
    if (rc < 0){
        perror("snprintf in delete");
    }
    rc = unlinkat(directoryFD, formatString, 0);
    if (rc == 0){
        printf("file unlinked\n");
    }
}
...