2013-03-27 4 views
1

Я хочу прочитать escape-последовательность из файла, где он хранится дословно.Escaping in sprintf

В какой-то момент мой вызов заканчивается в одном из ANSI-C отформатированный функций

sprintf(target, format, ...); 

моя проблема проявляется без ARGS части - так что не беспокойтесь о деталях этого.

строка формата загружается из файла и сохраняется в буфере. '\\' 'r' '\0' (файл содержит '\\' 'r' '\0')

Я хочу, чтобы цель, чтобы сохранить «\r», но моя цель всегда заканчивается как '\\' 'r' '\0'.

Как я могу решить эту проблему?


Edit:

Чтобы прояснить мою проблему.

текстового файла содержит три символа - '\\' 'r' '\0'

Те три считываются и должны быть сохранены как два cahracters '\r' '\0'

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

+0

все это встроено в тестируемый модуль, и мне нужно сохранить аргументы. Мне нужно, чтобы sprintf распознал побег. – Johannes

+1

Это не совсем понятно (хотя я ценю, что это трудно описать!); этот текстовый файл содержит три символа или 13? –

+2

Если вы дадите рабочий пример того, что вы делаете, это поможет сделать это более ясным. – teppic

ответ

2

Там нет стандартных функций, которые будут делать ООН-ускользающей для вас, так что вам придется сделать это самостоятельно ,

void unescape(const char *in, char *out) 
{ 
    int esc = 0; 

    while (*in) { 

     if (esc) { 

      switch(*in) { 
      case 'r': 
       *out++ = '\r'; 
       break; 
      case 'n': 
       *out++ = '\n'; 
       break; 
      default: 
       *out++ = '\\'; 
       *out++ = *in; 
       break; 
      } 

      esc = 0; 

     } else if (*in == '\\') { 
      esc = 1; 
     } else { 
      *out++ = *in; 
     } 

     in++; 
    } 

*out = 0; 
} 

(* обратите внимание, что буфер 'out' должен быть не менее, чем буфер 'in'.И если последний символ является \, то теряется)

Вы бы затем сделать

char input[BUFSZ]; 
char buf[BUFSZ]; 

//read data from the file into 'input' 

unescape(input, buf); 
sprintf(target, buf, ...); 
+0

ОК, я думаю, что я ничего не могу сделать ... я буду говорить с клиентом о том, что ему действительно нужно, и посмотреть, смогу ли я обойти это. – Johannes

2

Двойной "" сделать строку из \r, тогда как '\r' относится к одному символу или экранированной последовательности. Вы можете использовать strcat -функцию и добавить один символ в свой формат, поскольку strcat требует const char*. Попробуйте

strcat(format, '\r'); 

конечно, вам нужно будет предоставить достаточный объем памяти.

Как предусмотрено Oli Чарльзуорт, возьмите строку и

len = strlen(str); str[len] = '\r'; 
str[len+1] = '\0'; 

В этом конкретном случае, вы пишете над строкой.

Посмотрите here.

+0

строка формата предоставляется снаружи и содержит три символа '\\', 'r', '\ 0'. Я не свободен для жесткого кодирования '\ r'. – Johannes

+1

'strcat' принимает' const char * 'как свой второй аргумент, а не' char'. –

+0

@OliCharlesworth Так ли это? –

1

Разобрать внешний формат и построить (внутренний) формат, как требуется, например:

if ((externalformat[0] == '\\') 
     && ((externalformat[1] == 'r') 
     && ((externalformat[2] == 0)) 
{ 
    strcpy(format, "\r"); 
} 

/* use format */ 
sprintf(target, format, ...); 
+0

Это была бы моя последняя солома, я надеюсь, что есть другие варианты. Но вы поняли мою проблему. – Johannes

2

Можете ли вы sprintf это дважды?

Если исходный файл имеет "\\r" (три ненулевых символы), первый запуск через sprintf бы создать цель "\r" (два непустых символов с обратным косыми чертами экранирования).

Тогда вы могли бы использовать его в качестве формата строки для следующего sprintf, который должен создать цель '\r' (единственный символ возврата каретки).

Редактировать: Это не будет работать, если исходная строка формата также не выходит за пределы спецификаторов формата (%).

+0

Я буду экспериментировать с этим. Клиент согласился отказаться от usecase, он действительно не нуждается в этом. Иногда решение не программируется :) – Johannes