2010-06-08 4 views
3

"tab"구분 기호로 30 행 5 열의 파일을 읽으려고합니다. 매번 행의 일부만 가져옵니다. Windows 환경에서는 정상적으로 작동합니다. 유닉스에서 왜 작동하지 않는지 어떤 생각?C 언어 - 유닉스 환경에서 Fscanf 및 sprint 명령

while (fscanf(FFMapFile, "%s\t%s\t%s\t%s\t%s\t", fnfMap[i].COS_ID, fnfMap[i].FF_First_Act, fnfMap[i].FF_Next_Act, nfMap[i].Free_FF_allowed, fnfMap[i].FF_Change_Charge) != EOF) 
{ 
    sprintf(s,"%s\t%s\t%s\t%s\t%s\t", nfMap[i].COS_ID, fnfMap[i].FF_First_Act, fnfMap[i].FF_Next_Act, fnfMap[i].Free_FF_allowed, fnfMap[i].FF_Change_Charge); 
    error_log(s,ERROR); 
    i++; } 
+0

샘플 행을 게시하고 읽음 값을 얼마만큼 말해 줄 수 있습니까? – Mawg

+0

똑같은 파일을 사용하고 있습니까? Windows/Unix 탭은 다르게 해석됩니다. 창에 탭을 사용하여 만든 파일이 유닉스에 복사 될 때 예상대로 작동하지 않을 가능성이 있습니다. –

+3

@Gunner - 끝 마커로 마커를 혼동하지 않으시겠습니까? – detly

답변

0

fscanf()의 반환 값을보다주의 깊게 확인하십시오. 3 개의 필드와 일치하면 3을 반환합니다. 버퍼 오버플로를 피하기 위해 다양한 문자열의 크기에주의해야 할 수도 있습니다. 즉, 다른 날의 제목 일 수 있습니다.

나를 공격 할 수있는 가능성은 형식 문자열의 마지막 탭이 개행 문자로 더 좋을 수 있지만 보통 fscanf()은 형식 문자열 및 데이터의 공백에 대해 상당히 자유로운 태도를 취하는 것입니다.

이 단순화 (하지만 완전한 작업) 코드의 버전

#include <stdio.h> 

int main(void) 
{ 
    char b1[20], b2[20], b3[20], b4[20], b5[20]; 
    while (fscanf(stdin,"%s\t%s\t%s\t%s\t%s\t", b1, b2, b3, b4, b5) == 5) 
     printf("%s\t%s\t%s\t%s\t%s\n", b1, b2, b3, b4, b5); 
    return 0; 
} 

그러나 맥 OS X에서 올바로 수행 더 많거나 적은 동작, 그것은 문자열을 치료했다 'k k k k k'(5 개 단일 문자를 공백으로 분리) 5 개의 탭으로 구분 된 것과 같습니다.

형식은 0 개 이상의 지시어로 구성되어있다 : 문제는, 따라서 C 표준의 섹션 §7.19.6.2가 지정하는 하나 이상의 공백 문자, 일반 멀티 바이트 문자 (도 % 공백 문자가 아님) 또는 변환 지정.

에 [, c 또는 n 지정자가 포함되어 있지 않으면] 공백 문자 (isspace 함수에서 지정한 값)는 건너 뜁니다.

는 또한, '% s'을 (를) 지정에 관해서, 그것은 말한다 :

비 공백 문자의 순서와 일치합니다.

실제 탭을 강제로 일치 시키려면 훨씬 더 세게 작업해야합니다. 버퍼에 라인을 읽고 (fgets()) 수동으로 분할하는 편이 훨씬 쉽습니다. 이렇게하면 한 줄에 5 개의 단어를 적용 할 수 있으며 필드가 너무 적거나 많으면 오류 또는 경고를 생성 할 수 있습니다. fscanf()을 사용하면이를 수행 할 수 없습니다. 한 줄에 8 단어를 입력하면 처음 다섯 번을 읽은 다음 줄의 나머지 세 단어와 그 다음 두 단어를 읽는 식으로 계속 읽습니다.

0

성공한 경우 fscanf은 성공적으로 읽은 항목 수를 반환합니다. 이 수는 예상 수와 일치하거나 일치하지 않는 경우에 더 적을 수 있습니다.

어떤 행이 올바르게 구문 분석되지 않았는지 확인하고 입력 데이터를 검사하려면 fscanf s 반환 값을 확인해야합니다.

1

fscanf() 문자열의 \ t 문자는 필요하지 않습니다. 탭은 공백이므로 "% s % s % s % s"라고 말하면됩니다. 두 개의 scanf 구현은 다르게 처리합니다 . 또한 fscanf가 EOF 이외의 값을 반환하지만 예상되는 변환 수와 같지 않은지 확인해야합니다. 이는 일종의 변환 오류를 나타냅니다.

+1

""% s % s % s % s "(이)라고 말할 수 있습니다."- 아니요, 오타를 "% s % s % s % s % s" 여전히 대용품이되지는 않을 것이다. 그러나 후행 공백을 없애기위한 "% s % s % s % s % s \ t"는 대용품이됩니다. –

관련 문제