2

I have a text file that looks something like this

user1|password1
user2|password2

I have a string, say "user1|password1". I need to compare each line of the text file with this string.

    FILE *fp;
    fp = fopen("user_info_file.txt", "r");
    while(fgets(str, 10, fp)!=NULL){
    n = write(newsockfd, "STR:", 4);
    n = write(newsockfd, str, 15);}

And then go on to strcmp. I use the write function because I'm having a server write this to a client.

I've just put 15 as a random value (it is within bounds) to see if any text is being read. But when it prints str, well str doesn't contain anything. It just prints as "STR:" and then I get my prompt back on the next line.

Please tell me how to read the data in user_info_file.txt (at least the first line) into str. I've spent hours on this but I just can't seem to get it. Newbie here, please bear with me.

EDIT: Basically I'm creating an IM application. User registers by entering their username and password, which is sent to the server and the server stores it in user_info_file in the form I've written above. After a user registers, they need to be able to login. They enter username and password, which again I send to the server. I then need the server to compare this string with the existing entries in user_info_file to validate the login. So I need the server to check every line of user_info_file and compare it to what the user enters.

So I have

char* str = new char[256];
    FILE *fp;
    fp = fopen("user_info_file.txt", "r");
    while(fgets(str, 10, fp)!=NULL){
    n = write(newsockfd, "STR:", 4);
    n = write(newsockfd, str, 15);}
    if(strcmp(buffer, str) == 0)
        n = write(newsockfd, "Logged in", 9);
    else
        n = write(newsockfd, "No such username", 16);

Basically I am trying to read each line of user_info_file into str. Then I compare str after every read line with buffer. buffer stores the login info the client has sent. If they are a match, then the login should be successful.

But, when I write str, well it doesn't print anything. 15 is the number of characters from str it should write, correct? So even if the number was, say, 5, it should print at least "user1" or "user2" or the first 5 characters of SOME line of user_info_file. But it doesn't look like anything is getting read from the file into str at all.

I hope I've made it clear. What can I do? I'm at my wit's end.

alk
  • 69,737
  • 10
  • 105
  • 255
user1825770
  • 359
  • 1
  • 6
  • 17
  • You don't show the definition of str, which I suspect has something to do with your problem. Can you include that part of your code as well? – Marc Cohen Nov 15 '12 at 06:14
  • What is the type of `str`? Do you get any data in `str`? – evanmcdonnal Nov 15 '12 at 06:15
  • 2
    you are reading 10 characters in fgets , then how come you are writing 15 characters in write ...? – Pavunkumar Nov 15 '12 at 06:32
  • Your text file uses ASCII (or UTF-8) and isn't saved as, say, UTF-16, right? Also, are you positive that it's `fgets` that's failing? Have you tried inspecting the contents of `str` after `fgets` by simply printing it (or using a debugger)? – jamesdlin Nov 15 '12 at 06:42
  • @jamesdlin Well yes I did try printing the output of fgets, it still led to nothing being printed. – user1825770 Nov 15 '12 at 07:45
  • @pavun_cool Changed 15 to 5, no change in the result. Still only prints "STR:". – user1825770 Nov 15 '12 at 07:46
  • @MarcCohen I have declared str as char* str = new char[256]; as shown above, nothing more than that. I later tried declaring it as char* str = malloc(256); on the suggestion of evanmcdonnal but then on compile that line shows an error: invalid conversion from ‘void*’ to ‘char*’ [-fpermissive] – user1825770 Nov 15 '12 at 07:48
  • Did you verify that `fopen` succeeds? Are you absolutely sure that `user_info_file.txt` contains what you think it does? – jamesdlin Nov 15 '12 at 08:23
  • From the comments I conclude this `C++` not `C`. Retagged. – alk Nov 15 '12 at 13:03

1 Answers1

0

I don`t think that is is convenient in your case to read from file char by char using fgets function. I propose you to use fscanf, which offers you more oppotunities: like reading values of different formats at the same time. Here I got some code snipet, to demonstrate how you can obtain desired information from file using fscanf:

int main(void)
{
    char str[256];
    char checkLogin[256];
    char checkPassword[256];
    FILE *fp = fopen("user_info_file.txt", "r");
    /*while(fgets(str, 10, fp)!=NULL){
    n = write(newsockfd, "STR:", 4);
    n = write(newsockfd, str, 15);}*/
    int scanSucceed = 1;
    do
    {
        scanSucceed = fscanf(fp,"%s|%s ", checkLogin, checkPassword); 
        if (!strcmp(checkLogin, buffer))
        {
        // in case if password for that login match
            if (!strcmp(checkPassword, password))
            {
                ValidLogin = true;
                scanSucceed = -1; // exit from while loop
            }
        }
    }
    while(scanSucceed != -1); // while string was read
}
spin_eight
  • 3,925
  • 10
  • 39
  • 61
  • `fscanf` is hard to use correctly. In particular, you have to be careful not to overflow your destination buffers. It is almost always preferable to use `fgets` (or `getline` if available) and then use `sscanf`. – jamesdlin Nov 15 '12 at 08:25
  • This is you own point of view about difficulty of usage of fscanf and it isn`t supported by any considerable arguments. As you mentioned buffer overflow- yes you should watch such things, overwise I don`t understand why you choose C language which provides you a lot of low level functionality which you can`t handle properly, so instead you should consider higher level languages. – spin_eight Nov 15 '12 at 08:56
  • It is not just my point of view. See http://www.c-faq.com/stdio/scanfprobs.html. `fscanf` is not significantly better than `scanf` in this regard. Using `fgets` (or `getline`) with `sscanf` is not much extra work, so why wouldn't you use a better, safer alternative? – jamesdlin Nov 15 '12 at 09:14
  • Have you read info, the link on which you provided?? Even the author tells you that when we have well structured input we are going to deal with it is better to use scanf, instead of fgets. Also pay your attention to the question which was asked, from it you can easily guess that author has file where info: user_name| password is stored, so it is evidient that format of file is known and it is consistent therefore for serialization it is better to use fscanf. – spin_eight Nov 15 '12 at 09:25
  • The link says: "When a data file has a known format... it *may* be appropriate to read it with `fscanf`" (emphasis mine). That is not a recommendation to use `fscanf`, nor is there anything there that says it is preferable to use over `fgets` + `sscanf`. As for the question: regardless, I would not recommend using `fscanf` (especially in a way that does not explicitly check buffer sizes) to anyone not already well-versed with its quirks. – jamesdlin Nov 15 '12 at 10:53
  • @spin_eight +1 for nice thinking. – joey rohan Nov 15 '12 at 13:09