#c
#c
Вопрос:
эй, ребята, итак, у меня есть этот код, с которым я работаю, и он делает все, что мне нужно, однако я не могу понять, почему мой printf печатается дважды для level . вот код.
while(fgets(str_read, sizeof(str_read)-1 , fptr)!= NULL)
sscanf(str_read, "%d ", amp;somearray->level);
printf("level: %dn", somearray->level);
также, если есть что-то еще, над чем я мог бы поработать, я открыт для обратной связи. я работаю с файлом .txt, который имеет следующие настройки:
int
name
int
name
int
name
Комментарии:
1. «вот код»? Я думаю, что нет, если только это каким-то образом не закодировано в точке в конце этого предложения 🙂
2. извините, у меня возникли проблемы. все еще новый, так что я все еще получаю свои морские ноги.
3. кроме того, если кто-нибудь хочет научить меня тому, как делать эти классные фрагменты кода с моими собственными комментариями, я тоже открыт для этого.
4. Райан, ты можешь либо поставить как минимум четыре пробела в начале каждой строки кода (и пустую строку до и после), либо окружить свой код тройными обратными метками. Для этого первого варианта вы можете пометить текст без отступов, а затем просто использовать CTRL-K.
5. Предполагается
str_read
, что это массив,sizeof(str_read)-1
просто должен бытьsizeof(str_read)
, нет-1
withfgets()
, это гарантирует, что результирующая строка завершается нулем. Такжеprintf("level: %dn", somearray->level);
НЕ является частью вашего цикла. C — это не Python….
Ответ №1:
Вам нужно проверить возвращаемое значение из sscanf
. В строках, которые не содержат целого числа, оно будет возвращено 0
. В этом случае somearray->level
он не изменится, поэтому вы распечатаете его во второй раз.
Одним из возможных решений является:
while(fgets(str_read, sizeof(str_read)-1 , fptr)!= NULL)
if (sscanf(str_read, "%d ", amp;somearray->level) == 1)
printf("level: %dn", somearray->level);
Это пытается sscanf
выполнить для каждой строки, но выводит результат только в том случае, если было найдено значение.
Другим решением было бы отслеживать четные и нечетные строки и пытаться использовать только sscanf
нечетные строки.
Комментарии:
1. Спасибо Тому за помощь. Ценю это
2. @Ryanv048 — ваши выводы здесь: (1) вы проверяете КАЖДЫЙ пользовательский ввод и (2) вы проверяете КАЖДОЕ преобразование. Вы делаете это, чтобы знать, что у вас есть допустимое значение, прежде чем продолжить использовать это значение в своем коде. Сбой проверки вызывает неопределенное поведение .
Ответ №2:
Во-первых, я собираюсь предположить, что ваш код имеет фигурные скобки вокруг него, поскольку в противном случае он будет печатать только один раз в конце (фигурные скобки управляют тем, что находится в теле цикла, а не отступом):
while(fgets(str_read, sizeof(str_read)-1 , fptr)!= NULL) {
sscanf(str_read, "%d ", amp;somearray->level);
printf("level: %dn", somearray->level);
}
Это соответствует тому, что вы видите. Если ваш текстовый файл состоит из чередующихся целых чисел и нецелых имен, каждую секунду sscanf
будет происходить сбой, потому что имя нельзя рассматривать как целое число. Поскольку вы не проверяете возвращаемое значение, вы просто слепо предполагаете, что преобразование сработало, и печатаете значение, которое было введено ранее somearray->level
.
Вызовы scanf
семейства функций обычно должны включать проверку, чтобы убедиться, что все было правильно отсканировано, что-то вроде:
if (sscanf(str_read, "%d ", amp;somearray->level) != 1) {
handleBadScan();
}
Комментарии:
1. Спасибо, Пакс, Это действительно приятно знать. Я буду работать над этой проверкой.
2. Привет, Пакс, вопрос к тебе. куда мне следует обратиться, чтобы узнать больше о возвращаемых значениях thing, как в этом примере 1. Я знаю, что 0 в return означает, что он выполняется просто отлично и без ошибок, и возвращает, как 1 и -1 возвращает ошибки. Они имеют ту же концепцию, что и в операторе if? Надеюсь, это имеет смысл. лол
3. Райан, я использую для этого стандарт C, но в основном это довольно сухое чтение, поэтому вы можете подумать о том, чтобы просто посмотреть справочные страницы, или cplusplus.com . Однако в качестве окончательного источника того, что делают функции, я предпочитаю стандарт.