tags:

views:

170

answers:

4

I am trying to finish a homework program that compares a string with a text file, so the user can essentially search the text file for the search term (string) in the file. I'm getting there :)

However today I'm running into a very weird issue. When it asks for the term to search for I input the text, but it never ends. I could type all day long and it still asks for input. What weird issue(s) am I overlooking? Fresh pair of eyes might help :)

/*
 ask the user for a word
 convert user word to LOWER CASE
 open output file
 open input file
 test to be sure input file is open
 search for target word and keep count --> how??
 print results to monitor
 write results to file
 close files
 */
#include<stdio.h>
#include<stdlib.h>

int main (void)
{
    //declare 
    int i =0;
    int count = 0;

    /*************************************************************
     working with arrays and strings
    *************************************************************/
    char mystring[50]; //what user puts in
    char target[50]; //the word in the file we are looking for

    printf("input your message ");
    scanf("%s", mystring);
    //printf("%s", mystring);


    /*************************************************************
     find file, write to it, output the string, end and close file
    **************************************************************/

    //define text file to use
    FILE *cfile;
    //name of file == file
    cfile = fopen("./thanksgiving_proclamation.txt", "a");

    //error handling if file does not exist
    if(cfile == NULL) printf("Cannot open file");

    /*************************************************************
             parse through file and search for string
    **************************************************************/ 
    //convert string to lowercase
    for(i = 0; i < /*strlen(mystring)*/ 500; i++)//convert to string length
    {
     if(target[i] >= 'A' && target[i] <='Z')
      //convert char between a and z into lowercase
      target[i] = target[i] + 32; //makes uppercase char
    }

    //compare our strings
    do{
     //scan through file
     fscanf(cfile, "%s", mystring); 

     //convert string to lowercase
     for(i = 0; i < /*strlen(mystring)*/ 300; i++)//convert to string length
     {
      if(mystring[i] >= 'A' && mystring[i] <='Z')
       //convert char between a and z into lowercase
       mystring[i] = mystring[i] + 32; //makes uppercase char
     }
     if(strcmp(mystring, target) == 0)
      count++;
    }while(!feof(cfile));

    //while(strcmp(target,"quit")!=0)//end loop


    //print to file
    fprintf(cfile, "%s", mystring);

    //close file
    fclose(cfile);

    //show user file has been written
    printf("\nSuccess. File has been written\n");


    printf("Press Enter to Continue...");
    getchar();
    return 0;
}
A: 

It ends when you hit Enter and only stores characters till a whitespace.

Jacob
when i hit enter, it still allows me to input characters. this is my issue. when one hit enters it should go to the next task but in this case it just keeps on letting me hit characters, even after i hit 'enter'.
HollerTrain
how about the print statement after scanf? does it work after you hit enter?
Amarghosh
The print statement is commented out. Out of curiosity I ran it and it works - btw, it doesn't even compile because of the `FILE* cfile` in the middle. Maybe in some **super** *weird* way, that's the reason?
Jacob
hmm doesn't work over here :(
HollerTrain
@Amarghosh, no it does not print it. Just keeps letting me input content
HollerTrain
What compiler are you using? And this can't be C code due to the position of `FILE*`
Jacob
@Jacob, I am using Terminal in Mac. I'm also pretty sure it's C code.
HollerTrain
@Jacob: What's wrong with FILE* cfile in the middle? It looks valid to me.
Ken
@Ken: if this is a C89 or earlier compiler, you cannot mix declarations and code. It's legal as of C99.
John Bode
A: 

You don't need "&mystring", "mystring" is already the address of the array.

It would be better to use gets or getline.

You are reading the search string into mystring, but then you are also reading the file contents into mystring.

Martin Beckett
Doesn't really answer the question .. :)
Jacob
Never use gets. Repeat for emphasis. NEVER use gets. fgets is fine, but gets is a buffer overflow waiting to happen.
William Pursell
ah right, changed it to simply 'mystring'. still doesn't solve my issue tho :(
HollerTrain
Wow, that's the first time I've seen anybody suggest the use of gets(). As William points out, gets() is a guaranteed overflow, since it doesn't allow you to specify the size of your buffer.
asveikau
This is only a homework question not an industrial grade solution. ps. how exactly does scanf prevent overflows?
Martin Beckett
Hmm. Homework assignments which teach pupils that avoiding buffer overflows is "industrial grade" stuff that they don't need to know, result in programmers who can't avoid buffer overflows. If the school doesn't want its students to be able to do that, they should teach using Java, not C.
Steve Jessop
@mgb scanf() does not prevent that either, absent non-standard format strings (on GNU, is there an %a which allocates memory for you?). fgets() is what you want to use.
asveikau
Then the solution would be to use SQLServer full text search!
Martin Beckett
+2  A: 

You open the file in append mode:

cfile = fopen("...", "a");

and then you try to read from it.

fscanf(cfile, "%s", mystring);

For a first attempt at solving the problem, I'd try to open the file for reading, read from it inside the loop and close the file. Then open it again, this time for appending to add the mystring there (and fclose it).

Once that works, if you want to, try to see if opening in "reading and appending mode" works ...

cfile = fopen("...", "a+");
pmg
A: 

I think pmg has hit on the actual problem; you've opened the file in append mode, and according to my copy of H&S reading from an append stream is not permitted. You'd have to open it "a+" (append/update) in order to read and write the stream.

You should always check the result of the *scanf() call (fscanf(), sscanf(), scanf(), etc.) for success before checking feof() or ferror(), and you should never make feof() the loop test condition (since it won't return true until after you've attempted to read past the end of the file, your loop will always execute once too many times).

I'd change your loop to something like this:

for(;;)
{
  if (fscanf(cfile, "%s", mystring) != 1)
  {
    if (feof(cfile)) 
    {
      fprintf(stderr, "Reached end of file!\n");
      break; // exit loop
    }
    if (ferror(cfile)) 
    {
      fprintf(stderr, "Error while reading from file!\n");
      break;
    }
  }
  /**
   * continue as before
   */
}
John Bode
perfect. the missing '+' was the culprit. now i have to go through and figure out the rest of the project ;)
HollerTrain
@John, Thanks btw :)
HollerTrain
I thought the user input (typed) was the problem?
Jacob
yeah it was, but this fixed it. no clue.
HollerTrain