Forums

Forums (http://www.abandonia.com/vbullet/index.php)
-   Tech Corner (http://www.abandonia.com/vbullet/forumdisplay.php?f=23)
-   -   C code noob's corner (http://www.abandonia.com/vbullet/showthread.php?t=32006)

Mighty Midget 24-08-2013 06:15 PM

C code noob's corner
 
I am (trying???) to learn C as part of my studies. Things are going fairly ok in programming but extending one task is giving me some grey hairs.

This code will output the size in bytes for various types of variables, as well as the value range. However, things are tricky when it comes to the
float
double
both signed and unsigned, long and short, if it's there, I want to include it in the program.

Code:

#include <stdio.h>
#include <limits.h>
#include <float.h>

int main()
{
    printf("char... \tsize: %d byte \t", sizeof(char));
    printf("%d to %d \n", CHAR_MIN, CHAR_MAX);
    printf("unsgn char... \tsize: %d byte \t", sizeof(unsigned char));
    printf("0 to %d \n", UCHAR_MAX);
    printf("short int... \tsize: %d bytes \t", sizeof(short int));
    printf("%d to %d \n", SHRT_MIN, SHRT_MAX);
    printf("unsgn s int... \tsize: %d bytes \t", sizeof(unsigned short int));
    printf("0 to %d \n", USHRT_MAX);
    printf("long int... \tsize: %d bytes \t", sizeof(long int));
    printf("%ld to %ld \n", LONG_MIN, LONG_MAX);
    printf("unsgn l int... \tsize: %d bytes \t", sizeof(unsigned long int));
    printf("0 to %u \n", ULONG_MAX);                                           
    printf("float... \tsize: %d bytes \n", sizeof(float));
    printf("double... \tsize: %d bytes \n)", sizeof(double));
return 0;
}

As you can see, the MIN and MAX are missing for the last two, the float and double, and I haven't figured out if there are any long/short/signed/unsigned versions of these two.

The float header was included as I messed around with different float constants not getting anywhere.

Any input, so to speak, would be greatly appreciated!

Japo 25-08-2013 07:25 PM

The short answer is that, if you haven't found those constants in the same place as the rest, they probably don't exist. Although I'm not sure, and there's always a way to find those values out. Such constants aren't required by the C specifications; whether they're defined or not depends on the implementation (compiler) that you're using.

In C, not even the bit sizes and ranges of data types are defined uniquely. For example an int will be 32 bits long in a 32-bit environment, and 64 bits long in a 64-bit one. Most more recent languages do specify fixed sizes and ranges for all data types, but C is different in this regard.

PS: there's a sub board for this:
http://www.abandonia.com/vbullet/forumdisplay.php?f=25

jonh_sabugs 27-08-2013 05:40 AM

Actually, float.h contains the constants FLT_MAX, FLT_MIN, DBL_MAX and DBL_MIN, which are the largest and smallest numbers you can represent in those types. These values are ANSI, and must exist in any standard C compiler. It seems, though, that these values are just the minimum/maximum values that the compiler must accept (i.e. a float could have numbers larger than FLT_MAX, but it must be able to represent at least numbers up to FLT_MAX).

Japo 27-08-2013 03:34 PM

Thanks John and sorry MM if I was misleading. I'm not familiar with the different C standards, but I know that data types in C are dependent on the platform (bitness), although the compiler takes care of parsing the correct #define's depending on the environment.

Look what I found:
http://en.wikipedia.org/wiki/C_data_...he_basic_types

jonh_sabugs 27-08-2013 03:53 PM

Hello Japo. You are correct, C data types may have different sizes in different implementations, which can be annoying, but the ANSI standard defines a minimum range the types must represent. Take a look here:

http://www.acm.uiuc.edu/webmonkeys/b...guide/2.4.html

Which was actually a good idea from the guys who created the standard, otherwise portability would be a pain.

Japo 27-08-2013 04:27 PM

Thanks I didn't know there was a minimum irrespective of platform. By "the standard" I suppose you mean C89?

Anyway MM keep the questions coming, I hope you stick to learning! BTW to be real standard C you should define "int main(void)", not "int main()"

jonh_sabugs 27-08-2013 04:37 PM

That's a good question. I originally learned about the types restrictions as being ANSI, but I don't know which of the standards issued it.

Mighty Midget 27-08-2013 05:07 PM

Thanks tons to both of you! And don't worry, Japo, I will keep asking :D I will need all the inputs I can get. This school isn't wasting time or waiting for stragglers!

The Fifth Horseman 27-08-2013 07:44 PM

Quote:

As you can see, the MIN and MAX are missing for the last two, the float and double, and I haven't figured out if there are any long/short/signed/unsigned versions of these two.
IIRC, long double is a thing. Float is what you'd describe as "short double", really.
As per the IEEE-754 specification, all floating point numbers are signed. See http://en.wikipedia.org/wiki/IEEE_floating_point for more details. :) And thank your deity of choice that you don't have to learn that in order to implement floating point operations in assembly... completely on CPU. :p

Also, you might be missing wchar_t but I don't remember for sure if it's a C or C++ thing.
Quote:

Originally Posted by Japo (Post 456469)
In C, not even the bit sizes and ranges of data types are defined uniquely. For example an int will be 32 bits long in a 32-bit environment, and 64 bits long in a 64-bit one. Most more recent languages do specify fixed sizes and ranges for all data types, but C is different in this regard.

IIRC, there is an include for that sort of thing (though my memory fails to provide the name).

Japo 27-08-2013 09:23 PM

Quote:

Originally Posted by The Fifth Horseman (Post 456543)
IIRC, there is an include for that sort of thing (though my memory fails to provide the name).

But I don't think it's ANSI... Microsoft has its own extended data type system at least since they created the Windows API:
http://msdn.microsoft.com/en-us/library/aa383751.aspx

I think wchar_t is C++ (never used C++ a lot) but I don't think it's C, unless it was introduced in C99, or C11 (most popular compilers don't follow even C99).

Mighty Midget 03-09-2013 03:26 PM

Ok, here's a good Q about ASCII codes:

If I hold down left tab and type 248, I get °
If I hold down left tab and type 0248 I get ø

I'm trying to have this program type out an ø but starting a decimal number with 0 is not going to work so any idea how I can have the program print out an ø and not a °?

Japo 03-09-2013 05:07 PM

Short answer: there's no way to print "ø" with the standard library. You're barking at the wrong door. Either you want a simple console C program, or you want to print strange characters. You can of course switch to a graphic mode (again not in the standard library) and use some font library. My advice is that you continue your C learning with interesting programs that are practical to write in C, not these pointless bells and whistles, you won't learn anything useful, let alone nowadays. Use "oe" instead etc.

Forget about "°", it's completely unrelated. Windows extended the number of characters that you can create with the numpad in that way, but that doesn't mean that the ASCII character "x" has any relationship with the character "0x". You just get sixteen times as many possible codes or characters.

Portable C (the standard library) supports ASCII characters (0-255) only--and be careful with the extended set (from 128 to the final end 255--see below why).

Nowadays there are simpler ways to get international characters as well as fancy windows and whatnot. Nobody uses the console, and when they do, they don't ask it to display funny stuff.

Back in the day MS-DOS came up with a way to print international characters on the console: the commands "MODE con codepage prepare" and "... select". Since there are many more than it's not possible to get all international characters. IIRC these commands replace the standard extended set (128-255) with country-specific characters (you select the country when you call the command, you can't have all characters at once). On the other hand, this would break the display of programs that rely on the standard extended ASCII set. Moreover, the MODE command is specific to MS-DOS; for example it doesn't come with DOSBox.

The Fifth Horseman 03-09-2013 05:13 PM

The first as ASCII 0xF8. The second is Unicode 0x00F8.
Option A, figure out a way to output unicode instead of ASCII.
Option B, figure out which codepage you should be using in order for 0xF8 to map to ø and how to switch to that codepage.

Mighty Midget 03-09-2013 06:50 PM

I have it working perfectly for both å and æ, but not for ø. ASCII for å and æ both start with a non-0 and it works. The thing is ø starts with a 0, withouth the zero it's the code for a plain o.

What I'm not getting is why å and æ are ok but ø has a "useless" code.

I wrote a program to give me the ascii values for any sign and for all but ø it worked. For ø I got the value for o.

As for the whys and all that, this is a school assignment so style and reason are irrelevant I guess.

Japo 03-09-2013 07:06 PM

2 Attachment(s)
Again, the codes that start with 0 on the Windows charmap are NOT ASCII.

http://en.wikipedia.org/wiki/ASCII
Quote:

Not to be confused with MS Windows-1252, also known as "ANSI", or other types of Extended ASCII, often just called "ASCII".

The American Standard Code for Information Interchange (ASCII) is a character-encoding scheme originally based on the English alphabet that encodes 128 specified characters
See attachments.

You'd need to change codepage--which is a platform-dependent operation when available. Honestly if I were you I'd be studying interesting algorithms instead of doing archeology in the museum of horrors.

Mighty Midget 03-09-2013 07:34 PM

If I were you, I'd see it the same way but unfortunately, this assignment is pretty well defined and is going in for review.

Japo 03-09-2013 09:34 PM

OMG, it reminds me when in college they made us program a database from scratch with binary files. Who wants to use already available and specially designed tools like SQL? :rolleyes: Some teachers seem to think that it's more educative to make a wheel with clay than to build a working bicycle with available materials and less effort.

And localization is so important for beginning programmers to learn... Or for anyone for that matter... :rolleyes:

In what platform must you do this? Windows? What compiler must you use or are you using? What libraries are you allowed to use?

The Fifth Horseman 03-09-2013 10:25 PM

Look at it this way: your software is outputting the correct code. Your shell is using a codepage where the character maps to something else than it should. The simple solution is to change the codepage such as by calling system("CHCP 1142");

Japo 03-09-2013 10:29 PM

Hmm it's been a while since I learned C... :palm: Apparently (of course) Unicode is now part of the standard library. See versions of standard functions that include the letter w, for example:

http://msdn.microsoft.com/en-us/library/wc7014hz.aspx

Wide char strings are made of wchar_t instead of char, and their literals are preceded with an L:

Code:

wprintf(L"Hell\u00f8 wørld! %s",
        L'ø' == L'\u00f8' ? L"True" : L"False");

To change the console mode from ANSI to Unicode (solving the °/ø confusion), apparently you can do this:

Code:

#include <io.h>
#include <fcntl.h>

Code:

_setmode(_fileno(stdout), _O_U16TEXT);
Make sure though that the font used by your console window does have those strange characters. It's not the case by default in my case, but you can right-click on the console window title bar and go to choose properties > font tab. Then restart your program, because the font will have transformed the strange characters to ? or normal letters before outputting them. (See how pointless all this is...!)

jonh_sabugs 03-09-2013 11:30 PM

I don't think wchar_t and unicode strings are part of standard C library, only C++. I know that compilers such as GCC do not implement wchar family for C code.

Japo 04-09-2013 06:02 AM

wchar_t is defined even in C89, but you have to include <stdlib.h> or <stddef.h>.

http://en.wikipedia.org/wiki/Wide_character#C.2FC.2B.2B
Quote:

The wide characters are defined using datatype wchar_t, which in the original C90 standard was defined as
"an integral type whose range of values can represent distinct codes for all members of the largest extended character set specified among the supported locales" (ISO 9899:1990 §4.1.5)
I've even tried it in TurboC++ 1.01 for DOS (not the Unicode program above, only one with a wchar_t instead of char, and literals preceded with L. Of course the Unicode part can be platform dependent, but I think nowadays it'll be standard.

Why a teacher would make someone who's starting to program deal with this, is beyond me...

jonh_sabugs 05-09-2013 08:02 PM

You are right, I stand corrected.

Japo 05-09-2013 09:29 PM

Yep I had no idea myself, I just researched it on the go, so I was learning too. :) I've tried enabling the "compile as C" (as opposed to C++) in Visual Studio and this code works, I think it should be portable to any Unicode-enabled platform:

Code:

#include <stdio.h>
#include <stddef.h>
#include <io.h>
#include <fcntl.h>

int main(void)
{       
        _setmode(_fileno(stdout), _O_U16TEXT);
        wprintf(L"Hell\u00f8 wørld!\n");
        return 0;
}


jonh_sabugs 05-09-2013 10:14 PM

Well, we are always learning. I researched a bit more and it seems wchar_t has no defined size, and could be only 8 bits wide, so it doesn't look portable.

Japo 05-09-2013 10:35 PM

As portable as it gets in this case, ;) I think. In practice I think in most (all non embedded) implementations wchar_t will be wider than 8-bit, but the bigger risk is no Unicode support (probably compile time error that _O_U16TEXT isn't defined, like I get in TC++ 1.01). That's why I like C# or D in which regular strings are always already Unicode. Also standards are as useful as they are but not more (ask SQL...)

Mighty Midget 02-07-2014 08:45 PM

I need to ask again:

This time, I'm trying to write a code (C) that will generate prime numbers. Thing is, all the sample code I've seen checks each number up against all other, lower, natural numbers but the point is, that is not necessary and in fact will save me a LOT of time as the primes get larger if I only check up against the lower primes I generate.

The idea is to write the primes to a txt file (since 10,000,000,000 primes can take up a lot of memory), and read this list to check the candidate number.

Problem is: I use fscanf and it really isn't playing ball. Either it reads the entire list as one number or it stops reading as soon as it hits a space or new line.

Is there a neat way of reading each number in the list while allowing for space and new line?

Also, is there a way to jump straight to the last number in the list instead of having to go through the entire nightmare everytime I want to resume the job?

The idea here is, when I want to resume the job after a break, I want the program to pick the last prime found + 1 as the new candidate.

Japo 05-07-2014 01:04 AM

The problem is that if you don't want to read the whole file in one go, you need the FILE pointer to be moved from the start of the file to where you finished the last read.

Use fread(), it moves the pointer automatically, and allows you to read any number of numbers in each call. I think binary mode will be better than text.

http://msdn.microsoft.com/en-us/library/kt0etdcs.aspx
Quote:

The file pointer associated with stream (if there is one) is increased by the number of bytes actually read.


The current time is 04:15 AM (GMT)

Powered by vBulletin® Version 3.7.1
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.