【问题标题】:Code doesn't enter in while loop even when condition is satisfied [duplicate]即使满足条件,代码也不会进入while循环[重复]
【发布时间】:2012-10-01 11:16:57
【问题描述】:

可能重复:
“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 是一个全局变量)。是什么导致了这个问题?

【问题讨论】:

  • 你登录counter了吗?应该是0
  • 你是否输入了一个断点并查看计数器的实际值是多少?
  • @DrummerB 是的,我记录了计数器,它在调用函数中打印了真实值
  • @AlexeyFrunze 哇,这就是为什么它打印最后一行的副本:))。谢谢建议
  • @quartaela,这也是您应该检查返回值的原因。 :)

标签: c while-loop printf multiprocessing


【解决方案1】:

由于stdout 被缓冲(循环内的printf() 语句不包含\nstdout 没有明确地fflush()d)和对@987654326 的调用,循环的输出没有出现@ 在main() 中,它替换了当前进程映像,并且stdout 缓冲区在正常程序退出时不会像往常一样刷新。在printf() 中添加换行符或在循环后显式调用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);

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

char ch;

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

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

【讨论】:

  • 在我使用 malloc 之前,我面对的是segmentation fault error,这就是我分配的原因。另一方面,为什么我们要准确检查2 与 fscanf _ 的返回值?
  • @quartaela, fscanf() 返回分配的数量。由于fscanf() 的调用试图为chtemp 赋值,如果成功,则返回值为2。
  • 是的,我想这种方式也有效,而且效率更高。另一方面,它仍然无法进入while循环,所以这不是未定义行为的原因_?
  • @quartaela,您是否更改了所有使用str 的代码?比如strcmp()? (只是检查)。
  • 是的,我检查像if(str=='A')这样的字符
猜你喜欢
  • 1970-01-01
  • 2016-03-14
  • 1970-01-01
  • 2022-10-13
  • 1970-01-01
  • 2013-04-08
  • 2021-08-07
  • 2020-04-15
  • 1970-01-01
相关资源
最近更新 更多