2012-09-25 70 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");线...