即使条件满足,代码也不会进入while循环

时间:2012-10-10 21:20:56

标签: c while-loop printf multiprocessing

  

可能重复:
  “while( !feof( file ) )” is always wrong

我有一个与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循环。但每当我在print_file函数的第一行放置printf以检查它是否成功输入它打印。 (注意counter是一个全局变量)。是什么导致这个问题?

1 个答案:

答案 0 :(得分:5)

由于stdout被缓冲,循环的输出没有出现(循环内的printf()语句不包含\nstdout未明确{{1} d)和fflush()execl()的调用,它取代了当前的过程映像,并且main()缓冲区在正常程序退出时不像往常一样被刷新。在stdout添加换行符或在循环后显式调用printf()


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

fflush(stdout);

分配1个字节,然后使用char* str = (char*)malloc(1);

str
即使只读取了一个fscanf(fptr,"%s%d",str,&temp);

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

int

要解决此问题,请改为使用fprintf(fptr,"A %d\n",i); 和格式说明符char

%c

始终检查返回值(char ch; if (2 == fscanf(fptr, "%c%d", &ch, &temp)) { } fopen()fprintf()等)。