почему snprintf копирует разные значения, хотя одни и те же переменные копируются в строковый массив каждый раз - PullRequest
0 голосов
/ 04 октября 2019

Моя проблема описана в следующем простом коде. Я ожидаю, что в обоих printfs скопировать одно и то же значение в эту строку каждый раз. Но я вижу, что для одного оператора копируется значение ascii, а для другого фактическое значение копируется. Почему эта разница?

#include<stdio.h>
#include<string.h>

int main()
{
   char string[20];
   int id = 1;
   memset(string,0,20);
   snprintf((char *) (string),19,"%d",id);
   snprintf((char *) (string+10),19,"%d",id);
   return 0;
}

вывод (с использованием gdb)

(gdb) p  string
$1 = "1\0\0\0\0\0\0\0\0\0\61\0\0\0\0\0\0\0\0"
(gdb)

Ответы [ 2 ]

1 голос
/ 04 октября 2019

Символ '1' и восьмеричное значение '\ 61' являются презентациями из одинакового значения.

Рассмотрим:

Breakpoint 1, main () at main.c:11                                                           
11         return 0;                                                                         
(gdb) p string                                                                               
$1 = "1\000\000\000\000\000\000\000\000\000\061\000\000\000\000\000\000\000\000"             
(gdb) p string[0]                                                                            
$2 = 49 '1'                                                                                  
(gdb) p string[10]                                                                           
$3 = 49 '1'                                                                                  
(gdb)    
1 голос
/ 04 октября 2019

Нет разницы между результатами, полученными при двух вызовах snprintf. В обоих случаях символ «1» записывается в указанное место, за которым следует нулевой символ.

Существует разница в том, как GDB отображает данные. Для байтов 0 и 1 из string он показывает:

1\0

, что означает символ «1», за которым следует символ с кодом 0, также называемый нулевым символом. Для байтов 10 и 11 из string он показывает:

\61\0

, что означает символ с восьмеричным кодом 61, за которым следует символ с кодом 0. Код ASCII для «1» равен 61 в восьмеричном (49 в десятичном виде), так что это то же значение, что и в байте 0, при условии, конечно, что ваша реализация C использует ASCII.

Единственное отличие заключается в отображении. Это отображение является следствием поведения GDB, а не вашей программы. Мы можем предположить, что GDB отображает «1» в байте 10 в восьмеричном виде, а не в виде литерала «1», потому что перед ним или в окружении непечатаемых символов, или потому, что после нулевого символа заканчивается нормальная строка.

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