printf()不会在c中打印字符串

时间:2016-04-28 07:33:33

标签: c

我正在尝试在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循环可能导致错误吗?

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

4 个答案:

答案 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个)字符。
  • 从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

现在回到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

为了完整起见,这就是它的作用:

  • 仅为标记长度分配内存(不是索引加标记),加上字符串终止符的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未被定义为&#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);
相关问题