2016-04-28 2 views
-1

Я пытаюсь напечатать массив символов после цикла for, чтобы увидеть результат, чтобы убедиться, что он правильный. Однако он не будет печатать строку. Почему он не печатает строку? Я что-то упускаю? Он печатает строку индекса println, но бит тега не будет печататься. Что мне не хватает?printf() не печатает строку в c

Вот мой код

char *getTag(char *address){ 
    char *binary, *resultsIndex, *resultsTag, *resultsOffset; 
    char* tags; 
    int i, j, t; 

    printf("Get Tag function\n"); 

    binary = hexToBin(address); 
    printf("Binary : %s\n", binary); 
    printf("Tag : %i\n", TAG); 
    printf("Offset : %i\n", OFFSET); 
    /*Seperate index, tag and offset*/ 

    i = 0; 
    resultsIndex = (char *)malloc(sizeof(char) * INDEX); 
    for(i = 0; i < INDEX; i++){ 
    resultsIndex[i] = binary[i]; 
    } 

    resultsTag = (char *)malloc(sizeof(char) * TAG); 
    //resultsTag = '\0'; 
    for(t = INDEX; t < TAG + 1; t++){ 
     resultsTag[t] = binary[t]; 
     printf("binary[i] %c\n", binary[t]); 
     printf("resultsTag[i] %c\n", resultsTag[t]); //<----prints individual character 
    } 

    printf("Index bit: %s\n", resultsIndex); 
    printf("Tag Bit %s", resultsTag); //<-----Won't print the string 
    return resultsTag; 
} 

Я попытался прибегая к помощи проблеме и попытался некоторые из методов. Один, чтобы сделать результатыTag [t] = '\ 0'. Я попробовал это, и он не будет печатать еще. Что-то не так с моей петлей for, которая может вызвать это?

Он печатает отдельный символ внутри цикла, поэтому я вижу, что он хранит его, но он не будет выводить его за пределы цикла. Любые советы, которые могут быть полезны?

+2

Возможно, из-за отсутствия нулевого символа. Попробуйте добавить результатыTag [t] = 0; в конце блока цикла. – niyasc

+0

Попробуйте добавить 'resultsTag [t] = '\ 0';' после цикла. – Chirality

+0

@niyasc: Отсутствующий терминатор может привести к печати мусора * после * строки, а не печати ничего. В этом случае это «мусор» в начале строки. – Clifford

ответ

1

Если я правильно понимаю, вы пытаетесь разбить строку на две определенные точки, верно? Оказывается, у вас есть строка в binary, которая имеет следующий формат:

XXXXYYYYYYZZZ0 
^ ^^^
| | | \String terminator 
| | \Offset 
| \Tag 
\Index 

Длина отдельных частей, конечно, только пример, потому что я не вижу ваши постоянные значения.Но, по моему примеру, вы можете иметь переменные, определенные как это (с указанием их конец в строке):

#define INDEX 4 
#define TAG 10 
#define OFFSET 13 

Теперь то, что первая проблема в том, почему он сразу не работает для вас: Вы не правильно построив resultsTag. Но давайте сначала посмотрим на resultsIndex.


resultsIndex вид работ, но это тоже не сделано правильно. Я объясню вам, почему. Вы делаете это:

resultsIndex = (char *)malloc(sizeof(char) * INDEX); 
for(i = 0; i < INDEX; i++){ 
    resultsIndex[i] = binary[i]; 
} 

Что он делает:

  • Выделяют INDEX (4 в моем примере) символы для строки результата.
  • Петля от 0 до INDEX (4) исключительно, то есть INDEX - 1 (3) включительно и скопируйте данные.
    Таким образом, i будет получать значения 0..1..2..3 во время цикла. Это означает, что он скопирует все символы из позиций 0-3 в binary в позиции 0-3 в resultsIndex.

После этой части resultsIndex определяется размером 4-х символов (если придерживаться моего примера значения выше) и выглядит следующим образом:

____ << defined size 
XXXX 

... который является частью индекса которую вы скопировали. Однако одна ошибка здесь заключается в том, что нет строкового ограничителя! Он должен выглядеть следующим образом:

_____ << defined size 
XXXX0 
    ^
    \string terminator 

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

Однако, потому что ничего не стоит в одиночку, но, как правило, в окружении других частей памяти, я предполагаю, что это случилось выглядеть следующим образом:

____ << defined size 
XXXX00000000000... 
^ ^
| \you were lucky that those null bytes were around 
\this part you actually allocated 

Но вы не должны полагаться на это. Это, возможно, также выглядел так:

____ << defined size 
XXXXgarbage... 

... тогда бы напечатали XXXXgarbage вместо просто XXXX. Или:

____ << defined size 
XXXX| << here the memory block actually ends 

... тогда он потерпел бы крах, пытаясь распечатать его.

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

resultsIndex = (char *)malloc(sizeof(char) * (INDEX + 1)); 
for(i = 0; i < INDEX; i++){ 
    resultsIndex[i] = binary[i]; 
} 
resultsIndex[INDEX] = 0; // string terminator 

OK Теперь назад к resultsTag. В моем примере выше (и похоже, что вы делаете это аналогично), моя константа TAG была определена как 10, которая представляет собой в основном длину части перед тегом (индекс: 4) и сам тег (6).Но сам тег всего 6 символов (= TAG - INDEX).

На данный момент, вы делаете это (я удалил некоторые вещи для ясности):

resultsTag = (char *)malloc(sizeof(char) * TAG); 
for(t = INDEX; t < TAG + 1; t++){ 
    resultsTag[t] = binary[t]; 
    printf("resultsTag[i] %c\n", resultsTag[t]); 
} 

Что он делает:

  • Предоставлять TAG (10 в моем примере) байт результата строка.
  • Петля от INDEX (4 в моем примере) до TAG + 1 (11) исключительно, то есть TAG включительно (10), так что фактически один символ после конца тега.
    Таким образом, переменная t будет получать значения 4..5..6..7..8..9..10 во время цикла.
    Фактически это копирует данные с позиций 4-10 в binaryв положения 4-10 в resultsTag.

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

__________ << defined size 
????YYYYYYZ 
^ ^ ^
| |  \this is actually written outside of the allocated block of memory 
| \this are the 6 characters of the tag you copied 
\you never wrote to this part, so nobody knows what is there 

После моего предположения из ранее, что модули память выделения с помощью malloc является неявным заполняются нулями системы (которая, опять-таки , вы ничего не должны полагаться на), вполне вероятно, что она на самом деле выглядит следующим образом:

__________ << defined size 
0000YYYYYYZ 
^ ^ ^
| |  \this is actually written outside of the allocated block of memory 
| \this are the 6 characters of the tag you copied 
\zero values - remember that they act as string terminator! 

Так что же происходит, когда вы пытаетесь напечатать resultsTag? Система посмотрит на память и скажет: «Хорошо, давайте напечатаем». Что такое первый персонаж? ... О, терминатор строк уже? Ну, это было коротко! Нечего печатать! Доброй ночи.

И поэтому ничего не печатается, потому что ваша строка начинается с красного флага с надписью «string заканчивается здесь». : P

Так что это последняя часть имеет три проблемы:

  • Вы выделяющие неправильный объем памяти и начать запись в середине его, а не с самого начала.
  • Вы пишете за его пределами (из-за TAG + 1 в цикле).
  • Вы снова не завершаете строку.

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

resultsTag = (char *)malloc(sizeof(char) * (TAG - INDEX + 1)); 
for(t = INDEX; t < TAG; t++){ 
    resultsTag[t - INDEX] = binary[t]; 
    printf("resultsTag[i] %c\n", resultsTag[t - INDEX]); 
} 
resultsTag[TAG] = 0; // string terminator 

Для полноты картины, вот что он делает:

  • Выделяем память для длины тега только (не индекс плюс метки) , плюс 1 байт для ограничителя строк. В моем примере это будет 6 + 1 = 7 байт.
  • Петля из INDEX (4 в моем примере) до TAG (10) исключительно, т.е. TAG - 1 включительно (9), но мы не используем тот же индекс для источника и назначения копирования: Переменная t будет получить значения 4..5..6..7..8 ..9 во время цикла, но индекс назначения будет начинаться с 0, а не 4 в этот раз, и будет проходить через 0..1..2..3..4..5.
    Фактически, это копирует данные с позиций 4-9 в binaryв позиции 0-5 в resultsTag.

Так, resultsTag будет выглядеть следующим образом:

_______ << defined size 
YYYYYY0 

Это, вероятно, будет немного менее запутанным, если TAG не были определены как «длина индекса плюс длина тега», но так же, как длина тега, потому что тогда расчеты были проще и более очевидным, но я оставлю это упражнение;)


можно увидеть несколько других проблем с вашим кодом тоже:

1) Вы пропускаете память, потому что resultsIndex не освобожден (т. free(resultsIndex); resultsIndex = NULL;) после окончания использования. Если вы действительно хотите получить только тег (как предлагает название функции getTag), вам не нужна вся часть с resultsIndex, хотя ... Я не знаю, что вы делаете со значением resultsTag после возвращения это, но вы должны убедиться, что вызывающий и освобождает его!

2) Собственно, binary пахнет другой утечкой памяти. Как hex2bin выделяет память для возвращаемой строки? Если это также просто malloc и нет никакого управления магией памяти, вам нужно будет использовать free(binary); в конце.

3) i = 0; является сверхтекучим, потому что вы устанавливаете его на ноль на две линии ниже этого.

-1

Вы должны очистить стандартный вывод, или добавить \ п (стандартный вывод AutoFlush на новой линии)

printf("Tag Bit %s\n", resultsTag); //<-----Won't print the string 

fflush (stdout); 
+0

А также вам нужно оканчивать нулевой результат resultTag string –

0

Прежде всего вы доступ к вашему resultTag таНоса-ованному массиву из границ из-за состояние: t < TAG + 1; Вы должны зациклиться до TAG-1, чтобы оставить место для нулевого терминатора. Или malloc TAG+1 байт.

Во-вторых, вы должны добавить нулевой ограничитель в свою строку, чтобы сделать его C-String.

resultsTag = malloc(sizeof(char) * TAG+1); 
    for(t = INDEX; t < TAG; t++) 
    { 
     resultsTag[t] = binary[t]; 
     printf("binary[i] %c\n", binary[t]); 
     printf("resultsTag[i] %c\n", resultsTag[t]); //<----prints individual character 
    } 

    resultsTag[t] = '\0'; 

Те же соображения resultsIndex

resultsIndex = (char *)malloc(sizeof(char) * INDEX+1); 
    for(i = 0; i < INDEX; i++){ 
    resultsIndex[i] = binary[i]; 
    } 
    resultsIndex[i] = '\0'; 

Как Клиффорд указывает цикл начать заполнение вашей строки из INDEX, то вы должны напечатать строку, начиная с этого смещения.

printf("Tag Bit %s\n", &resultsTag[INDEX]); 

или изменить назначение внутри цикла:

resultsTag[t-INDEX] = binary[t]; 

Кроме того, вы должны быть уверены, что все значения указываемые binary являются ASCII.

1

Вы пишете resultTag, начиная со смещения INDEX, но попытайтесь распечатать его из начального запуска. Если в начале есть ноль, оно ничего не печатает.

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

+0

Хороший улов. Я этого не видел. – LPs

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