2017-03-05 93 views
1

對於教育用途,我試圖實現一個簡單的查找程序(類似於找到(1)功能少得多)。在實現第一個功能 - 「用戶」時 - 我通過將一個「控制函數?」與兩個不同的函數(一次用於uid,一次用於名稱)結合起來進行挑戰。我想我正在尋找類似於C#中的重載函數的東西,在C中解決這個問題的最佳實踐是什麼?c中的「超載」函數 - 不知道輸入參數類型

我希望解決的辦法,這使得我的程序來處理這兩個選項,而稱之爲: 如:

  • 「my_find - 用戶文森」 號
  • 「my_find -user 1000」

如果您在我的示例中發現了一些編碼或樣式問題,請將它們指出來,我願意學習!我意識到錯過了一些乾淨的內存管理,但會在稍後添加。

更新 我考慮它正在處理參數作爲一個字符數組並檢查每個字符爲其ASCII碼並調用該函數,如果沒有「CHAR」被發現的功能。有那樣的「合法」嗎?

#include <dirent.h> 
#include <stdio.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <pwd.h> 

void entries_with_uid(char *init_path, int pattern_uid); 
void entries_with_name(char *init_path, char *pattern_name); 

int main(int argc, char **argv) 
{ 
    /* 
    char *path = argv[1]; 
    */ 
    entries_with_name("/home/mario/Documents/codes", "mario"); 
    entries_with_uid("/home/mario/test_project", 1000); 
    return 0; 
} 

void entries_with_uid(char *init_path, int pattern_uid) 
{ 
    DIR *dir; 
    struct dirent *entry; 

    dir = opendir(init_path); 
    entry = readdir(dir); 

    if(dir == NULL) return; 
    if(entry == NULL) return; 

    do { 
     if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; 

     char path[1024]; 
     int len = snprintf(path, sizeof(path)-1, "%s/%s", init_path, entry->d_name); 

     path[len] = 0; 

     struct stat sb; 
     stat(path, &sb); 

     if(sb.st_uid == pattern_uid) printf("%s\n", path); 

     if (entry->d_type == DT_DIR) entries_with_uid(path, pattern_uid); 
    } while (entry = readdir(dir)); 

    closedir(dir); 
} 

void entries_with_name(char *init_path, char *pattern_name) 
{ 
    DIR *dir; 
    struct dirent *entry; 

    dir = opendir(init_path); 
    entry = readdir(dir); 

    if(dir == NULL) return; 
    if(entry == NULL) return; 

    do { 
     if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; 

     char path[1024]; 
     int len = snprintf(path, sizeof(path)-1, "%s/%s", init_path, entry->d_name); 

     path[len] = 0; 

     struct stat sb; 
     stat(path, &sb); 

     struct passwd *pwd = getpwuid(sb.st_uid); 

     if(strcmp(pwd->pw_name, pattern_name) == 0) printf("%s\n", path); 

     if (entry->d_type == DT_DIR) entries_with_name(path, pattern_name); 
    } while (entry = readdir(dir)); 

    closedir(dir); 
} 

謝謝!

更新

我與它的自變量中檢查的字母數字字符串的函數同時解決了這個問題:

int count_alphanumeric(char *string) 
{ 
    int alphanumeric_counter = 0; 
    int i = 0; 

    while(string[i]!='\0') 
    { 

    if (string[i] <= 57 && string[i] >= 48) 
    { 
     i++; 
     continue; 
    } 
    else alphanumeric_counter++; 
    i++; 
    } 
    return alphanumeric_counter; 
} 

還在尋找一個更優雅的選擇! ;)

Cheeers!

+0

2011版C標準增加了[通用選項](http://en.cppreference.com/w/c/language/generic)。所以人們可以編寫模擬重載函數的宏。不幸的是,這種行爲稍微[在指定的情況下](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1930.htm)。 – StoryTeller

+0

專業人士主要使用哪種最佳或最佳實踐? –

+0

那麼,如果你選擇接受一個'char *'並且在傳遞一個字符串時總是對其進行轉換(有點麻煩,但是便攜),那麼你可以避免含糊不清。 – StoryTeller

回答

1

您需要檢查用戶輸入的字符串是否爲數字。這與函數重載或任何這樣的語法糖無關。函數重載基於編譯時已知的類型,而不是用戶可以輸入的內容,因此不要尋找巧妙的方式來使用它。你目前的想法絕對沒問題。

然而,實施並非如此。 57是什麼?爲什麼有人應該記住ASCII表?字符常量用單引號寫入,例如'0'和'9'。爲什麼重新發明輪子?將其廢棄並使用適當的慣用C方式。

int is_numeric (const char* s, unsigned long* number_return) 
{ 
    char* endp; 
    *number_return = strtoul(s, &endp, 0); 
    return (*endp == '\0'); 
} 
+0

「正確的慣用C方式」就是我一直在尋找的!謝謝! –

相關問題