Сижу, отлаживаю новый онлайновый ассемблер в своем эмуляторе Радио-86РК. Под отладкой понимается ёрзанье с применением html'я.
Для сборки финального html-файла из кучи мелких у меня написана примитивная программа. Вот ее фрагмент:
...
while (!feof(f)) {
char line[1024];
*line = 0;
fgets(line, sizeof(line), f);
printf(line);
}
...
Подразумевается, что данный код прострочно копирует данные из файла f
на стандарный вывод.Даже если отставить в сторону использование буфера с константной длиной и прочих "штучек" языка С, этот код имеет одну проблему, которая стоила мне сомнений в наличии сознания. До каких-то пор все работало отлично, но как только я начал использовать процентные значения для широт и высот в html, начались странности. Получалось, что вместо, например:
<table width="100%">
на выходе было:<table width="100">
Вы, наверное, уже догадались, в чем тут дело. Но, признаюсь, я искал проблему минут тридцать.Вместо:
printf(line);
надо писать:printf("%s", line);
А иначе все процентные символы будут расцены как указатели форматов, ибо первый параметр printf()
- это не просто строка, а формат, и в случае их неэкранирования будут уделены, что и происходило в моем случае.Вывод (который следует после начального "сам дурак"): Лучше писать на С++ и использовать потоки для форматного вывода.
Лирическое отступление. Кстати, онлайновый ассемблер очень огранично вписался в эмулятор. Спасибо Вячеславу Славинскому за оригинальный код этого ассемблера. Особенно меня радует возможность автоматической фоновой компиляции. Теперь можно, прямо не отходя от эмулятора, переключиться в ассемблер, написать что-нибудь на диалекте Intel 8080 (КР580), скомпилировать и загнать прямо в эмулятор.
Плюс ещё ошибки будут, если в файле есть нулевые символы ('\0') или спецсимвол конца файла.
ОтветитьУдалитьА компилировали бы с флагом -Wall, сразу бы увидели предупреждение.
ОтветитьУдалитьТеперь буду знать.
ОтветитьУдалитьДля вывода строки можно использовать просто puts. Оно быстрее должно работать, ведь puts не нужно разбирать формат.
ОтветитьУдалитьПо поводу спецсимвола конца файла (0x1A - ^Z), он применим только для текстового режима - "t". В этом случае в вендах при встрече 0x1A, feof действительно возвращает EOF(-1). Кроме того, текстовые преобразования при режиме "t" зависят от платформы, на некоторых системах режим "t" игнорируется, и всегда используется режим "b". Поэтому лучше "t" не использовать, открывать файлы в бинарном режиме "b".
-Wall не покажет варнинг. Как будто не может быть динамических форматов.