2013-10-27 32 views
1

我正在編寫一個簡單的Linux程序。我有一個函數「addonlyonce」的問題。它比較字符串並將其添加到數組而不會重複(如果字符串不存在於數組中)。該函數運行良好,但不適用於utmp結構。當比較utmp文件中每一個串始終返回1(這意味着字符串已經存在數組中 - 這是錯誤的:()。你可以通過gcc thiscode.c -o test編譯這段代碼(它只能在Linux上)Linux登錄和strcmp

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

int addonlyonce(char **array, char *str) { 
    int i=0; 
    printf("I got %s\n",str); 
    while(*array != '\0') { 
     if(strcmp(*array,str)==0) { 
      printf("Already exists!\n"); 
      return 1; 
     } 
     i++; 
     array++; 
    } 
    *array=str; 
    printf("Sit down on the number: %d\n",i); 
    return 0; 
} 

void printarray(char **array) { 
    printf("Array looks like: "); 
    while(*array != '\0') { 
     printf("%s ",*array); 
     array++; 
    } 
    printf("\n"); 
} 

int main(void) { 
    char *users[20]={0}; 
     char exuser2[]="exuser2"; 
    struct utmp current_record; 
    FILE *fp = fopen(UTMP_FILE, "r"); 

    addonlyonce(users,"exuser1"); 
    printarray(users); 
    addonlyonce(users,exuser2); 
    printarray(users); 
    addonlyonce(users,"exuser1"); 
    printarray(users); 
    addonlyonce(users,"exuser3"); 
    printarray(users); 
    while (fread(&current_record, sizeof(struct utmp), 1, fp) == 1) { 
     addonlyonce(users,current_record.ut_name); //HERE DON'T WORK 
     printarray(users); 
    } 
    addonlyonce(users,"exuser4"); 
    printarray(users); 
    fclose(fp); 
    return 0; 
} 

我想讓它這樣(正常功能):

I got exuser1 
Sit down on the number: 0 
Array looks like: exuser1 
I got exuser2 
Sit down on the number: 1 
Array looks like: exuser1 exuser2 
I got exuser1 
Already exists! 
Array looks like: exuser1 exuser2 
I got exuser3 
Sit down on the number: 2 
Array looks like: exuser1 exuser2 exuser3 
I got reboot 
Sit down on the number: 3 
Array looks like: exuser1 exuser2 exuser3 reboot 
I got kelloco2 
Sit down on the number: 4 
Array looks like: exuser1 exuser2 exuser3 reboot kelloco2 
I got przemek 
Sit down on the number: 5 
Array looks like: exuser1 exuser2 exuser3 reboot kelloco2 przemek 
I got guest 
Sit down on the number: 6 
Array looks like: exuser1 exuser2 exuser3 reboot kelloco2 przemek guest 
I got exuser4 
Sit down on the number: 7 
Array looks like: exuser1 exuser2 exuser3 reboot kelloco2 przemek guest exuser4 

但是,後執行的我得到這樣的:

I got exuser1 
Sit down on the number: 0 
Array looks like: exuser1 
I got exuser2 
Sit down on the number: 1 
Array looks like: exuser1 exuser2 
I got exuser1 
Already exists! 
Array looks like: exuser1 exuser2 
I got exuser3 
Sit down on the number: 2 
Array looks like: exuser1 exuser2 exuser3 
I got reboot 
Sit down on the number: 3 
Array looks like: exuser1 exuser2 exuser3 reboot 
I got kelloco2 
Already exists! //Here a problem arises 
Array looks like: exuser1 exuser2 exuser3 kelloco2 
I got przemek 
Already exists! 
Array looks like: exuser1 exuser2 exuser3 przemek 
I got guest 
Already exists! 
Array looks like: exuser1 exuser2 exuser3 guest 
I got exuser4 
Sit down on the number: 4 
Array looks like: exuser1 exuser2 exuser3 guest exuser4 

enter image description here

什麼可能是錯誤的? 問候K.

+0

您是否打開了編譯器警告?我看到一些問題......雖然它們可能不會導致你所看到的問題。無論如何,你應該清理它們。 –

+0

我用-Wall編譯,但沒有警告;/ –

+0

我在看這個:「while(* array!='\ 0')」這是醜陋的,但我猜'0'在這種情況下與0相同。儘管如此,將char *與char相比似乎並不正確。但不是你的問題。 –

回答

5

沒有看過所有的代碼,但這個錯誤我:

while(*array != '\0') { 

陣列是一個**char。這意味着*數組是一個*char。但是你將它與char('\0')進行比較。你可能意思是NULL

現在到你的錯誤:

*array=str; 

這是壞線。你沒有複製字符串!你只是指着記憶中的同一個地方!

這意味着如果更改str指向的字符串,*array指向的字符串也將更改!

所以一旦你使用ut_name一個字符串,然後改變ut_name,然後重新添加添加 - 它發現它已經,因爲你有ut_name*array相同的內存。

無論如何 - 使用strcpy(分配內存後!!!),而不是該行*array=str,一切都會正常工作。

+0

是的,即將發佈。 –

+1

「..使用strcpy(分配內存後!!!)..」 - 「strdup」呢? – usr2564301