2011-09-29 14 views
1

我正在處理一個字符串,其中每個單詞由空格分隔。 <表示它是輸入重定向,並且>表示它是輸出重定向。 例如:在C中,一次保存一個字符

<Hello> World 

我想保存在不同的變量的話(的char *中,燒焦*總分) 我怎麼能這樣做?我查看了字符串庫,似乎沒有人能夠完成這項工作。

這是我迄今爲止關於這個問題。

char buff[MAXARGS]; 
char *str; 
char *in; 
char *out; 

if(strchr(buff, '<') != NULL) 
{ 
    str = strchr(buff, '<'); 
    str++; 
    if(*str == ' ' || *str == '\0' || *str == '\n' || *str == '\t') 
    { 
    fprintf(stdout, "User did not specify file name!\n"); 
    } 
    else 
     in = str; // This will save Hello > World all together. I don't want that. 
} 

非常感謝。

+0

你在** **真的想要做什麼?如果它「解析命令行」,那麼處理輸入和輸出重定向已經由shell進程完成。如果你正在嘗試閱讀和解析一個shell腳本或類似的東西,那麼C可能是實現語言最糟糕的選擇。 –

+0

謝謝你的回覆! 是的,我正在寫一個簡化的shell程序,這是我的parse.c的一部分。真的嗎?因爲我的程序除了輸入,輸出重定向和背景外,還能完美地執行所有其他命令(例如:ls,exit,cat)。因此,我爲了解決這三個問題而增加了額外的功能。 – Dino55

+0

@Karl,但最快...... – YAHOOOOO

回答

0

爲了讓您一開始,這裏是你如何能做到這一點假設你被允許修改buff,假設一個簡單的情況下(至多一個<和最多一個>)。

首先,得到的<>

in = strchr(buff, '<'); 
out = strchr(buff, '>'); 

的位置,然後你人爲地分割字符串:

if (in) { 
    *in = 0; 
    in++; 
} 
if (out) { 
    *out = 0; 
    out++; 
} 

在這一點上,buff指向沒有一個C結尾的字符串<>in要麼是null,要麼指向跟在<之後的字符串,並且不包含>out相同。

然後,您需要「去掉」所有這些字符串(刪除空格),然後檢查它們是否仍包含有意義的數據。

您需要更多邏輯才能正確使用所有案例,包括拒絕無效輸入。

+0

謝謝你的回覆! 但是,我不確定你爲什麼設置爲0? (* in = 0; and * out = 0;) – Dino55

+0

用0代替'<',這會終止字符串。如果'buff'是'hello output \ 0',那麼它會是'hello \ 0input \ 0output \ 0'。所以如果你在'buff'上使用字符串函數,它看起來好像只包含'hello'。 'in ++'將是C字符串'input'。 – Mat

0

u可以使用這個..

char filename[max_path] 
str1 = strchr(buff, '<'); 
str2 = strchr(buff, '>'); 

memcpy(filename , str1+1 , str2-str1-1); 

所以<之間的路徑>將是文件名。

output = str2 + 1; 
+0

謝謝你的回覆:)但是,該字符串將由用戶輸入,所以無法保證他們輸入的字符串看起來像我的例子.. – Dino55

0

假設你輸入圖案固定爲<input_name> output_name,你希望能夠分別提取input_nameoutput_name

一個解決方案是使用「<>」分割str。以下代碼將連續打印出Hello,World。將它們保存到inout是留給你作爲一個練習:)

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

int main() 
{ 
    char str[] ="<Hello> World"; 
    char *in; 
    char *out; 
    char *pch; 
    char *del=" <>"; 
    pch = strtok (str,del); 
    while (pch != NULL) 
    { 
    printf ("%s\n",pch); 
    pch = strtok (NULL, del); 
    } 
    return 0; 
} 
+0

如果輸入模式不固定?我正在考慮檢查,而不是指向一個空白空間,複製到字符數組的字符。也許使用for循環讓它按索引增加。但是我找不到一個能夠一次複製char的函數?謝謝! – Dino55

0

您需要決定分配兩個文件名的存儲位置,以及如何知道提供了多少存儲空間。

static void find_filename(const char *str, char *name) 
{ 
    char c; 
    while ((c = *str++) != '\0' && isspace((unsigned char)c)) 
     ; 
    if (c != '\0') 
    { 
     *name++ = c; 
     while ((c = *str++) != '\0' && !isspace((unsigned char)c)) 
      *name++ = c; 
    } 
} 

int find_io_redirection(const char *str, char *in, char *out) 
{ 
    const char *lt = strchr(str, '<'); 
    const char *gt = strchr(str, '>'); 
    if (lt != 0) 
     find_filename(lt+1, in); 
    if (gt != 0) 
     find_filename(gt+1, out); 
    return(lt != 0 && gt != 0); 
} 

此代碼簡單地假設你inout提供足夠大的字符串。如果你想要更安全,那麼你告訴函數每個目標字符串有多大。您可以壓縮該代碼。您可能會決定要返回重定向次數。你可能會決定你應該知道雙輸出重定向,或雙輸入重定向。你可能會決定你應該返回一個指示哪些重定向出現的掩碼。有了相當複雜的接口,您可能能夠指示輸入線的哪些部分表示I/O重定向;這將有助於調用函數確定現在應忽略哪一部分行。

你會使用上面的代碼是這樣的:

char buffer[MAXCMDLEN]; 
char in[MAXFILENAMELEN]; 
char out[MAXFILENAMELEN]; 

if (fgets(buffer, sizeof(buffer), stdin) != 0) 
{ 
    if (find_io_redirection(buffer, in, out)) 
     ...process buffer know that I/O redirection is present... 
    else 
     ...witter about missing I/O redirection... 
} 
+0

哇!非常感謝你的回覆!我從來不知道有一個內置函數叫做isspace()!這應該派上用場:)當我回家時,我將不得不嘗試你的方式。 – Dino55

+0

'isspace()'是來自''的宏/函數。與'isblank()'函數相比,它們接受不同的字符集。你可能會認爲'isblank()'比'isspace()'好。 –

相關問題