Вот решение, основанное на мощном, но плохо документированном методе logging.config.dictConfig
. Вместо того, чтобы отправлять каждое сообщение журнала на стандартный вывод, он отправляет сообщения с уровнем журнала ERROR
и выше на stderr
, а все остальное на stdout
. Это может быть полезно, если другие части системы прослушивают stderr
или stdout
.
import logging
import logging.config
import sys
class _ExcludeErrorsFilter(logging.Filter):
def filter(self, record):
"""Filters out log messages with log level ERROR (numeric value: 40) or higher."""
return record.levelno < 40
config = {
'version': 1,
'filters': {
'exclude_errors': {
'()': _ExcludeErrorsFilter
}
},
'formatters': {
# Modify log message format here or replace with your custom formatter class
'my_formatter': {
'format': '(%(process)d) %(asctime)s %(name)s (line %(lineno)s) | %(levelname)s %(message)s'
}
},
'handlers': {
'console_stderr': {
# Directs log messages with log level ERROR or higher to stderr
'class': 'logging.StreamHandler',
'level': 'ERROR',
'formatter': 'my_formatter',
'stream': sys.stderr
},
'console_stdout': {
# Directs log messages with log level lower than ERROR to stdout
'class': 'logging.StreamHandler',
'level': 'DEBUG',
'formatter': 'my_formatter',
'filters': ['exclude_errors'],
'stream': sys.stdout
},
'file': {
# Directs all log messages to a file
'class': 'logging.FileHandler',
'level': 'DEBUG',
'formatter': 'my_formatter',
'filename': 'my.log',
'encoding': 'utf8'
}
},
'root': {
# In general, this should be kept at 'NOTSET' to ensure it does
# not interfere with the log levels set for each handler
'level': 'NOTSET',
'handlers': ['console_stderr', 'console_stdout', 'file']
},
}
logging.config.dictConfig(config)
Печать «\\ n» - «\\» дает «\», и тогда «n» распознается как обычный символ. Для получения дополнительной информации см. здесь .
The function printchar()
below will print some characters as "special", and print the octal code for characters out of range (a la Emacs), but print normal characters otherwise. I also took the liberty of having '\n'
print a real '\n'
after it to make your output more readable. Also note that I use an int
in the loop in main
just to be able to iterate over the whole range of unsigned char
. In your usage you would likely just have an unsigned char
that you read from your dataset.
#include <stdio.h>
static void printchar(unsigned char theChar) {
switch (theChar) {
case '\n':
printf("\\n\n");
break;
case '\r':
printf("\\r");
break;
case '\t':
printf("\\t");
break;
default:
if ((theChar < 0x20) || (theChar > 0x7f)) {
printf("\\%03o", (unsigned char)theChar);
} else {
printf("%c", theChar);
}
break;
}
}
int main(int argc, char** argv) {
int theChar;
(void)argc;
(void)argv;
for (theChar = 0x00; theChar <= 0xff; theChar++) {
printchar((unsigned char)theChar);
}
printf("\n");
}
Вы можете убрать обратную косую черту, чтобы печатать обычную обратную косую черту: «\\ n».
Изменить: Да, вам придется выполнить синтаксический анализ вручную. Однако код для этого будет просто поиском и заменой.
Если вы хотите убедиться, что вы не печатаете непечатаемые символы, вы можете использовать функции из ctype.h
, например isprint
:
if( isprint( theChar ) )
printf( "%c", theChar )
else
switch( theChar )
{
case '\n':
printf( "\\n" );
break;
... repeat for other interesting control characters ...
default:
printf( "\\0%hho", theChar ); // print octal representation of character.
break;
}
В C / C ++ символ '\' зарезервирован как escape-символ. Поэтому, когда вы действительно хотите напечатать '\', вы должны ввести '\'. Итак, чтобы напечатать фактическое значение '\ n', вы должны напечатать следующее:
printf("\\n");
В дополнение к примерам, предоставленным другими людьми, вам следует посмотреть на функции классификации символов, такие как isprint () и iscntrl () . Их можно использовать для определения того, какие символы можно или не печатать, без необходимости жесткого кодирования шестнадцатеричных значений из таблицы ascii.
Просто используйте String :: replace для замены неправильных символов перед вызовом printf.
Вы можете обернуть printf, чтобы сделать что-то вроде этого:
void printfNeat(char* str)
{
string tidyString(str);
tidyString.replace("\n", "\\n");
printf(tidyString);
}
. ..и просто добавьте дополнительные операторы замены, чтобы избавиться от других нежелательных символов.
[Edit] или, если вы хотите использовать аргументы, попробуйте следующее:
void printfNeat(char* str, ...)
{
va_list argList;
va_start(argList, msg);
string tidyString(str);
tidyString.replace("\n", "\\n");
vprintf(tidyString, argList);
va_end(argList);
}