2016-04-28 181 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; 
} 

我试着用搜索引擎的问题,并尝试了一些方法。一个可以使resultsTag [t] ='\ 0'。我试过了,它不会打印。我的循环可能会导致这个问题吗?

它在循环内打印单个字符,所以我可以看到它正在存储它,但不会将它打印到循环外部。任何可能有用的建议?

+2

这可能是因为没有空字符。尝试添加resultsTag [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。这意味着它会将binary中位置0-3的所有字符复制到resultsIndex中的位置0-3。

这一部分之后,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),即包含(10)的TAG环,实际上在标签结束后一个字符。
    因此,变量t将在循环中得到值4..5..6..7..8..9..10。
    实际上,这将数据从binary中的位置4-10复制到resultsTag中的位置4-10。

最后一部分是它不打印的原因(但这不是您代码中的唯一问题)。这个循环之后,存储器,开始在那里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分配内存是隐含由系统以0字节(再次,什么是你应该依靠),很可能,它实际上是这样的:

当您尝试打印 resultsTag
__________ << 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! 

所以会发生什么?系统会查看内存并说:好的,让我们打印一下。第一个角色是什么? ...哦,一个字符串终结者已经?那很简单!没什么可打印的!晚安。

所以没有打印出来,因为你的字符串以红色标志开头,说“字符串在这里结束”。 :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。
    实际上,这将数据从binary中的4-9位的数据复制到resultsTag中的位置0-5。

所以,resultsTag看起来就像这样:

_______ << defined size 
YYYYYY0 

它可能会少一点混乱,如果TAG没有定义为“索引加上标签的长度的长度”,但只是作为长度标签的,因为这样的计算是更简单,更明显,但我会离开,作为一个练习;)


我可以看到其他一些问题与您的代码太:

1)您正在泄漏内存,因为resultsIndex未被释放(即,你完成使用后,如果你真的只想得到标签(因为功能名称getTag建议),你根本不需要整个部分resultsIndex,虽然...我不知道你在返回后的值为resultsTag它,但你必须确保调用者也可以释放它!

2)实际上,binary闻起来像是另一个内存泄漏。 hex2bin如何为返回的字符串分配内存?如果它也只是malloc,并且没有魔法内存管理,那么最终还需要使用free(binary);

3)i = 0;是超级的,因为您将它设置为零以下两行。

-1

您需要刷新标准输出,或添加\ n(新行标准输出自动冲洗)

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

fflush (stdout); 
+0

而且,您还需要零结束resultTag字符串 –

0

所有要访问您的resultTag的malloc-ated阵列出因病情界的第一:t < TAG + 1;您必须循环,直到TAG-1为空终止符留出空间。或者malloc TAG+1字节。

其次,您必须在您的字符串中添加空终止符以使其成为C字符串。

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

你从INDEX开始写入resultTag,但试图从初始化开始打印。如果开始包含零,它将不会打印任何内容。

此外,最终打印不会以换行结束,并且输出流不会刷新,因此不会立即在某些系统上显示。

+0

好的结果。我没有看到它。 – LPs