2012-03-26 3 views
0

배열의 단어를 검색하는 바이너리 검색 기능이 있습니다. 그러나 배열을 검색하기 전에 검색 할 단어를 알아야합니다. 사용자에게 입력을 요청하는 코드를 작성했지만 프로그램은 입력 요청을 인쇄하지만 사용자로부터 아무 것도받지 않습니다. 프로그램에서 초기 scanf를 사용하여 외부 파일의 모든 문자열을로드하고 배열에 배치하는 것이 버퍼 문제라고 생각했습니다. 나는 내 초기 scanf 후 fflush를 사용하여 시도하고, 이전 스레드에서 지적한 바와 같이 gets로 두 번째 재 작성을 시도했다. 아마 나는 그것을 올바르게 구현하지 않을 것입니다. 여기에 내가 지금까지 무엇을, 두 번째 scanf 작동하지 않는 이유에 대한 조언을 주셔서 감사합니다.Scanf가 두 번째 문자 문자열을 허용하지 않음

#include "set.h" 
#include "sortAndSearch.h" 
#include <stdio.h> 
#include <ctype.h> 
#include <string.h> 

int main(){ 
char names[320][30]; 
char str[30]; 
int i, j; 
char *key; 
int numOfWords; 
char userWord[30]; 
Set set1, set2, set3; 

//scan each char string into array names 
for(i=0; scanf("%s", str) != EOF; i++){ 
     strcpy(names[i], str); 
} 

//set number of words in file 
numOfWords = i; 

//sort names array 
//bubbleSort(names, numOfWords); 

//print out names, sorted 
//for(i=0; i<numOfWords; i++){ 
//  printf("%s\n", names[i]); 
//} 

printf("What word would you like to search for? "); 
scanf("%s", userWord); 

//addName2Set(set1, userWord); 

return 0; 
} 
+0

당신이 입력의 * 라인 *을 읽으려면 라인을 읽는 기능을 사용합니다. 그렇지 않으면 단어를 읽고 선 끝을 떠납니다. –

답변

0

회 돌이 중 처음에 scanf()은 EOF까지 모든 것을 읽으므로 '어떤 단어를 검색 하시겠습니까?' 읽을 수 scanf(). 이 문제를 해결

한 가지 방법은 (프로그램, 또는 고정 이름에 인수 될 수 fopen(), fscanf(), fclose() — 및 파일 이름) 파일에서 초기 이름을 읽는 것입니다.

시도 할 수있는 또 다른 방법은 clearerr(stdin);의 앞에 '어떤 단어'scanf()입니다. 그 (clearerr())는 EOF 비트를 해제하고 scanf()을 다시 시도 할 수 있습니다. 프로그램의 입력이 터미널 인 경우 작동 할 수 있습니다. 프로그램의 입력이 파일에서 오는 경우 도움이되지 않습니다.


int main(int argc, char **argv) 
{ 
    char names[320][30]; 
    char str[30]; 
    int i, j; 
    char *key; 
    int numOfWords; 
    char userWord[30]; 
    Set set1, set2, set3; 
    FILE *fp; 

    if (argc != 2) 
    { 
     fprintf(stderr, "Usage: %s word-file\n", argv[0]); 
     exit(1); 
    } 

    if ((fp = fopen(argv[1], "r")) == 0) 
    { 
     fprintf(stderr, "Usage: %s word-file\n", argv[0]); 
     exit(1); 
    } 

    //scan each char string into array names 
    for (i = 0; i < 320 && fscanf(fp, "%29s", str) != EOF; i++) 
    { 
     strcpy(names[i], str); 
    } 

    fclose(fp); 

    //set number of words in file 
    numOfWords = i; 

이것은 당신이 (대신 ./a.out < example.dat의) ./a.out example.dat를 사용할 것을 주장한다. 그러면 원하는대로 다소 효과가 있습니다. 물론 파일을 읽는 코드는 파일 이름, 배열 및 배열 크기를 전달하는 함수에 있어야합니다. 루프의 320은 오버플로 보호이며 배열 선언과 루프에서 모두 사용되는 열거 형 enum { MAX_WORDS = 320 };이어야합니다. 29은 오버 플로우 방지입니다. 그것을 매개 변수화하기는 어렵지만 배열의 두 번째 차원보다 하나 작습니다. 파일이 각 단어 자체에되도록 포맷 된 경우

+0

왜 scanf는 data.dat 파일의 끝에서 종료되지 않습니까? – manalishi

+0

파일 이름이 고정되어 있지 않습니다. 프로그램이 실행될 때 제공됩니다. ./a.out manalishi

+0

'clearerr (stdin);'트릭도하지 않았습니다. 초기 입력은 외부 파일에서 이루어지며, 두 번째 입력은 터미널 내에서 이루어집니다. – manalishi

4

두 번째 scanf 첫 번째 scanf 결코 종료하지 않기 때문에 작동하지 않습니다. scanf은 입력 스트림이 닫히지 않는 한 EOF을 반환하지 않습니다. 즉, 콘솔이 닫히는 것입니다.

scanf은 읽은 문자 수를 반환하므로 루프 조건은 scanf(%s, str) != 0이되어야합니다. 그러면 사용자가 아무 것도 입력하지 않고 엔터를 치자 마자 루프가 종료됩니다.

+0

for (i = 0; scanf ("% s", str))가 변경되었습니다!= 0; i ++)'하지만 세분화 오류가 발생했습니다. – manalishi

+0

외부 파일에서 입력을 가져오고 그 파일에 데이터가 얼마나 있는지 모르기 때문에 EOF가 있습니다. 두 번째 scanf까지 사용자에게 메시지가 표시되지 않습니다. – manalishi

+0

'첫 번째''scanf()'never never' '는 무엇을 의미합니까? 입력이 파일에서 리디렉션되면 (어떤 일이 일어나는 지에 대한 주석이 있습니다), 루프는 파일의 끝까지 반복적으로'scanf()'를 실행합니다. 입력이 터미널에서 온 것이면, Windows에서 control-Z를 입력하거나 Unix에서 control-D (일반적으로)를 입력하면 입력이 종료됩니다. 모든 경우에 루프 내의'scanf()'는 행복하게 실행됩니다. –

0
귀하의 질문과 코드가 무섭게 첫눈에 잘못 정렬 된 듯

...

scanf()이 파일 읽기에 대한 잘못된 기능을, 당신은 fscanf()를 원하거나 행 fgets()도 작동합니다 (개행은 각 문자열의 읽기를 중지 함). 마찬가지로, scanf() 대신에 gets()을 사용하여 입력이 문자열 (return) (newline) 다음에 오는 경우 사용자 입력을 읽을 수 있습니다.

Everything you need to know about stdio.h

관련 문제