0

可能重复:
“while(!feof(file))”总是错误的

我有一个与 while 循环有关的奇怪问题。我有一个函数,它在进程的父进程 () 结束时调用,print_file()它不接受继续执行的真实条件。这是我的简单多进程代码,如下所示。

#include <stdio.h>     /* basic I/O routines.   */
#include <stdlib.h>
#include <unistd.h>    /* define fork(), etc.   */
#include <sys/types.h> /* define pid_t, etc.    */
#include <sys/wait.h>  /* define wait(), etc.   */
#include <signal.h>    /* define signal(), etc. */
#include <pthread.h>
#include <time.h>
#include <ctype.h>

void print_file(char* [], char* []);
void child_process(int,int);
void parent_process();
int counter=0;

int main(int argc, char* argv[]) {

    counter = atoi(argv[1]);
    int i,k;
    pid_t child_pid;
    int child_status;
    char* array[counter];
    srand ( time(NULL) );
    int temp;

    for(i=0; i<counter; i++){
        temp = rand()%4;
        child_pid = fork();

        switch(child_pid) {
            case -1:
                printf("Error occured with fork()\n");
                exit(1);
            case 0: 
                child_process(i,temp); /* Child Process */
                exit(0);
        }
    }

    wait(&child_status);
    parent_process();
    execl("/usr/bin/killall","killall","tail",(char *) 0);
    return 0;
}

void child_process(int i,int temp){

    FILE* fptr;
    fptr = fopen("sample.txt","a+");
    if( temp==0 ) {
        fprintf(fptr,"A %d\n",i);
    }
    else if( temp==1 ) {
        fprintf(fptr,"C %d\n",i);
    }
    else if( temp==2 ) {
        fprintf(fptr,"G %d\n",i);
    }
    else if( temp==3 ) {
        fprintf(fptr,"T %d\n",i);
    }
    fflush(fptr);
    sleep(1);
    fclose(fptr);
}

void parent_process(void){

    FILE* fptr;
    fptr = fopen("sample.txt","r");
    char* str = (char*)malloc(1);
    int temp,i,k;
    char* array_opst[counter];
    char* array[counter];

    i=0;
    while(!feof(fptr)){

        fscanf(fptr,"%s%d",str,&temp);
        if(feof(fptr))
            break;

        if(strcmp(str,"A")==0){
            array[temp]="A";
            array_opst[temp]="T";
            printf("Array[%d] = %s\n",temp,array[temp]);
        }
        else if(strcmp(str,"C")==0){
            array[temp]="C";
            array_opst[temp]="G";
            printf("Array[%d] = %s\n",temp,array[temp]);
        }
        else if(strcmp(str,"G")==0){
            array[temp]="G";
            array_opst[temp]="C";
            printf("Array[%d] = %s\n",temp,array[temp]);
        }
        else if(strcmp(str,"T")==0){
            array[temp]="T";
            array_opst[temp]="A";
            printf("Array[%d] = %s\n",temp,array[temp]);
        }
        i++;
    }
    fclose(fptr);
    free(str);
    print_file(array,array_opst);
}

void print_file(char* array[counter], char* array_opst[counter]) {

    int j=0,i=1;

    while(j<counter){
        printf("%d", i);
        i++;
        j++;
        if(i==10){
            i=0;
        }
    }
    return;
}

print_file函数中,即使满足条件,它也永远不会进入 while 循环。但是每当我将 printf 放在函数的第一行print_file以检查它是否成功输入时,它就会打印出来。(注意这counter是一个全局变量)。是什么导致了这个问题?

4

1 回答 1

5

由于stdout被缓冲(printf()循环内的语句包含 no\n且未stdout显式d)和对infflush()的调用,循环的输出没有出现,它替换了当前进程映像,并且缓冲区在正常程序退出时不会像往常一样刷新. 在循环之后向or 显式调用添加换行符。execl()main()stdoutprintf()fflush(stdout);


存在缓冲区溢出,导致未定义的行为:

char* str = (char*)malloc(1);

分配 1 个字节,str然后这样使用:

fscanf(fptr,"%s%d",str,&temp);

fscanf()str即使只char读取一个,也会添加一个超出结尾的空终止符。我看不到动态分配它的原因,甚至当它需要是一个数组时,因为行的格式似乎是一个char后跟一个int

fprintf(fptr,"A %d\n",i);

要解决此问题,只需使用 achar和格式说明符%c

char ch;

if (2 == fscanf(fptr, "%c%d", &ch, &temp))
{
}

始终检查返回值(fopen()、、fprintf()fscanf())。

于 2012-10-10T21:26:56.530 回答