0

I have to make a C program that reads a file (I have to use read() method, I'm not allowed to use C libraries and other methods) word by word. I'd like to compare the words from the file with given words. It's basically searching a file for specific words.

My problem is, when I get a word from the file eg. "bla" and I compare it to the same string, strcmp() doesn't show that they are identical.

I pasted my code below:

#include <stdlib.h>
#include <fcntl.h> //open,creat
#include <sys/types.h> //open
#include <sys/stat.h>
#include <errno.h> //perror, errno
#include <string.h>

int tananyag; 
int fogalom; 
int modositott;
char string_end = '\0';

int main(int argc,char** argv){

    tananyag = open("tananyag.txt",O_RDONLY); 
    fogalom = open("fogalom.txt",O_RDONLY); 
    modositott =open("modositott.txt",O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR);

    if (tananyag < 0 || fogalom < 0 || modositott < 0){ perror("Error at opening the file\n");exit(1);}

    char c;
    int first = 1;
    char * str;
    str = (char*)malloc(80*sizeof(char));

    while (read(tananyag,&c,sizeof(c))){ 

            if(c != ' '){

            if(first){
                strcpy(str,&c);
                first = 0;
            }
            else{
                strcat(str,&c);
            }           
        }
        else
        {
            strcat(str,&string_end);

            printf("%s string length: %i \n",str,strlen(str));
            printf("%s string compared to bla string: %i \n",str, strcmp(str,"bla"));
            str = (char*)malloc(80*sizeof(char));
            first = 1;
        }
    }
    close(tananyag);
    close(fogalom);
    close(modositott);
}
dcaswell
  • 3,137
  • 2
  • 26
  • 25
  • 1
    Magyarok! Gondoljátok, hogy az a rengeteg üres sor segít az olvashatóságban? :D Továbbá, [ne casteld a `malloc()` visszatérési értékét](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc/605858#605858). –  Oct 23 '13 at 20:38
  • 2
    (yay, that's just my usual "format your code and don't cast malloc" comment in Hungarian, in case anyone's wondering.) –  Oct 23 '13 at 20:39
  • 1
    `if(first){ strcpy(str,&c);` c is a single character, it is not NUL terminated. In this case you could just use `str[0] = c;` and do the nul termination afterwards. – wildplasser Oct 23 '13 at 20:39
  • @wildplasser (No way they can learn that C strings need to be NUL-terminated. Really, no way. I wonder what's so hard about that.) –  Oct 23 '13 at 20:40
  • Also: you allocate `str` but don't null-terminate it, then use `strcpy` and `strcat`... recipe for seg faults. – vanza Oct 23 '13 at 20:40
  • This has buffer overflow written all over it – Scotty Bauer Oct 23 '13 at 20:42
  • `strcat(str,&string_end);` is complete nonsense: `strcat(a,b)` appends `b` after `a`, that is: it first finds the end of `a` (which is indicated by the position of the terminating '\0' ) No need to put a '\0' there, it's already there. – wildplasser Oct 23 '13 at 20:46

1 Answers1

0

You can't use strcpy with c, because c is a single character, and strcpy expects a null-terminated characters sequence. I am surprised this code even works. You should use your own method to write to the string. For example, you can keep an index i that stores the next position where you can write.

Sample code derived from yours:

int i = 0;
while (read(tananyag,&c,sizeof(c))){ 
    if (c != ' ') {
        if (i < 79) {
            str[i] = c;
            i++;
        }
    }
    else
    {
        str[i] = '\0';
        printf("%s string length: %zu\n",str,strlen(str));
        printf("%s string compared to bla string: %d \n",str, strcmp(str,"bla"));
        i = 0;
    }
}

I added an important check to avoid buffer overflows. You can't write beyond the size of your buffer. With this code, any excess characters in a huge word will be ignored.

NOTE: As good practice rules demand, you should make that 80 a defined constant.

Filipe Gonçalves
  • 20,783
  • 6
  • 53
  • 70