2012-09-25 86 views
0
void getS(char *fileName){ 
    FILE *src; 
    if((src = fopen(fileName, "r")) == NULL){ 
     printf("%s %s %s", "Cannot open file ", fileName, ". The program is now ending."); 
     exit(-1); 
    } 
    //char *get = " ";  

    int c = 1; 
    char ch = 'x'; 
    while(ch!=EOF) { 
     ch = fgetc(src); 
     if(ch == '\n') c++; 
    } 
    fseek(src, 0, SEEK_SET); 
    int random = rand() % c; 
    int i = 0; 
    for(i = 0; i < random; i++){ 
     while(ch != '\n'){ 
      ch = fgetc(src); 
     } 
    } 
    do{ 
     ch = fgetc(src); 
     if(ch != '\n' && ch != EOF){ 
      printf("%c", ch); 
     } 
    }while(ch != '\n' && ch != EOF); 
    printf("%c", '\n'); 
    fclose(src); 
} 

所以這是我的職責,抓住一個文件,並在文件中打印出一個隨機單詞,如果每個字是由新線分離。Ç隨機的,有問題

問題1: 爲什麼隨機偏好前兩個單詞?

問題2:我怎樣才能讓它可以多次使用這個函數而不用做printf(「%c」,'\ n');因爲如果我最終沒有那個函數調用,就會覆蓋舊的調用函數。

在此先感謝,我一直在問今天謝謝所有幫助stackoverflow! :)

P.S.使用srand(time(NULL));

+0

的''%運營商總是有一些偏差,除非可能的隨機值的數量是整除,儘管這可能不是一個顯著的問題。但是,避免需要通過文件兩次傳遞是個巧妙的技巧。當你找到第一個詞時,你有100%的選擇機會。當你找到第二個單詞時,你有一個1比2的選擇機會。當你找到第三個詞時,你有三分之一的選擇機會,等等。您需要生成大量的隨機數字,但通常比通過文件兩次更便宜。 – Steve314

+0

你可能需要仔細檢查一下這個概率是否合適,但是,是的,它確實在最後選擇了具有相同概率的任何單詞。最近有一篇博客文章提到了這一點,但我失去了鏈接。 – Steve314

+0

您可以使用'putchar(ch)'而不是'printf(「%c」,ch)'......它更清晰更快速。 –

回答

2

看看這裏的邏輯:

for(i = 0; i < random; i++){ 
     while(ch != '\n'){ 
      ch = fgetc(src); 
     } 
    } 

一旦你打一個換行符,你將無法讀取任何更多的字符,所以你總是要打印的第一或第二線。

你能解決這個問題是這樣的:

for(i = 0; i < random; i++){ 
     ch = fgetc(src); // start by reading the first character on the line 
     while(ch != '\n'){ 
      ch = fgetc(src); 
     } 
    } 

吉姆·巴爾特也指出,CH將最被宣佈爲一個int。這是因爲EOF不被認爲是常規字符。

+0

我很困惑什麼回車是確切的。它是'\ r'嗎?究竟是如何造成的? –

+0

哦,我想我明白了,但我怎麼會不讀回車,所以它不會在文件開始時重新開始? –

+0

@OstapHnatyuk:我不知道你是什麼意思,「所以它不會讓我回到文件的開頭。」只有fseek()會導致它從文件的開始處開始。 –

0

沒有它工作正常結束printf("%c","\n");線...