2014-09-27 23 views
-1

我基本上想從stdin中取一行輸入,抓住'strings'(一個由空格分隔的char數組),然後將每個'string'放入數組中的char []。我已經嘗試過使用fgets,getline和strtok;我不想使用外部庫或任何Unix不可用的東西。我在這裏看到很多類似的問題,所以我很抱歉如果這個問題已經得到解答,但是我找不到一個簡單明瞭的方法來做到這一點。C Unix - 解析一行字符

謝謝,我很抱歉,如果我錯誤地稱爲什麼,我非常不習慣C.

編輯:好了,這裏就是我試過最近:

#include <string.h> 
#include <stdio.h> 

int main() { 
const char str[80] = "This is a | test"; 
const char s[2] = " "; 
char *token; 
char arguments[10][50]; 
int i = 0; 

/* get the first token */ 
token = strtok(str, s); 

/* walk through other tokens */ 
while(token != NULL) 
{ 
    printf(" %s\n", token); 
    arguments[i] = token; 
    i++; 
    token = strtok(NULL, s); 
} 

return(0); 
} 

編輯:謝謝保羅,對同一個問題的人,因爲我有,我得到了它通過改變這行的工作:

arguments[i] = token; 

到:

strcpy(arguments[i], token); 
+1

顯示你的嘗試以及失敗的方式。 'fgets()'和'strtok()'或手動解析的組合是正常的方法,所以如果這不適合你,那麼讓它適合你是你應該做的,而不是尋找另一個辦法。 – 2014-09-27 18:27:51

+0

'arguments [i] = token;' - 你不能像這樣分配數組,你需要使用'strcpy()'。 'strtok()'修改你傳遞給它的字符串,所以你不應該使它成爲'const'。這是非常基本的,我想你需要多花一點時間學習C,然後在Stack Overflow上提出問題。 – 2014-09-27 18:44:23

+0

我認爲'argv'(在'int main(int argc,char * * argv);')可能正是你所需要的。請注意,設計程序以獲取參數作爲命令行參數比交互式查詢用戶通常更好。不幸的是,後者是大多數書籍和課程教給你的。 – 5gon12eder 2014-09-27 18:52:02

回答

1

將它分成以下步驟:

  • 首先,獲取使用getline(GNU擴展輸入的整個行;如果它不存在,請實現自己作爲一個循環周圍fgets

  • 接下來,執行換行標準化。有些應用程序會一直需要結尾的換行符;別人會希望它永遠不會; getline會給你有時,所以你需要強迫它(我建議刪除,因爲它只是一個NUL字節的條件分配,而不是有條件的realloc)。請注意,如果你想DTRT與回車(處理窗口和經典的mac文件 - 是的,仍然存在在野外 - 你需要編寫自己的功能,而不是getline

  • 在這一點上,您擁有包含整行的malloc ed字符串的所有權。我假設你想一次訪問所有參數(在一個數組中),而不是一次訪問所有參數,所以你需要分配一個足夠大的數組;通過對輸入進行早期傳遞來計算分隔符的數量(如果您使用提供數組作爲類的更高級語言來執行此操作,則通常會逐漸增量式地進行推送),這樣做通常很方便。 請勿使用像最常見的固定尺寸陣列。它永遠不會被接受,因爲它會導致真實世界中的安全漏洞。或者,如果您確切知道根據代碼預計有多少令牌,則可以準確分配多少令牌,並在出現太多或太少的情況時出錯。

  • 現在迭代字符串。我傾向於避免strtok,因爲它有許多問題,其中一些問題沒有通過strtok_r解決,因此請使用直接迭代進行自定義搜索(如果需要執行額外的預處理,例如反斜槓或引號處理,這很有用 - 可以在(用於單個字符;另請參閱strchrnul,以獲取更方便的GNU擴展)或strpbrk/strspn/strcspn(用於搜索任何字符集,例如空格或製表符(注意,請記住)或使用strchr那些baskslash /報價處理也可以用來完成,並且可能比手動循環更有效。但對於你通常花費時間解析的東西,可讀性遠比效率重要,所以重要的是你可以讀取的內容))

  • 對於每個單詞,將NUL存儲在分隔符的頂部並存儲指向數組開始的指針,然後跳過分隔符開始下一個單詞。如果你擊中輸入字符串的末尾而不是分隔符,請打破。

  • 最後寫一組測試用例。想到的一些重要情況是:空行,只有空格的行,在開始/結尾處有空格的行,與相鄰空格行對齊的行,只有一行的行,多行的行;用每個分隔符重複上述所有操作,並且不用每種形式的尾隨換行符。您可能會發現代碼中存在一些錯誤,因此返回並修復它。 (有些人主張編寫測試用例第一個,並且只是在必要時編寫代碼才能使測試通過,但我想你沒有掌握什麼樣的測試有助於發現錯誤,但是你會在編寫錯誤如果你想要一個有趣的實驗,試着在你的測試寫完之後刪除你的主源文件,然後看看你的測試套是否足以迫使你正確地重寫它;否則,你需要更多的測試。)