Прочитайте прямо в выделенное пространство с помощью fgets()
.
Особое внимание следует уделить распознаванию успешной ошибки чтения, конца файла, ввода и выхода из памяти.
Этот метод сохраняет строку '\n'
.
#include <stdio.h>
#include <stdlib.h>
#define FGETS_ALLOC_N 128
char* fgets_alloc(FILE *istream) {
char* buf = NULL;
size_t size = 0;
size_t used = 0;
do {
size += FGETS_ALLOC_N;
char *buf_new = realloc(buf, size);
if (buf_new == NULL) {
// Out-of-memory
free(buf);
return NULL;
}
buf = buf_new;
if (fgets(&buf[used], (int) (size - used), istream) == NULL) {
// feof or ferror
if (used == 0 || ferror(istream)) {
free(buf);
buf = NULL;
}
return buf;
}
size_t length = strlen(&buf[used]);
if (length + 1 != size - used) break;
used += length;
} while (buf[used - 1] != '\n');
return buf;
}
Использование образца
int main(void) {
FILE *istream = stdin;
char *s;
while ((s = fgets_alloc(istream)) != NULL) {
printf("'%s'", s);
free(s);
fflush(stdout);
}
if (ferror(istream)) {
puts("Input error");
} else if (feof(istream)) {
puts("End of file");
} else {
puts("Out of memory");
}
return 0;
}
Для этого вы можете использовать объекты F ()
.
Вот как вы импортируете F
: из django.db.models import F
Новое в Django 1.1 .
Вызовы для обновления также могут использовать F () объекты для обновления одного поля на основе значения другого поля в модели. Это особенно полезно для увеличения счетчиков на основе их текущего значения.
Entry.objects.filter(is_published=True).update(views=F('views')+1)
Хотя вы не можете выполнить обновление нарезанного набора запросов ... редактировать: на самом деле вы можете ...
Это можно сделать полностью в django ORM. Вам понадобятся два SQL-запроса:
Получение неразрезанного запроса набор - жесткий бит. Я подумал об использовании in_bulk
, но это возвращает словарь, не набор запросов. Обычно можно использовать Q объектов
для выполнения сложных запросов типа ИЛИ, и это будет работать, но pk__in
выполняет эту работу намного проще.
latest_entry_ids = Entry.objects.filter(is_published=True)\
.order_by('-date_published')
.values_list('id', flat=True)[:10]
non_sliced_query_set = Entry.objects.filter(pk__in=latest_entry_ids)
n = non_sliced_query_set.update(views=F('views')+1)
print n or 0, 'items updated'
Из-за того, что django выполняет запросы лениво. , в результате получается всего 2 обращения к базе данных, независимо от того, сколько элементов обновлено.
Вы могли обработать обновления в единственной транзакции, которая могла значительно улучшить производительность. Используйте отдельную функцию, украшенную @transaction.commit_manually.
@transaction.commit_manually
def update_latest_entries(latest_entry_list):
for entry in latest_entry_list:
entry.views += 1
entry.save()
transaction.commit()
Пересмотренный
Вы обновляете 10 отдельных, отдельных, отдельных объектов.
Эти 10 отдельных, отдельных, отличных обновлений не могут легко быть свернуты в одно волшебное обновление, которое так или иначе касается 10 объектов.
При реальной необходимости в эффективности в данный момент Вы имели бы к выпадающему в SQL и выполнять обновление сами. Это не стоит добавленной сложности в этом случае, все же.
Django 1.1 Вы будете в состоянии сделать это в единственном вызове SQL через ORM использование F () объекты к полям ссылки в значении обновления.
Улучшение производительности к предыдущей записи. Это приводит к одной базе данных, с помощью подзапросе.
latest_entry_query_set = Entry.objects.filter(is_published=True)
.order_by('-date_published')[:10]
non_sliced_query_set = Entry.objects.filter(pk__in=latest_entry_query_set.values('id'))
n = non_sliced_query_set.update(views=F('views')+1)
print n or 0, 'items updated'