2012-12-20 3 views
0

안녕 얘들 아 내가이 파일 구조체를 파일.
줄을 읽고 원하는 줄을 얻는 가장 좋은 방법은 무엇입니까?읽기 TXT는 언어 C

예 : 우리가 1, 2, 3, ... 번호를 가질 수 있기 때문에

0 
2 4 
0,1,ab,5,b 
1,2,b,5,a 
... 

의 선 크기가 다를 수 있습니다. 내가 볼

//struct 
#define MAX_ 20 

struct otherstats{ //struct otherStats 
    int conectstat[MAX_];//conection with others stats 
    int transitions[MAX_];//Symbols betwen conection ASCI 
}tableStats[MAX_]; 

struct sAutomate{ 
int stat_initial; //initial 
int stats_finals[MAX_]; //final orfinals 
struct otherstats tableStats[MAX_]; //otherStats 0 1 2 3 4 5 6 
}; 

/* eXample that what i want ..using the example 
sAutomate.stat_initial=0 
sAutomate.stats_finals[0]=2 
sAutomate.stats_finals[1]=4 

Others Stats table 
//0 
sAutomate.tableStats[0].conectstat[0]=1; 
sAutomate.tableStats[0].conectstat[1]=5; 
sAutomate.tableStats[0].transitions[0]=ab; 
sAutomate.tableStats[0].transitions[1]=b; 
//1 
sAutomate.tableStats[1].conectstat[0]=2; 
sAutomate.tableStats[1].conectstat[1]=6; 
sAutomate.tableStats[1].transitions[0]=b; 
sAutomate.tableStats[1].transitions[1]=a; 
///etc 
*/ 



void scanfile(){ //function to read the file 

struct sAutomate st; //initialize st struct 

char filename[] = "txe.txt"; 
FILE *file = fopen (filename, "r"); 
char buf[81];  
char parts[5][11]; 

fscanf(file,"%d", &st.stat_initial);//read first line 
printf("initial state : %d \n", st.stat_initial); 
fscanf(file,"%d",&st.stats_finals); 
fscanf(file,"%d",&st.stats_finals); 


while (fgets(buf, sizeof(buf), stdin) != NULL) 
{ 
if (sscanf(buf, "%10[^:]: (%10[^(], %10[^)]), (%10[^(], %10[^)])", 
      parts[0], parts[1], parts[2], parts[3], parts[4]) == 5) 
{ 
    printf("parts: %s, %s, %s, %s, %s\n", 
     parts[0], parts[1], parts[2], parts[3], parts[4]); 
} 
else 
{ 
    printf("Invalid input: %s", buf); 
} 
} 
//fclose 
+3

시도해보십시오. fscanf' ... –

+0

벌써했는데 만났을 때 문제가 발생했습니다 : (문자 .i는 숫자와 문자 만 원하고 구조체에 각 값을 넣고 싶습니다.) – devish

+4

코드를 표시하십시오. – Nocturno

답변

1

첫 번째 문제는 당신이 stats_finals 덮어 쓰기를하고있다 : 당신이하고 싶었던 무엇

fscanf(file,"%d",&st.stats_finals); 
fscanf(file,"%d",&st.stats_finals); 

했다 :

fscanf(file,"%d",&st.stats_finals[0]); 
fscanf(file,"%d",&st.stats_finals[1]); 

으로

나는 이미 그것을했다 텍스트 파일에서 "2"와 "4"를 모두 저장하지 마십시오.

두 번째 큰 문제는 당신이 stdin에서 읽고있는 경우 : 키보드에서 입력을 읽고 텍스트 파일을 읽고 ... 그래서 당신이 원하는하지 않습니다

while (fgets(buf, sizeof(buf), stdin) != NULL) 

가가로 :

while (fgets(buf, sizeof(buf), file) != NULL) 

세 번째 (사소한) 문제는 fscanf()이 개행을 읽지 않으며, fgets()이됩니다. 즉, 두 번째 문자 인 stats_finals을 읽음에서 while 루프의 첫 번째 읽기까지 가면 첫 번째 입력은 줄 바꿈 문자 이상이됩니다. "잘못된 입력"을 확인한 이후로 큰 문제는 아니지만 주목할 가치가 있습니다.

마지막으로, sscanf를 나에게 잘못 같습니다

sscanf(buf, "%10[^:]: (%10[^(], %10[^)]), (%10[^(], %10[^)])", 
      ^     ^
       That's a width of 10,  Why are you checking for commas? You didn't 
       I don't think that's  have any in your text file 
       what you wanted... 

나는 이것이 당신이 찾고 있던 무엇을 더 생각 : 원래 지점을 놓친

sscanf(buf, "%[0-9]: %[0-9](%[^)]) %[0-9](%[^)])", 
       ^
      takes a digit (0 to 9) 

편집 할 수 있습니다. 문자열이 얼마나 오랫동안 읽는지 알 수없는 경우 sscanf()을 사용할 수 없습니다. 그것은 간단합니다. :)

scanf 패밀리는 구문 분석 할 객체의 수를 알고 있고 그 중 많은 수의 형식 문자열을 사용한다고 가정합니다. 그러나 다른 옵션이 있습니다.

fgets로 한 행을 읽었지만 토큰화할 수 있습니다. C 함수 strtok 또는 for 루프를 사용하여 직접 손으로. 그러나

한주의 사항 :

당신이 얼마나 오래 알고하지 않기 때문에

이 : char parts[5][11];는 가장 좋은 건 아니다. 이것은 2 개의 항목으로 제한됩니다 ...아마도 이것을 동적으로하는 것이 더 낫습니다. (라인을 읽고 정확한 크기를 할당하여 토큰을 저장하십시오.)

+0

고마워요. 유타 주요 문제는 그 각 줄의 크기를 모르겠다 ... 얼마나 많은 인수가 필요합니다 ... 나는 1 라인 0 : 1 (ab) 5 (b) 또는 0 : 1을 가질 수 있습니다 (ab) 5 (b) 9 (ba) ... 예 4 : 5에서 (ab)는 다른 사람이 아니라 3 개의 인수 만 가지고 있기 때문에 오류가 발생합니다 – devish

+0

@devish - 아무런 의미가 없습니까? 그 라인은 단순히 num (char)만큼 많을 수 있습니다. – Mike

+0

yes :/sry, 나는 대답을 정말로 좋아한다. 첫 번째 줄에만있다. (0) 나는 단 하나의 숫자 인 – devish

0

라인에 포함될 숫자와 문자의 수를 정확히 알지 못하는 이유는 무엇입니까? 고정 된 양의 숫자와 문자? 당신은 여전히 ​​필요하면 그것의 복사본을 만들고,

const char* const DELIMITERS = " "; 

int i; // index for tableStats 
char* token; 

token = strtok(line, DELIMITERS); 

// first integer 
if (token == NULL || sscanf(token, "%d:", &i) < 1) 
    // error 

/* it seems like you should have at least one element in your "list", 
* otherwise this is not necessary 
*/ 

token = strtok(NULL, DELIMITERS); 

if (token == NULL || sscanf(token, "%d(%[^)])", 
    &(tableStats[i].connectstat[0]), 
    &(tableStats[i].transitions[0])) < 2) 
    // error 

// read optional part 
for (int j = 1; (token = strtok(NULL, DELIMITERS)) != NULL; ++j)  
    if (sscanf(token, "%d(%[^)])", &(tableStats[i].connectstat[j]), 
     &(tableStats[i].transitions[j])) < 3) 
    break; 

strtok 문자열을 변경 기억 :

당신은 fgets과 전체 라인을 읽은 다음 strtok 같은 토크 나이, 같은 뭔가를 구문 분석 할 수 .

코드는 임의의 긴 행에 대한 것이므로 처음 두 행을 읽는 것은 간단합니다.

+0

구획자를 어떻게 설치해 줘서 고마워요? – devish

+0

@devish 죄송합니다.이 파일은 복사/붙여 넣기에서 지워졌습니다. 그것은 당신 사이의 라인에있는 요소입니다. – effeffe

+0

그래서이 예제에서는 내 const char * const DELIMITERS = ":, (,)"; .. 작동하지 않습니다. – devish