2010-08-08 2 views
2

Я недавно писал некоторые основные программы командной строки (я хочу, чтобы мои навыки были острыми в течение лета), но printf и scanf начали меня раздражать. Я не замечательный программист на C, и мне нужно попасть в printf/scanf, и их неустойчивости (или, что еще хуже, fgets и т. Д.) Не совсем устраивает меня в утешительной обстановке (именно по этой причине я люблю NSLog, с его комфортным пространством имен по умолчанию и его автоматическим анализом NSString и NSObject).Методы замены печати/сканирования: требуется некоторая обратная связь/рекомендации

К большому разочарованию, однако, NSLog не имеет функции-контрагента и печатает много лишнего «мусора» (время, имя функции и т. Д. Вместе с новой строкой в ​​конце), которая побеждает много цели в моем использовании. Поэтому я решил сесть за другое упражнение по программированию и написать функции для замены printf и scanf, которые отвечали бы моим потребностям.

И voila, я придумал свой собственный файл NSInput.h, содержащий две функции: NSPrint() и NSScan(). Эти две функции сильно моделируются после printf и scanf, но также обрабатывают NSString. Я знаю, что нахожусь здесь на священном пространстве имен, но я не мог удержаться (IFPrint и IFScan просто звучит ужасно!).

Теперь, когда я действительно счастлив, что рабочий код (для которого вы можете найти источник here), я знаю, что это не эффективно (к моему удивлению, хотя, NSPrint в несколько раз эффективнее, чем printf под LLDB в Xcode 4, но это не относится к делу). Мне нужен совет о том, как сделать функции лучше и эффективнее. NSScan, например, преобразует va_list, он получает в NSPointerArray и использует NSScanner для сканирования формата и ввода строк, поэтому я знаю, что есть много возможностей для улучшения.

В принципе, Я хочу знать, есть ли какие-либо вопиющие ошибки, которые я сделал, которые могут и должны быть исправлены? Есть что-то огромное, что я пропустил? Должен ли я просто называться испорченным и вернуться к использованию printf и scanf? Пожалуйста, скажите мне, я ищу здесь вход (каламбур не предназначен!) ...

Заранее благодарен!

+0

Что вы ищете в функции, подобной printf, которую вы не можете получить с помощью [NSString stringWithFormat:]? –

+2

Одно явное упущение, которое я заметил, - отсутствие тестового набора. –

+1

@Seamus: если вы посмотрите на источник, это именно то, что я делаю. @Greg: Я на самом деле никогда не делал тестовых наборов раньше, так что, думаю, сейчас самое подходящее время попробовать, верно? Спасибо за ответы! –

ответ

3

Мои мысли:

  • Не называть их NSxxxxx, NS зарезервирован для какао и Фонда.
  • Обе функции должны быть изменены, чтобы принять FILE*, то есть вы должны моделировать интерфейс до fprintf() и fscanf() для большей гибкости.
  • Ваша функция Printf, вероятно, будет лучше, если вы использовали fputs()

например

void NSFPrint (FILE* fp, NSString *format, ...) 
{ 
    // Create the variable argument list. 
    va_list args; 
    va_start(args, format); 

    // Using NSString, parse the argument list and convert it to a C string. 
    fputs([[[[NSString alloc] initWithFormat:format arguments:args] autorelease] UTF8String], fp); 
    va_end(args); 
} 
  • рассмотреть вопрос о добавлении поддержки ввода и вывода, отличных UTF-8 кодировке.
  • Ваша замена scanf смешивает C буферизированный IO и Unix без буферизации ввода-вывода на stdin. Это может быть плохо.
  • Ваша замена scanf считывается до конца строки, даже если она не нужна. Я не проверял внимательно, но если формат сканирования не потребляет всю строку, похоже, что вы отбрасываете ввод. Это может быть плохо.
+0

Спасибо за предложения! Я буду применять их как можно скорее. Только один вопрос, однако. Что вы подразумеваете под моим использованием как C буферизованного ввода-вывода IO, так и Unix-буферизованного ввода-вывода, или, по крайней мере, как я могу избежать этой проблемы? –

+0

Я немного обновил свой код (http://snipt.org/XmL), чтобы отразить ваши предложения (я переименовал функции IFPrint и IFScan, теперь они принимают указатели файлов в качестве аргументов, 'IFPrint' теперь использует 'fputs', и я заменил' read (0, NULL, 1) 'на' fgetc' - это то, что вы имели в виду с буферизованным/небуферизованным IO?). Надеюсь, я направляюсь в правильном направлении. –

+2

Да. Вызов функции read() 'является системным вызовом Unix, и он читает прямо из дескриптора файла, используя только вызовы Unix IO. 'fgets()' - это функция библиотеки C, которая работает на 'FILE *'. указатель файла. Указатель файла поддерживает буфер и fgets только считывает из физического файла, когда этот буфер исчерпан. И когда он читает, он читается в большом блоке. Таким образом, выполнение 'fgetc()' не так неэффективно, как вы думаете, потому что большую часть времени он получает символ из внутреннего буфера. – JeremyP

 Смежные вопросы

  • Нет связанных вопросов^_^