If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register or Login
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

Re: Assigning a value to struct variables?

@2kaud: Sorry, can you please explain this line:

if (char *nl = strrchr(acct.name, '\n')) *nl = 0;

I haven't used that many libraries yet, except for stdio/stdlib/math, so please excuse me. And I'm really confused about the pointers (*). Can I get a layman explanation from you, 2kaud? All the stuff I've read so far can be a little bit too confusing for a beginner like me, unfortunately...

fgets(..) will read the next line from the file and put a maximum of 59 chars into acct.name and null terminate it. fgets returns a pointer to acct.name on success or null on failure. fscanf returns the number of arguments actually assigned a value - which should be 3 in this case. So if fgets returns a non-null value and fscanf returns 3 then the test succeeds. Note that fscanf is only evaluated if fgets returns a non-null value.

Code:

if (char *nl = strrchr(acct.name, '\n')) *nl = 0;

strrchr searches from the end of acct.name until it finds a new line ('\n'). If it does find one then it returns a pointer to it otherwise it returns null. So this assigns the returned pointer from strrchr to nl and if this is non-null the test succeeds and then replaces the char pointed to by nl with a 0 which overwrites the \n and terminates the string.

All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

Re: Assigning a value to struct variables?

I was told that using !feof() is a bad thing to do, so I guess I'll stick to my while statement? So the output is still the same. I really don't know what I'm doing wrong here, as to why the extra digits are appearing in the bal variable. I need to get the exact value since I'll be making computations using it...

Re: Assigning a value to struct variables?

Originally Posted by riechan

I need to get the exact value since I'll be making computations using it...

Then you can't use double ot float.

This has been discussed many times here -- if you want accuracy, you need to use all integers or get a library of code that handles exact math. Doubles and floating point variables are by their very nature, inaccurate.

Also, if you're using Turbo C, then the output we get will be different than the output that you will get when it comes to floating point values, since in all likelihood, others are using more modern compilers (Visual Studio or gcc). So comparing what 2kaud gets or laserlight gets in terms of that float variable is not an indicator of whether your program works or not.

I once had to maintain two bodies of code, one coded with Borland C++, the other with Visual Studio 6.0. The floating point calculations when applied to both compilers produced different numbers in the 4th or 5th decimal place.

Again, all of this is caused by inaccuracies of float and double. For float, there is no standard way that a compiler can represent that number. It could be IEEE or a home-grown version of characteristic/mantissa representation of that number (and I believe Turbo C even emulates floating point values via software, so that is another wrinkle).

Re: Assigning a value to struct variables?

I need to get the exact value since I'll be making computations using it...

As has been said many times before on these threads, some decimal numbers can't be represented exactly as binary - the same way that 1/3 can't be represented exactly as a decimal. That's one reason why I used the %.2f format in the printf statement. However, consider storing bal as a double rather than a float. On my MSVS this gives a more accurate number representation. Also your fscanf format string is not correct. It will not work if there is more than 1 record in the file. Look at my fscanf format.

I've changed my program to use double rather than float and I'm now printing the whole balance rather than just 2dp.

On your turbo c system, try this program as it stands without changes and see what the output produces with the same data as I've used.

All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

Re: Assigning a value to struct variables?

On your turbo c system, try this program as it stands without changes and see what the output produces with the same data as I've used.

I would also be interested in seeing the results.

I don't think that Turbo C used IEEE doubles (maybe I'm wrong), but I do remember that their floating point was either emulated, or if you had the 8087 chip, done using that FP coprocessor (which predates the IEEE standard used by Visual Studio / gcc).

I checked this using a c compiler and it compiles OK and produces the same result as above.

So, I changed it up to:

Code:

char *nl;
...
if (*nl = strrchr(acct.name, '\n')) {
*nl = 0;
}

And now I'm getting a nonportable pointer conversion/possibly incorrect assignment error. When I use this however:

Thats because strrchr returns a pointer and you are assigning a pointer value to a char!

nl is a pointer to a memory location in which a char can be stored. *nl refers to the actual char stored at the memory location pointed to by nl. I know this can be confusing!

You need

Code:

char *nl;
...
if (nl = strrchr(acct.name, '\n')) {
*nl = 0;
}

Last edited by 2kaud; July 30th, 2013 at 03:01 PM.

All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

Re: Assigning a value to struct variables?

@2kaud: Just made a couple of changes with the code. I used your test data and the results were all correct, surprisingly:

You must also do one more thing, and that is to #include all of the appropriate headers that correspond with the functions you're calling.

For example, did you #include <string.h>? You're calling string functions, but I don't see that #include.

The reason why it is very important for a 'C' program to #include the headers is that a program can and will run differently if you leave them out. For 'C', if a function is undefined, 'C' defaults the return value to int, and that can be disastrous.

So next time, please post the headers you have included, since a lot of weird output for a 'C' program stems from not including the neessary header files (There was a thread that went on for days, with the issue being exactly that -- a 'C' program that didn't #include the headers, and the poster couldn't understand why they were getting the wrong output).

Re: Assigning a value to struct variables?

I suppose I'll be using long integer for the time being, since floating point numbers have been very erratic. But, I'll revise the data types once I finish coding everything. I'll follow up on you guys with the finished code, I think.

I have a quick question though, when I tried to assign a value to acct.pin:

Code:

acct.pin = pina;

Both acct.pin and pina are string variables with a length of 10. I got an error: "Lvalue required"? I didn't get that error though when I tried using it with integer variables (acct.bal)

Re: Assigning a value to struct variables?

I have a quick question though, when I tried to assign a value to acct.pin:

Code:

acct.pin = pina;

Both acct.pin and pina are string variables with a length of 10. I got an error: "Lvalue required"? I didn't get that error though when I tried using it with integer variables (acct.bal)

acct.pin is a fixed pointer (determined by the compiler) to a memory location where the data resides. So what you are doing isn't valid as you are trying to change the memory location to which acct.pin points. To copy the data from the char array pointed to by pina to the char array pointed to by acct.pin use

Code:

strcpy(acct.pin, pina);

Note that the memory storage allocated for acct.pin must be at least the number of characters copied from pina (not forgetting the terminating null!) - otherwise a buffer overflow occurs.

An Lvalue is an expression that can be used on the left of an assignment. In the statement

Code:

a = 3;

a is the Lvalue and 3 is the Rvalue. If this was reversed

Code:

3 = a;

then here 3 is the Lvalue and a is the Rvalue. But 3 cannot be assigned a value so this is an error. In your example, acct.pin would be the Lvalue, but you can't assign to this hence the compiler error. This is why you often find if statements of the form

Code:

if (3 == a) ...

rather than

Code:

if (a == 3) ...

both perform the same test, but if the equality relational operator was mistyped as

Code:

if (3 = a) ...

then this would cause a compiler error as 3 is not a valid Lvalue. But the (probably incorrect) statement

Code:

if (a = 3) ...

is valid syntax and assigns a the value of 3 which is the value of the if condition. The condition is then always non-zero so the if statement always evalutes to true.

Last edited by 2kaud; July 31st, 2013 at 05:49 PM.

All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

Re: Assigning a value to struct variables?

I have a quick question though, when I tried to assign a value to acct.pin:

Code:

acct.pin = pina;

Both acct.pin and pina are string variables with a length of 10. I got an error: "Lvalue required"? I didn't get that error though when I tried using it with integer variables (acct.bal)

All 'C' books and materials make it a point that null-terminated char arrays are not the same as simple variables. Since they are arrays, you must use functions to manipulate them. Assignment and comparison of arrays cannot be done in C (and in C++) using "simple" operations such as "=" and "==". You must use the functions defined in <string.h> to manipulate null-terminated strings as one entity (as opposed to a single character at a time).

So are you using a 'C' book? If so, I suggest you read carefully the chapter on null-terminated char arrays, as that is a foundation of 'C' programming when it comes to strings.