2014-02-23 138 views
1

我試圖通過C編程語言書籍和即時通訊練習1-21,在那裏你必須用適當數量的製表符和空格替換空格的塊,以等於相同的空間,我能夠讓所有的東西都能正確運行和編譯,但它會在輸出中輸入錯誤的製表符和空格。練習1-21 C編程語言

從本書中的實際問題:

寫一個程序entab由最低 號標籤和空白的空格替換字符串來實現相同的間距。與detab一樣使用相同的 製表位。當選項卡或單個空白 就足以達到製表位,哪個應該給予優先?

再次,夥計們對編程仍然很陌生,所以請儘可能描述一下。

if I input something like asdf  asdf  asdf 
i get something like----- asdf    asdf    asdf back out. 

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#define MAX_BUFFER 1024 
#define SPACE  ' ' 
#define TAB   '\t' 
#define TabSize 4 


int main() 
{ 
    int c, i, j, spaces = 0, size, tempspaces, x, y, z; 
    int tabs = 0; 
    char arrayPrimary[MAX_BUFFER]; 
    char arraySecondary[MAX_BUFFER]; 
/* ********************************************************************** */  
    for(i = 0;(c = getchar()) != EOF && c != '\n'; i++) 
    { 
     arrayPrimary[i] = c; 
    } 
    arrayPrimary[i] = '\0'; 
    size = i; 
    printf("%s\n", arrayPrimary); 
/* ********************************************************************** */  
    for(i = 0, j = 0, tempspaces = 0; i < size; i++) 
    { 
     if(arrayPrimary[i] == SPACE) 
     { 
      tempspaces++; 
     } 
     else 
     { 
      arraySecondary[j] = arrayPrimary[i]; 
      j++; 
     } 
     if(tempspaces > 0 && arrayPrimary[i + 1] != SPACE) 
     { 
      spaces = tempspaces % TabSize; 
      printf("Spaces %i\n", spaces); 
      tabs = ((tempspaces - spaces)/TabSize); 
      printf("Tabs %i\n", tabs); 
      for(y = 0; y <= spaces; y++) 
      { 
        arraySecondary[j] = SPACE; 
        j++; 
      } 
      for(x = 0; x <= tabs; x++) 
      { 
       arraySecondary[j] = TAB; 
       j++; 
      } 
      tabs = 0; 
      spaces = 0; 
      tempspaces = 0; 
     } 

    } 
    arraySecondary[j + 1] = '\0'; 
    printf("%s\n", arraySecondary); 
    return 0; 
} 
+0

您在示例輸入中說「類似」。這些是_exact_輸入和輸出,還是你只是輸入「類似」他們?你如何查看輸出結果?大多數終端的標籤大小默認爲8,但您的代碼具有「TabSize 4」。 – Arkku

回答

1

在每次你要插入一個額外的空間和一個額外的標籤最起碼:

 for(y = 0; y <= spaces; y++) 

     for(x = 0; x <= tabs; x++) 

這些環路的兩個從0到的空格/製表符,即號碼,如果你每個有1個,循環將運行兩次(0 <= 1,1 <= 1)。從條件中刪除=

其次,大多數終端和編輯器不只是治療選項卡作爲等於一定數量的空間,而是標籤是可變寬度的,取光標移到下一個標籤停止。因此,例如,如果製表符停止四個空格分開,則字符串"123\tx""\tx"都會導致x以第4列中的同一製表符結束 - 第一個製表符相當於一個空格,而第二個製表符相當於四個空格......您的程序沒有考慮到這一點。

要正確實現製表位,您需要跟蹤當前列 - 該位置的製表符寬度將爲TabSize - (column % TabSize)

它看起來也像你對我不終止arraySecondary正確:

arraySecondary[j + 1] = '\0'; 

你總是分配給循環內的數組後增加j,所以這應該是

arraySecondary[j] = '\0'; 

另外爲此,請確保程序中定義的TabSize與您運行程序的終端的標籤大小相匹配,否則即使程序正確,輸出也不會在視覺上匹配。

+0

謝謝你,我有<=在那裏因爲我試圖解決它爲什麼不工作,但謝謝你幫助我。 – Endon55

0

針對解決這個問題的算法。開始。

定義標籤大小。創建並清空'輸入'數組和'輸出'數組。根據需要初始化數組和其他變量的索引變量。

首先,將整個輸入行收集到一個名爲'input'的數組中。然後,從「輸入」開始,讀取每個字符直到數組結束,並檢查它是否是「空格」字符。如果它不是'空格'字符,請將其複製到'輸出'數組中並繼續下一個字符。如果它是一個'空格'字符,那麼請記住我們找到'空格'的'輸入'中的索引,併爲任何連續的'空格'字符向前看'輸入',併爲我們遇到的每個'空格'字符增加一個計數器。當我們到達下一個非空間字符時,檢查我們剛剛讀取的「空格」字符數是否大於製表符大小。如果它大於製表符大小,則調用一個函數來獲取空格的數量,作爲製表符和空格的組合,並等於空格的數量並插入'輸出'中。如果它不大於標籤大小,那麼我們不能放置'tab'字符,所以我們只需將所有空格複製到'output'中。如果我們能夠調用entab函數,我們需要從我們已經記住的索引中恢復讀取'輸入',但是我們必須通過將我們遇到的'空格'字符的數目添加到記憶索引來跳過所有空格。

entab函數將不得不計算可以組合以實現實際間距的製表符和空格的數量。我們使用下面提到的公式計算到下一個製表符的距離:

x = tabSize - (currentInputIndex mod tabSize);

如果上述結果不爲零,那麼我們距離下一個製表符x個字符。現在插入一個'標籤'。然後通過從原始空間數中減去x來重新計算剩餘空間數。重新計算使用下面提到的公式所需的製表符和空格的數量:

nTabs = spacesRemaining/tabSize; nSpaces = spacesRemaining mod tabSize;

將nTabs'tab'和nSpaces'space'字符按順序插入到'output'中。 entab函數應該將輸出數組中的索引返回到主程序,以便它可以繼續處理輸入數組的其餘部分。