Valhalla Legends Forums Archive | C/C++ Programming | Question Refering to Databases

AuthorMessageTime
AC_Drkan
I was wondering,
How in the world do you read a file for something like "username = "
then assign the variable following that to something?

ex:

[code]
username = blah

szUsername="blah"
[/code]
June 8, 2004, 8:16 PM
Moonshine
Read the file into a buffer, then parse the data accordingly. These functions will help you:
strchr(), strrchr(), strtok(), strstr(), strcmp(), stricmp()

Note that stricmp is windows specific, it's strcasecmp() on *nix.
June 8, 2004, 9:46 PM
Mephisto
If it's just a username, and there will be no spaces, and you aren't concerned about buffer overflows (though for the most part, it's your fault if it occurs if you are directly handling the file/program yourself):

[code]#include <stdlib.h>
int main(void) {
FILE *fp = fopen("database.txt", "r");
char username[512] = '\0';
fscanf(fp, "Username = %s", username);
printf("The username is %s", username); // should print whatever was following Username =
return (0);
}[/code]

Note: fscanf is vulnerable to buffer overflows if used improperly, so keep this in mind. Additionally, fscanf will discontinue reading after the line has ended or has encountered a whitespace. If you wish to solve these problems, you'll need to invoke other methods using some of the provided functions in the stdio.h and fstream libraries, or even windows.h. Moonshine has provided some of these. Additionally, when your database contains more than one user, such as 50, and each user has one line (50 lines) you'll often find you'll need to have some sort of loop structure to iterate through the file until you reach EOF (end of file). So something such as while (fgets(buffer, sizeof(buffer), fp) != EOF) { ... }.
June 8, 2004, 10:34 PM
Zeller
He might not be using vc++. This should cover what you need to know.

http://www.cplusplus.com/doc/tutorial/tut6-1.html
June 8, 2004, 11:43 PM
Moonshine
[quote author=Zeller link=board=30;threadid=7158;start=0#msg64253 date=1086738227]
He might not be using vc++. This should cover what you need to know.

http://www.cplusplus.com/doc/tutorial/tut6-1.html
[/quote]

Neither what Mephisto or I wrote was VC++ specific.
June 9, 2004, 12:54 AM
Mephisto
[quote author=Zeller link=board=30;threadid=7158;start=0#msg64253 date=1086738227]
He might not be using vc++. This should cover what you need to know.

http://www.cplusplus.com/doc/tutorial/tut6-1.html
[/quote]

Visual C++ is nothing but C++ with some Microsoft extensions. It's all backwards compatable, so ANSI-C++ and Microsoft standards will compile in VC++. I don't believe anything in C/C++ FILE I/O has any Microsoft extensions in Visual C++. Even the FILE I/O functions and handles in the Win32 API (or windows.h rather) don't fit in the extensions of Visual C++...
June 9, 2004, 2:14 AM
Zeller
yea, your right. I just quickly assumed it was vc++ when I saw fopen for some reason. dont know why though :-[
June 9, 2004, 3:50 AM
UserLoser.
[quote author=Mephisto link=board=30;threadid=7158;start=0#msg64229 date=1086734050]
If it's just a username, and there will be no spaces, and you aren't concerned about buffer overflows (though for the most part, it's your fault if it occurs if you are directly handling the file/program yourself):

[code]#include <stdlib.h>
int main(void) {
FILE *fp = fopen("database.txt", "r");
char username[512] = '\0';
fscanf(fp, "Username = %s", username);
printf("The username is %s", username); // should print whatever was following Username =
return (0);
}[/code]

Note: fscanf is vulnerable to buffer overflows if used improperly, so keep this in mind. Additionally, fscanf() will discontinue reading after the line has ended or has encountered a whitespace. If you wish to solve these problems, you'll need to invoke other methods using some of the provided functions in the stdio.h and fstream libraries, or even windows.h. Moonshine has provided some of these. Additionally, when your database contains more than one user, such as 50, and each user has one line (50 lines) you'll often find you'll need to have some sort of loop structure to iterate through the file until you reach EOF (end of file). So something such as while (fgets(buffer, sizeof(buffer), fp) != EOF) { ... }.
[/quote]

I'm no expert, yet, but you should also check if the file was opened without any errors, and close it after you're done with it
June 9, 2004, 4:29 AM
Maddox
He was just giving an example. ::) It should also be %511s as well.
June 9, 2004, 5:31 AM
Skywing
Remember that you won't be able to have spaces in the strings scanned in. This can lead to unexpected results in some cases if you aren't aware of it.
June 9, 2004, 6:04 AM
Mephisto
[quote author=Skywing link=board=30;threadid=7158;start=0#msg64310 date=1086761060]
Remember that you won't be able to have spaces in the strings scanned in. This can lead to unexpected results in some cases if you aren't aware of it.
[/quote]
I already noted that scanning in variables (even though I specifically addressed fscanf) would be disastrous at runtime if you were expecting it to scan in the whitespace, which it will not).

[quote author=UserLoser. link=board=30;threadid=7158;start=0#msg64293 date=1086755357]
I'm no expert, yet, but you should also check if the file was opened without any errors, and close it after you're done with it
[/quote]
Checking to see if a file was successfully opened to me is pointless. I've never once with FILE I/O usage had a failure in opening the file successfully. Granted though, you have a point because you're reading from the file, the file may not even exist, and there would be nothing to read into a buffer if you made it, so go figure...It's not really as necessary when writing to the file because it will automatically make the file and open it for you if it doesn't exist. Additionally, if you're not using the file pointer for anything else (even if you were it's not necessarily necessary) calling fclose isn't really necessary, especially in such a small example because the ending of the program takes care of everything.

[quote author=Maddox link=board=30;threadid=7158;start=0#msg64303 date=1086759114]
He was just giving an example. ::) It should also be %511s as well.
[/quote]
%s is fine, as long as you're careful about your buffers you should be fine without specifying a scan length into the buffer. I've never had problems. Though if you find it necessary to make sure your buffers are not going to overflow, you can use %511s; or whatever number you wish your buffer to hold (what it's specified to).
June 9, 2004, 7:17 AM
Adron
[quote author=Mephisto link=board=30;threadid=7158;start=0#msg64312 date=1086765468]
I already noted that scanning in variables (even though I specifically addressed fscanf) would be disastrous at runtime if you were expecting it to scan in the whitespace, which it will not).
[/quote]

I'd like to point out that for those of us who know the language and how to use the functions, fscanf will scan in whitespace just fine if we want it to.



[quote author=Mephisto link=board=30;threadid=7158;start=0#msg64312 date=1086765468]
Checking to see if a file was successfully opened to me is pointless. I've never once with FILE I/O usage had a failure in opening the file successfully.
[/quote]

This shows that you are a very inexperienced programmer. I can't count the number of failures to open files I've had. And most have been properly handled, which is critical to do.


[quote author=Mephisto link=board=30;threadid=7158;start=0#msg64312 date=1086765468]
Granted though, you have a point because you're reading from the file, the file may not even exist, and there would be nothing to read into a buffer if you made it, so go figure...It's not really as necessary when writing to the file because it will automatically make the file and open it for you if it doesn't exist.
[/quote]

It's necessary when opening a file for writing as well. There are many reasons that an open for writing could fail.

[quote author=Mephisto link=board=30;threadid=7158;start=0#msg64312 date=1086765468]
Additionally, if you're not using the file pointer for anything else (even if you were it's not necessarily necessary) calling fclose isn't really necessary, especially in such a small example because the ending of the program takes care of everything.
[/quote]

Whether you're using the file pointer for something else or not doesn't seem relevant to the calling of fclose. You can reuse a variable without closing the file. And you don't reuse the actual storage area, since that's allocated for you by fopen.

Yes, in a small program, you can skip it, but it's a good habit always to close what you open. If you make instead make it a habit not to close files, you'll end up debugging weird errors in large programs.
June 9, 2004, 9:52 AM
Mephisto
Thanks. Anyways, Adron, how do you scan in the whitespace, because I've been curious to know if you could...

And just for the record, I do check to see if the file was successfully opened and I do close it in programs I make that are useful. As you've noted it's not really necessary in a small example program. But I haven't experienced a file opening error before...So I find it hard to relate to getting file opening errors a lot.

And I apologize for presenting my "inexperience" to the forums...
June 9, 2004, 7:18 PM
Adron
[quote author=Mephisto link=board=30;threadid=7158;start=0#msg64365 date=1086808711]
Thanks. Anyways, Adron, how do you scan in the whitespace, because I've been curious to know if you could...
[/quote]

You use the %[] format specifier, putting the acceptable character specification between the brackets. To read a line consisting of three columns, separated by = and a tab:

[code]
char line[] = "column number 1\tcolumn number 2=last column\n";
char val1[101], val2[101], val3[101];
if(sscanf(line, "%100[^\t]\t%100[^=]=%100[^\n]\n", val1, val2, val3) == 3)
printf("Value 1: %s\nValue 2: %s\nValue 3: %s\n", val1, val2, val3);
else
printf("Error!\n");
[/code]

I would suggest that you read lines from the file using fgets, and then process them with sscanf instead of reading with fscanf, if there's a risk of errors in the file. It's much easier to handle bad lines that way. Any line that doesn't pass the scanf can be simply ignored, without you having to manually skip forward to the next linefeed.


[quote author=Mephisto link=board=30;threadid=7158;start=0#msg64365 date=1086808711]
And just for the record, I do check to see if the file was successfully opened and I do close it in programs I make that are useful. As you've noted it's not really necessary in a small example program. But I haven't experienced a file opening error before...So I find it hard to relate to getting file opening errors a lot.
[/quote]

I get it often enough. Things that can go wrong include being in the wrong current directory, misspelling the file name, missing a double \ in a path, files on a network drive that isn't there, someone removing the file, read-only files (happens when you copy your program + files from a cd-rom), sharing violations, ntfs acls or file modes limiting access, ....


[quote author=Mephisto link=board=30;threadid=7158;start=0#msg64365 date=1086808711]
And I apologize for presenting my "inexperience" to the forums...
[/quote]

I don't mind that you post examples without error handling, leaving that out is normal to make the code clearer. Saying that error handling is "pointless" is wrong though.

In an application you're giving out to people, or using yourself more than very briefly, you should always add error handling for errors that can be expected. A file failing to open should be an expected error - it will happen sooner or later in a changing environment.
June 9, 2004, 9:27 PM

Search