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

标签 c while-loop printf multiprocessing

<分区>

Possible Duplicate:
“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 循环。但是每当我将 printf 放在 print_file 函数的第一行以检查它是否成功输入时,它就会打印出来。 (注意 counter 是一个全局变量)。是什么导致了这个问题?

最佳答案

由于 stdout 被缓冲,循环的输出没有出现(循环内的 printf() 语句不包含 \n并且 stdout 不是明确的 fflush()d) 和 main() 中对 execl() 的调用,它替换了当前进程镜像,并且 stdout 缓冲区在正常程序退出时不会像往常一样刷新。将换行符添加到 printf() 或在循环后显式调用 fflush(stdout);


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

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

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

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

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

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

要解决此问题,只需使用 char 和格式说明符 %c 即可:

char ch;

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

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

关于即使满足条件,代码也不会进入 while 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12828590/

相关文章:

c++ - 通过引用或指针传递 char 或 Short 是否比通过值传递慢?

c - 如何使用C程序根据不同的长度值设置掩码

java - 好奇为什么这个递归代码不起作用,并且在另一种方法中表现出非常相似的行为

c - 一行打印多个\t

c - 如何在多线程中使用 printf()

c - 分配中的段错误

平台之间的 C 枚举大小不匹配有潜在危险

javascript - 如何让 while 循环将其结果存储在数组中,并重复 10 次?

c - 为什么它显示主要因子的输出错误?

c - 如何将 Printf 之类的格式字符串与 argv 一起使用