2

I am reading words from file & need to search some specific words, below is my code

string read = malloc(50 * sizeof(char));

FILE* p = fopen("word","r");

while(fgets(read,50,p))
{
    printf("%s\n",read);
    if(strcmp(read,"apple") == 0)
     {
        printf("apple found\n");
        break;
     }
}

And sample file 'word' is as below,

$: more word

liol
apple
scizzors
big
bang
mentalist
scapegrace
goat
goti

Why is strcmp not working in this case, printf can print string read, so char pointer is working fine.

hivert
  • 10,579
  • 3
  • 31
  • 56
amitfreeman
  • 165
  • 1
  • 3
  • 12
  • @hivert: I think you updated this post in a manner that changed the actual problem (and in fact, probably solved it). OP showed the input file as a single line of words. You changed it to a separate line for each word. It makes all answers below irrelevant. – barak manos Mar 09 '14 at 10:07
  • 1
    @barak manos : The newline between the word where there before my edit (see the [history](http://stackoverflow.com/posts/22280813/revisions)), I only made them **apparent**. So I don't think I changed the meaning of the original question. – hivert Mar 09 '14 at 10:09
  • @hivert: OK, gotcha, sorry... – barak manos Mar 09 '14 at 10:10
  • @barak manos , sorry my bad, the file word is actually like hivert has modified, anyways , understood the concept of fgets using below answers! – amitfreeman Mar 09 '14 at 10:19
  • You might as well get rid of the `malloc` while you're at it... just use `char read[50]` instead (or if you insist on `read = malloc`, then at least `free(read)` at the end. – barak manos Mar 09 '14 at 10:35
  • @barakmanos manos Yes, I have a habit of freeing space allocated by malloc, I also use 'valgrind' to check memory leakage for bigger programs. – amitfreeman Mar 10 '14 at 14:12

2 Answers2

10

The fgets() function, in most circumstances, retains the newline at the end of the line. Hence yourtext\n will not compare equal to yourtext. You would have noted this with one of my favorite tricks for checking strings:

printf ("[%s]\n", read);

The presence of a newline before the closing ] would have immediately alerted you to the problem, or at a minimum raised an eyebrow.

If you want to strip a newline off before comparing, you can do something like:

int ln = strlen (read);
if ((ln > 0) && (read[ln-1] == '\n'))
    read[ln-1] = '\0';

Alternatively, you could skip that and just do:

if (strcmp (read,"apple\n") == 0)

It's not necessarily elegant but, if you don't need to use the word for anything other than that comparison, it'll be just fine.

However, you may then need to worry about the last line in the file in case it has no newline at the end of it so maybe it's better to use the newline-removing code above.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • Lets say I want to use 'read' for more than comparison, like encryption using some technique, do I need to remove '\n' from it then? – amitfreeman Mar 09 '14 at 10:11
  • @amitfreeman, probably, only you can really answer that. Encryption of `apple` will almost certainly _not_ be the same as encryption of `apple\n`. – paxdiablo Mar 09 '14 at 10:12
  • Note that on Linux you might also need to remove the carriage return `\r` So something like `if(read[ln-2] == '\r') read[ln-2] = '\0';` – Raghav Apr 09 '20 at 05:18
2

To search for a specific string in the line, rather than match the entire line, strncmp (which searches for n characters) can be used.

if (strncmp(read,"apple",strlen("apple")) == 0)
 {
    printf("apple found\n");
    break;
 }
suspectus
  • 16,548
  • 8
  • 49
  • 57
  • @amitfreeman if you like the answer, consider to accept it – Dabo Mar 09 '14 at 10:19
  • 1
    Hmmm. That code looks for words that start with "apple". To search for a string in a line (or _match_ it), you'd have to use `strstr`. (Anyway, the problem were the new-line charactres, I think.) – M Oehm Mar 09 '14 at 10:33