2012-10-13 5 views
0

안녕하세요, 다중 프로세스 프로그래밍에 대한 할당이 있고 내가 문자를 한 줄씩 읽으려고 할 때 문제가 있습니다. 각 줄은 3 자와 1 개의 정수로 구성됩니다. 문제는 내가 제대로 작동하지 않고 fscanf을 사용할 때 문자가 성공적으로 2 단계 만 읽는 것입니다. 여기 내 코드를 볼 수 있습니다. fscanf 제대로 작동하지 않습니다.

#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 <ctype.h> 

void child_process(int); 
void parent_process(); 
void function(); 
int counter=0; 
int bond_number=0; 

char* f_strand; 

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

    counter = atoi(argv[1]); 

    function(); 

    fflush(stdout); 

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

void function(){ 

    int i,k; 
    pid_t child_pid[counter]; 
    char array[counter]; 
    char array_opst[counter]; 
    srand (time(NULL)); 
    int temp; 

    FILE* fptr; 
    fptr = fopen("sample.txt","w"); 

    if(! (f_strand=(char*)malloc(counter*sizeof(char)))){ 
     printf("Error\n"); 
     exit(1); 
    } 

    for(i=0; i<counter; i++){ 

     temp = rand()%4; 

     if(temp==0){ 
      *(f_strand+i) = 'A'; 
      fprintf(fptr,"A\n"); 
     } 
     else if(temp==1){ 
      *(f_strand+i) = 'C'; 
      fprintf(fptr,"C\n"); 
     } 
     else if(temp==2){ 
      *(f_strand+i) = 'T'; 
      fprintf(fptr,"T\n"); 
     } 
     else if(temp==3){ 
      *(f_strand+i) = 'G'; 
      fprintf(fptr,"G\n"); 
     } 
    } 

    fclose(fptr); 

        for (i = 0; i < counter; i++) { 
         if ((child_pid[i] = fork()) < 0) { 

         perror("fork"); 
         abort(); 
         } 
         else if (child_pid[i] == 0) { 

         child_process(i); 
         exit(0); 
         } 
        } 
    int status; 
    pid_t pid; 
    int num=counter; 
     while (num > 0) { 
      pid = wait(&status); 
      //printf("Child with PID %ld exited with status 0x%x.\n", (long)pid, status); 
      --num; // Remove pid from the pids array. 
     } 


    parent_process(); 
    printf("\n"); 

} 

void child_process(int index){ 

    int i; 
    char str,str1,str2; 

    FILE* fptr; 
    fptr = fopen("sample.txt","r"); 

    fseek (fptr, 2*index, SEEK_SET); 
    fscanf(fptr,"%c", &str); 

    FILE* fptr2; 
    fptr2 = fopen("sample_2.txt","a"); 

     if(str == 'A'){ 
      str1='T'; 
      str2=';'; 
      fprintf(fptr2,"%c%c%c%d\n",str,str2,str1,index); 
      } 
     else if(str == 'T'){ 
      str1='A'; 
      str2=';'; 
      fprintf(fptr2,"%c%c%c%d\n",str,str2,str1,index); 
      } 
     else if(str == 'G'){ 
      str1='C'; 
      str2=':'; 
      fprintf(fptr2,"%c%c%c%d\n",str,str2,str1,index); 
      } 
     else if(str == 'C'){ 
      str1='G'; 
      str2=':'; 
      fprintf(fptr2,"%c%c%c%d\n",str,str2,str1,index); 
      } 

    fflush(stdout); 
    fclose(fptr); 
    fclose(fptr2); 
    sleep(1); 

} 

void parent_process(void){ 

    FILE* fptr; 
    fptr = fopen("sample_2.txt","r"); 

    char str,str1,str2; 
    int index,i,k; 
    char array_opst[counter]; // second strand 
    char array_type[counter]; // bond type 

    i=0; 

    while(!feof(fptr)){ 

     if(4==fscanf(fptr,"%c%c%c%d",&str,&str1,&str2,&index)){ 

      if(feof(fptr)) 
       break; 

      printf("STR = %c\n, K = %d",str,k); 

      array_type[index]=str1; 
      array_opst[index]=str2; 
      printf("WHILE\n"); 

      if(array_type[index] == ':') 
       bond_number=bond_number+2; 
      else if(array_type[index] == ';') 
       bond_number=bond_number+3; 
    } 

     i++; 
} 
    fclose(fptr); 

} 

는 3 자와 sample2.txt 파일에서 라인별로 하나 개의 정수 라인을 읽을하려고 parent_process()에서 sample2.txt

C:G5 
G:C6 
A;T4 
C:G3 
G:C7 
C:G8 
G:C2 
A;T9 
T;A1 
C:G0 

의 출력입니다. 하지만이 과정은 두 줄마다 수행됩니다. 나는 그것이 처음 세 번째 다섯 번째 라인을 읽고 계속된다는 것을 의미합니다. 어쨌든 도와 주시면 감사하겠습니다.

+0

이 동작을 나타내는'sample2.txt' 파일로 [SSCCE] (http://sscce.org)를 만들 수 있습니까? – oldrinb

+1

뭔가 'fscanf()'가 잘 동작 할 것입니다. –

+1

'fgets' 또는'read'와 같은 저수준 입력 루틴을 사용해 보셨습니까? 'fscanf'는 거의 항상 가치가있는 것보다 더 큰 문제입니다. – zwol

답변

3

이것은 흥미로운다면 문제입니다. 가장 먼저 유의해야 할 것은 c 전환을 사용하고 있다는 것입니다. C99 표준은 다음과 같이 명시되어 있습니다 (§7.19.6.2 ¶ 8). 명세서는 [, c 또는 n 지정자를 포함하지 않는

입력 공백 문자합니다 (isspace 함수 지정), 스킵된다.

이제 중요한 줄을 살펴 보겠습니다.

if(4==fscanf(fptr,"%c%c%c%d",&str,&str1,&str2,&index)){ 

란 발생하면 fscanf 의해 소비되고 그 공백 (항목 간의 심 라인 터미네이터 등)이다. 이 경우 읽기가 잘못 정렬되어 d 변환이 발생할 때 정수를 읽지 못합니다. 결과적으로 fscanf4으로 평가되지 않으며 분기가 수행되지 않으므로 잘못 읽힌 데이터는 인쇄되지 않습니다.

대신, 다른 모든 행을 잘못 읽고 올바른 입력을 '재배치'해야하므로이 선택 선만 인쇄됩니다. 이를 증명하려면 조건을 0 < fscanf(...)으로 바꾸고 잘못된 읽기는 다른 모든 행을 읽는 중간 시도를 보여주기 위해 출력을 생성합니다.

+0

답변 해 주셔서 감사합니다. 'if (5 == fscanf (fptr, "% c % c % c % d % c", & str, & str1, & str2, & index, & nl))로'\ n'을 문자로 읽으려고 할 때 작동합니다. – quartaela

2

문제가 줄 바꿈 문자라고 가정합니다. 형식 문자열에 포함 시키거나 연속 fscanf() 호출 사이에 여분의 문자를 읽으십시오.

+1

+1 변환 지정에'[','c','C' 또는'n' 변환 지정자가 포함되지 않는 한] 입력 공백 문자 ('isspace()'에 의해 지정된대로)는 건너 뜁니다. http://pubs.opengroup.org/onlinepubs/007904975/functions/scanf.html) – oldrinb

관련 문제