2016-04-28 87 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