我正在尝试在for循环后打印一个char数组以查看输出以确保它是正确的。但是,它不会打印字符串。为什么不打印字符串?我错过了什么吗?它打印索引println字符串,但不打印Tag位。我错过了什么?
这是我的代码
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;
}
我尝试使用Google搜索问题并尝试了一些方法。一个做结果标签[t] ='\ 0'。我试过了,它不会打印出来。我的for循环可能导致错误吗?
它打印循环中的单个字符,因此我可以看到它正在存储它但它不会在循环外打印它。任何可能有用的建议?
答案 0 :(得分:2)
您从偏移resultTag
开始写入INDEX
,但尝试从初始化开始打印它。如果开始恰好包含零,它将不会打印任何内容。
此外,最终打印不会以换行符结束,并且输出流不会被刷新,因此不会立即显示在某些系统上。
答案 1 :(得分: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个)字符。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
现在回到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。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
分配的内存被系统隐含地填充零字节(这也是你应该依赖的任何东西),它实际上可能看起来像这样:
__________ << 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
时会发生什么?系统会查看内存并说:好的,让我们打印一下。第一个角色是什么? ...哦,已经是一个字符串终止符?那很短暂!什么都没打印!晚安。
所以没有任何内容被打印,因为你的字符串以红色标记开头说&#34;字符串在这里结束&#34;。 :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
为了完整起见,这就是它的作用:
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
未被定义为&#34;索引的长度加上标签的长度,那么可能会有点混乱。但就像标签的长度一样,因为那时计算更简单,更明显,但我将其留作练习;)
我也可以看到代码的其他几个问题:
1)您正在泄漏内存,因为resultsIndex
在您使用完之后未被释放(即free(resultsIndex); resultsIndex = NULL;
)。如果你真的只想获得标签(正如函数名getTag
所暗示的那样),那么你根本不需要resultsIndex
整个部分,但是......我不会这样做。在返回之后知道你对resultsTag
的值做了什么,但你必须确保调用者也释放它!
2)实际上,binary
闻起来像另一个内存泄漏。 hex2bin
如何为它返回的字符串分配内存?如果它也只是malloc
并且没有神奇的内存管理,那么你最后也需要使用free(binary);
。
3)i = 0;
是超级的,因为你也将它设置为零以下两行。
答案 2 :(得分:0)
首先,由于条件,您正在访问resultTag
malloc-ated数组超出界限:t < TAG + 1;
您必须循环直到TAG-1
为空终止符留出空间。或malloc TAG+1
字节。
其次,必须在字符串中添加一个null终止符,使其成为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';
当Clifford指出循环开始从INDEX
填充你的字符串时,你必须从该偏移量开始打印字符串。
printf("Tag Bit %s\n", &resultsTag[INDEX]);
或更改循环内的分配:
resultsTag[t-INDEX] = binary[t];
此外,您必须确保binary
指向的所有值都是ASCII。
答案 3 :(得分:-1)
你需要刷新标准输出,或者添加\ n(stdout autoflush在新行上)
printf("Tag Bit %s\n", resultsTag); //<-----Won't print the string
fflush (stdout);