Почему моя простая программа C отображает мусор к stdout?

Проблема в том, что вы используете библиотеку actions-on-google для отправки информации обратно, но ваше Android-приложение не является Action. Поэтому он читает стандартные поля Dialogflow из ответа, а не просматривает раздел «google».

В общем, если вы планируете разрабатывать для платформ, отличных от Assistant, вам следует использовать библиотеку dialogflow-executement , а не actions-on-google, поскольку она позволяет указывать пользовательские полезные нагрузки для вашей платформы.

9
задан GEOCHET 18 January 2010 в 14:36
поделиться

5 ответов

Необходимо NUL-завершить строку. Добавить

buffer[fileLen] = 0;

прежде, чем распечатать его.

39
ответ дан 4 December 2019 в 05:51
поделиться

Подход JesperE будет работать, но можно быть интересно знать, что существует альтернативный способ обработать это.

Можно всегда печатать строку известной длины, даже когда нет никакого NUL-разделителя путем обеспечения длины printf как точность для строкового поля:

printf("%.*s\n", fileLen, buffer);

Это позволяет Вам, печатают строку, не изменяя буфер.

28
ответ дан 4 December 2019 в 05:51
поделиться

JesperE корректен относительно проблемы nul-завершения в Вашем примере, я просто добавлю, что при обработке текстовых файлов, было бы лучше использовать fgets () или что-то подобное, поскольку это правильно обработает последовательности новой строки через различные платформы и будет всегда nul-завершать строку для Вас. Если Вы действительно работаете с двоичными данными затем, Вы не хотите использовать printf () для вывода данных, поскольку функции printf ожидают строки, и nul байт в данных вызовет усечение вывода.

8
ответ дан 4 December 2019 в 05:51
поделиться

Для выделения уже инициализированной памяти можно использовать calloc вместо malloc. calloc принимает дополнительный аргумент. Он полезен для выделения массивов, первый параметр calloc указывает количество элементов в массиве, для которых необходимо выделить память, а второй аргумент - размер каждого элемента. Так как размер char всегда 1, то можно просто передать 1 в качестве второго аргумента:

 buffer = calloc (fileLen + 1, 1);

В C, нет необходимости приводить возвращаемое значение malloc или calloc. Вышеуказанное гарантирует, что строка будет аннулирована, даже если чтение файла по какой-либо причине закончилось преждевременно. calloc действительно занимает больше времени, чем malloc, так как он должен обнулить всю запрошенную память, прежде чем выдать ее вам.

0
ответ дан 4 December 2019 в 05:51
поделиться

.NET поддерживает это с атрибутом [Flags]:

[Flags]
enum KbdHookFlags {
  Extended = 0x01,
  Injected = 0x10,
  AltPressed = 0x20,
  Released = 0x80
}

Пример использования:

  KBDLLHOOKSTRUCT info = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(KBDLLHOOKSTRUCT));
  if ((info.flags & KbdHookFlags.Released) == KbdHookFlags.Released) {
    // Key was released
    // etc..
  }
-121--4121299-

Вы получаете хорошие ответы здесь, но они предполагают, что ваша программа довольно близка к оптимальной для начала, и вы говорите

Предположим, что программа была написан правильно, скомпилирован с полным оптимизация, тестирование и внедрение производство.

По моему опыту, программа может быть написана правильно, но это не значит, что она почти оптимальна. Требуется дополнительная работа, чтобы добраться до этого момента.

Если я могу привести пример, этот ответ показывает, как совершенно разумная программа была сделана более чем в 40 раз быстрее с помощью макрооптимизации . Большие скорости не могут быть сделаны в каждой программе, как впервые написано, но во многих (кроме очень маленьких программ), это может, по моему опыту.

После этого микрооптимизация (горячих точек) может дать вам хорошую отдачу.

-121--685210-

Неправильный подход к определению размера файла путем поиска до конца файла и последующего использования ftell () :

  • Если это текстовый файл, открытый без «b» во втором параметре вызова fopen () , то ftell () Например, окна используют два байта для конца строки, но при чтении это один символ . Фактически, возвращаемое значение ftell () для потоков, открытых в текстовом режиме, полезно только для вызовов fseek () , а не для определения размера файла.
  • Если это двоичный файл, открытый «b» во втором параметре до fopen () , то стандарт C имеет следующее значение:

    Установка индикатора положения файла на конец файла, как и для fseek (file, 0, SEEK_END) , имеет неопределенное поведение для двоичного потока (из-за возможных завершающих нулевых символов) или для любого потока с кодировкой, зависящей от состояния, которая, безусловно, не заканчивается в начальном состоянии сдвига.

Итак, то, что вы делаете, не обязательно будет работать в стандарте C. Ваша лучшая ставка - использовать fread () для чтения, и если вам понадобится больше памяти, используйте realloc () . Ваша система может предоставить mmap () или может гарантировать установку индикатора положения файла на конец файла для двоичных потоков, но полагаться на них не переносится.

См. также C-FAQ: В чем разница между текстом и двоичным вводом-выводом? .

3
ответ дан 4 December 2019 в 05:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: