Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Actually, AD, in this case it is possible to use Visual Studio as an IDE for NASM; this page explains how to integrate NASM with VS6. It's a bit dated, so some of the details about NASM itself may be off (e.g., paths), but it shouldn't take much tweaking to do it.

OTOH, the OP probably should at least be familiar with the process of assembling a program from the command line first, as you'd need to understand how things like paths work and how the command-line options are set for the instructions on that page to make sense. Also, with VS6, you won't get any syntax highlighting and other nice features for assembly (though with later versions of VS, there are plug-ins that support that); it would basically be a fancy text editor. Unless your goal is to integrate the assembly code with a C++ or VB program, Visual Studio 6 probably isn't the best choice of IDE for NASM.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

It could be done with a switch() statement, and very likely I would have done it that way if I were writing it myself, though I wasn't certain if you were familiar with those yet. There are also various esoteric tricks one could do with while() , or for() , or the ternary operator, but I wouldn't think your professor was expecting you to do something like that.

I can't think of any way to do it without some form of conditional statement, however.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

OK, I did mess up a bit; the professor is assuming that you already calculated the monthly fees, and are passing it into the the function. I missed that, but it's easy enough to fix:

// your function discFee must be inserted here

// returns -1 if the total number of activities is less than 0 or greater than 7
float discFee (int sports, int otherActivities, float monthlyFee){
    float discount;

    int activities = sports + otherActivities;

    // you only need to set the value of discount in the if statements
    if ((activities >= 0) && (activities < 4)){
        discount = 0.00;
    }

    if ((activities == 4 ) || (activities == 5)){
        discount = 75.00;
    }

    else if ((activities == 6 ) || (activities == 7)){
        discount = 125.00;
    }
    // all other values for activities are invalid, 
    // return an error
    else {
        return -1.00;
    }

    return (monthlyFee - discount);
}

You don't need to calculated the monthly fee inside this function; it's already been done by calcFee() , and the result of that is what the main() function is passing into discFee() .

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Sorry for the repeated edits; every time I saved it, I noticed something else that could be improved upon. I think that it's in a decent state now.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

It has to do with the additional declarations inside the if statements, and the rules for scoping of variables. By re-declaring the variable newFee inside of the if statements (as a different type, at that), you are masking the original declaration of newFee at the beginning of the function. Therefore, the newFee variables inside the if statements are entirely new variables, ones which are only in scope for the if statements they are inside. When the if statement ends, that variable vanishes, and the one scoped at the beginning of the function - which never gets set - becomes the one returned.

The solution is simply to eliminate the superfluous declarations. Here's a corrected version, with some additional fixes for you as well:

// your function discFee must be inserted here

// you only need to get numSport and numOther from the caller;
// monthFee is calculated inside the function
// returns -1 if the total number of activities is less than 0 or greater than 7
float discFee (int sports, int otherActivities){
    float discount;

    int activities = sports + otherActivities;

    // monthFee is the calculated monthly fee, as per calcFee()
    float monthlyFee = calcFee(sports, otherActivities);

    // you only need to set the value of discount in the if statements
    if ((activities >= 0) && (activities < 4)){
        discount = 0.00;
    }

    if ((activities == 4 ) || (activities == 5)){
        discount = 75.00;
    }

    else if ((activities == 6 ) || (activities == 7)){
        discount = 125.00; …
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

As a side note, you really need to learn how to indent your code for readability. While there are many different indent styles, and you're under no absolute obligation to use a specific one, it is important that you indent the code in some consistent manner that others will be able to follow easily. Fortunately, most IDEs (e.g., Code::Blocks, Visual C++ Express) and programming editors (e.g., EMACS, Notepad++, Geany) have an auto-indent feature of some sort, so you may be able to apply that and save a lot of effort.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Not really; it isn't like a paid help line would be where there is an guarantee of a response. You might get an answer in two minutes, or in two days, or never. That's just the nature of a public forum.

Now, there are members from all around the world, and for a basic question odds are good someone can get to it fairly quickly, but I wouldn't say that it is something you should rely upon in a real time crunch, especially as the questions get more complicated.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

EDIT: Apparently, you posted your corrected version just minutes before I posted this answer. You seem to have the basic idea now, yes.

You're on the right track from where you'd been, but you still haven't quite grasped the function syntax. Specifically, you need to remove the semi-colon at the end of the function header, and put braces around the body of the function:

float calcFee (int NumSport, int NumOther)
{
    float totFee;

    totFee = NumSport * 120 + NumOther * 100;

    return (totFee);
}

Basically, when you write a function, the form of it goes something like this:

<return-type> <function-name> ( <parameter-list> )
{  
    <body>;
}

You always have to have the braces around the body of the function.

Here is a more or less working version of your code (some unneeded variables have been removed):

//Assignment 2 Question 4a
#include <iostream>
using namespace std;
const float feeSport = 120.00;
const float feeOther = 100.00;
const float discount = 50.00;
const float creditS = 0.75;
const float creditO = 0.50;
//Your function calcFee must be inserted here

float calcFee (int NumSport, int NumOther)
{
    float totFee;

    totFee = NumSport * 120 + NumOther * 100;

    return (totFee);
}


int main()
{
    int nrSport, nrOther;
    float totFee = 0, totOther = 0;
    do
    {
        cout << "A total number of 7 activities are allowed:-" ;
        cout << endl <<endl;
        cout << "Please enter the number of sport activities : " << endl;
        cin >> nrSport; …
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

I'm still not certain what you mean by 'recognizing' the drive as A:\ (the backslash is the DOS and Windows directory indicator; it's in Unix and Linux that it is the forward slash). A: is just a name which the OS assigns the drive; it is up to you whether or not to do the same, or use some completely different scheme if you'd prefer.

Let's look at this operationally: what is it you want the OS to do? Are you looking for it to put an A:\> prompt after loading? Do you want to know how the OS can read the drive with the path rooted at A:\ and find a file there? What behavior are you looking for?

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Note also that multiplying by %ebx is not enough; you need to take 10 to the power of %ebx - 1. Does the assignment allow you to use the pow() function?

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

I think that the issue the line

imul	%ecx		/* eax = eax*ecx */

Here you should be multiplying by %ebx rather than %ecx, as %ecx still holds a pointer to the end of the string, whereas %ebx should be holding the decimal place which you want to multiply by.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

This may seem simple, but the question carries with it more than you might suppose. First off, what do you mean by 'a: drive'? This may seem like an obvious point, but it isn't: the meaning of the drive lettering and so on is a feature of the OS itself, and no every operating system sees and uses drives the same way.

If the question is, 'how do you get the system to boot from the floppy drive?', then the answer is that it isn't a matter of the OS at all, but of the system CMOS settings. You'll need to go into the System Setup and make some selection regarding boot sequence (just where it is and what is it called will depend on the particular model of PC). Set the Floppy Drive (or FDD or whatever it is referred to) as the first boot device, and you should be able to at least get started.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Given your stated preference for MS-DOS, you might want to start with FAT12 as your floppy disk filesystem, and go from there. FAT12 has the advantage of being easy to implement and designed for bootable systems, and has the added advantage that the files would be readable by Windows, if you do it right.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

To answer the second question first, yes, you'll want to copy both of the binary sections into the boot image, then copy that to the floppy. Assuming you have a blank image file already, and have already assembled the source files to the binaries, the following batch file should do the trick:

copy blankdisk.img boot.img
dd count=1 if=verbum.bin of=boot.img seek=0
dd count=1 if=stagetwo.bin of=boot.img seek=1

This copies the blank disk image to the file being created, then copies the first binary into the boot sector, then copies the second stage into the second sector of the disk image. You can then use the following batch command to copy the boot.img file to the floppy:

dd if=boot.img of=\\.\a: bs=1440k

I recommend keeping them as separate batch files, as you may want to create disk images without writing to a disk immediately (e.g., if you are using an emulator such as Bochs for testing), and conversely you might want to be able to write to a disk without rebuilding the whole file every time.

As for the first question, well, as I've said before, what I have here is just the starting point. You'll need to have code in the second part of the boot loader which can read the filesystem on the disk to find the location of the file being loaded, then be able to not only read the file into memory, but be able to interpret the file format and load the linked file into a suitable location …

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

You can also use the bximage utility which comes with Bochs to create blank floppy disk images. I'd nearly forgotten about that.

Also, what sort of trouble are you having with FASM? Is it with the assembler itself (the command-line tool, that is) or the editor that comes with it?

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

I'm not sure what you're asking, but I assume you mean, how would you create a disk image using dd? As it happens, the home page for the Windows version describes exactly how to do this. First, you need to make a blank image file, which can easily be done by copying the image of an empty floppy:

dd if=\\.\a: of=blankdisk.img bs=1440k

You would probably want to save this blank original and make copies of it for your actual disk images. Assuming you've made a copy named 'boot.img', you can then copy your binary to the beginning of the file like so:

dd if=kernel.bin of=boot.img

Finally, you can write this image file to the floppy like so:

dd if=boot.img of=\\.\a: bs=1440k

I hope this is what you needed, your previous post wasn't terribly clear.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Don't you need to link GRUB (or whatever multi-boot loader you're using) into your image as well?

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

You really can't write a boot-loader in C++, at least not entirely; the first stage, at the very least, would have to be in assembly language, and given that most C++ compilers produce only 32-bit code, you'd probably have to set the system into 32-bit protected mode before you could even run a C++ program. Even with a 16-bit compiler, you'd be limited to the very core of the language, and have to avoid any libraries you hadn't implemented yourself. Even the core C++ has features which require run-time support (e.g., memory management), making it a difficult language to do systems programming in compared to its parent language, C (which has very minimal run-time requirements, having been designed for the purpose of OS implementation).

All in all, one year of C++ with no experience in assembly and C is unlikely to be enough for this purpose. At the very least, you'll need to learn assembly language for the assembler of your choice (even for the same system, every assembler has a different syntax - the three most common x86 assemblers used for this purpose are MASM, NASM and gas), as well as understanding the boot loading process well enough to write the loader.

You may want to review the information and advice at the OS Dev Wiki, as it covers the requirements of a boot loader. You might also consider using an existing bootloader such as GRUB, which …

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

As it happens, the dd utility I mentioned earlier is convenient for this purpose as well, as you can use it to copy individual files into another file which can act as an image file.

Exe2Bin should be part of the MASM package, if you have that, at least it used to be. As I said, I use NASM, which can generate binaries for different formats directly, so I haven't needed that particular utility.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

There are two programs available for this purpose, RawWrite and DD. both can be gotten from chrysocome.net for free, and while dd is a bit of a pain to use, RawWrite is fairly easy.

Mind you, even with large numbers of floppies, you might want to do some testing using Bochs and a file image, which would give a much faster turn-around during debugging. You can't use RawWrite with disk images, AFAIK, but dd will do the trick fairly easily.

As for which to load to the boot sector, you definitely want the binary file, not the source file.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Unfortunately, if you're writing the boot sector yourself, then you'll need to have some way of loading the OS image file, which means writing at least a minimal version of the loader and enough of the file system to find the file in question. The usual solution is a two-stage boot loader, with the second stage being an assembly program which is loaded from a fixed position on the partition and contains enough of the file system and loader to get the actual boot image loaded. If you are using a 32-bit C++ compiler, you'd also need the code that sets up the GDT and switches to protected mode before jumping to the C++ code, as well.

Rather than rolling your own boot loader, you might consider using an existing multi-boot loader such as GRUB. I know that you had said you didn't want to deal with Linux, but GRUB is not for Linux alone: it should be able to load any conventional operating system, assuming that the image file was compiled to ELF format, or you can use chain-booting to load something in a different format (though in that case you'd still need to be able to load the file itself from scratch). Since it does a lot of the heavy lifting with regards to the memory setup and protected mode state, you'd save a great deal of effort in doing things this way.

I would recommend that you look into the information available at

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

What I gather out of all this is that you want to be able to write a loader for an executable file, correct? If so, then the reference text you want is Linkers and Loaders by John Levine. It covers several executable file formats in detail, including the DOS and Windows formats. You'll also need to be able to read the file system itself, at least to the point where you can find the file you want to load in, and trying to fit that into a single 512-byte sector is tricky at best.

Mind you, if all you need to be able to do is load a raw binary image, then all you really need is the ability to find the appropriate disk sector(s) and read them into memory. This is a much easier task, and a prerequisite of loading a file in the first place. I have an old sample bootloader which is able to read in the second sector from a disk (it assumes floppy disk, unfortunately, but I'm intending to work on a more advanced version RSN) and transfer control to the loaded binary. I can post this code if you'd like, as it may help you in working out what you're trying to do.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

If you don't mind me asking, what is the ptr variable for in the first place? You seem to have two completely different non-copying constructor, one which initializes the int s and one which initializes ptr , and they appear to be mutually exclusive.

Oh, and none of the c'tors initializes the ex variable, which I was also curious about. What is that one for?

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Would you mind posting the class declaration (in the header file), as well? It would clarify a number of things about the code.

From what I am gathering, though, the Bullet class has a number of instance variables, something like

int x, y, startX, startY, dx, dy;
char* ptr;

There may be more, but these are the ones which I could infer from the c'tors.

The main constructor seems to initialize the six integer instance vars, and declares (but does not create or initialize) an Extra object, ex . It does not initialize ptr , however.

The copy c'tor is the opposite of this, in that it copies the value of ptr (as a string) but does not copy or even mention any of the other instance vars. This is the 'shallow copy' they were referring to, and it isn't even a complete copy from appearances.

A 'deep copy' would need to copy the individual instance variables, one for one, and if any of them are themselves objects (or c-strings), they would need to be deep-copied as well.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

While I know you're new with this site, it should be mentioned that Cross-posting is frowned upon as it can cause a duplication of effort on the part of the two communities. It's generally considered best not to cross-post at all, but if you feel you would get better results this way (and not annoy people to the point that they ignore you), please at least mention that you've posted the same question elsewhere so the groups can review what was said elsewhere.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

It would help if you told us the problem that you're having, though in this case it is easy to guess. The reason that it doesn't recognize the string class is because string is in the std namespace, just like the <iostream> objects. You need to have a using std::string; statement, or else explicitly reference the namespace in the declarations. Given that there are only two such declarations, the explicit route may be better:

std::string Name;
    std::string idNumber;

Now, that's not the only problem I see (hint: use cin.ignore() after the >> operator), but that's the one preventing compilation.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

The comment here is incorrect, which may shed light on how the loop is failing as well:

while (in_stream >> number)     //in_stream >> number returns a Boolean value of true if the operation has been successful.

The >> operators, as a rule, return a reference to an istream not a boolean value per se. Mind you, a non-null pointer should be 'truthy' (that is, it would be treated as a true value), so I would expect the while() loop to continue indefinitely.

A more typical idiom for this would be

for (int index = 0; in_stream.good(); index++) 
    {
        in_stream >> number;
        array[index] = number;
        v.at(index) = number;
    }
    // check to see if it stopped because of an I/O error
    if (in_stream.fail())
    {
        //put error handling code here
    }

Well, OK, it would normally done with a while() rather than a for() , but in this case it makes for a more compact and integral expression.

mike_2000_17 commented: You're wrong. Check your facts before posting. -3
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

I didn't realise there was an age limit. Could you let me know what it is. I'm 3 years old by the way.

While I'll admit that I'd overlooked this myself, the age limit is spelled out in the Acceptable Use Policy:

Minimum Age Requirement
In compliance with the U.S. Coppa Act, no one under the age of thirteen (13) is permitted to register on these forums. If someone under the age of 13 does register, it is understood that they are doing so against DaniWeb's policies and without DaniWeb's knowledge.

Looking up the Children Online Privacy Protection Act (COPPA), it would be a violation to collect details such as names and locations for individuals under the age of 13 without written parental permission, or at least that's what I understand it to say - I don't have my Legalese to English dictionary on hand right now. It seems to me that, while there would be ways to accommodate underage members, the trouble needed to allow for it would be far too much to deal with feasibly.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Dipak Chauhan: To start off, it is generally considered impolite to re-start an old, existing thread with a new question this way. While what's done is done, please refrain from hijacking threads in the future. Even if the question is more or less the same, when it has been more than a month since anyone has posted in a thread, it makes more sense to start a new thread.

As for the question itself, the answer depends on the compiler and IDE you are using; each IDE has it's own form of project files, so answering questions about them will depend on the system you're using. If you don't already have a compiler available, I would recommend getting either Code::Blocks, which includes the GCC compiler (in the distro marked 'codeblocks-10.05mingw-setup.exe'), or Visual C++ Express, which is the free version of the Visual Studio IDE and includes the Microsoft C/C++ compiler.

Of course, all you really need are a text editor, a compiler toolchain which includes a version of make or some similar tool, and a shell or command prompt. For most Linux distros, such tools come with the system; for MacOS, you can download Xcode and have it all set up for you. Under Windows, you can get MinGW and Notepad++, and you'd be set to go. You would probably learn more this way, and I would recommend at least finding out how to compile a program from …

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

I would also recommend using an emulator (e.g., Bochs) or virtualizer (e.g., VirtualBox, QEMU, VirtualPC) rather than running off of live hardware, at least while testing and debugging. If nothing else, it would save you the constant work of rebooting the system as you test it, as you will be able to run the OS inside of your development machine.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Would this be a good point to mention that one usually speaks of 'assembling' an assembly language program, rather than 'compiling'?

As for Visual Studio, while it is true that VS 2010 can be used as an IDE for toolchains other than the ones which come with it, there is no specific support for the Netwide Assembler dialect of x86 assembly language (which differs from Microsoft's Macro Assembler in significant ways), so using it wouldn't gain you much... though apparently you aren't the only one out there looking to use VS2010 and NASM, as this code highlighting plug-in shows. You may want to look at this tutorial for how to set up assembling and linking through VS2010.

Still, I wouldn't really recommend it; you could use Notepad++ or a similar highlighting editor and assemble on the command line, and probably learn more doing so.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

I agree with Narue's advice, if it is possible - if you don't have a backup of the earlier version, and aren't using version control, it will be much harder to undo the changes. However, I was wondering if your course of study has covered classes yet; given the number of functions needed for the stack structure, it would make sense to wrap it all up into a class.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

I can see how the first one could be solved (using an if() statement with an empty block as it's body), but the problem itself is pointless - no one would do such a thing for any practical purpose. The only point I can see for this question is either to get you to think 'outside the box', or else to underscore the fact that printf() has a return value.

I am at a loss as to how the second problem would work.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

If you have any choice in the matter (and I realize you might not), I would suggest getting a more modern compiler and IDE. I personally find Code::Blocks to be very good, though Visual C++ Express has a superior debugger. If all else fails, and you can afford to pay for it, C++ Builder XE2 is the modern descendant of the Borland compiler. Given that you are writing what is essentially standard C++ code, it should compile and run under any of these, so which to use boils down to personal preference.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

If you don't mind me asking, what compiler are you using, and what version? The console I/O library isn't a standard one (which is fortunate, as you don't actually use it and can remove it from the include list), and the modern C++ header for the standard library is <cstdlib> , not <stdlib> . Also, most of the newer IDEs (including Code::Blocks and the newer versions of Visual C++) all pause after the end of a console program automatically, obviating the need for the system() call (and in turn the include for the standard library). Finally, any newer C++ compiler would require you to use the std namespace for the <iostream> and <string> objects and functions.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

I'm not sure why it would give that specific error message; it is more typical of certain types of header problems. You might try using 'g++' rather than 'gcc'; by default, gcc assumes that you're compiling a C program, while g++ is specific to C++.

I would also recommend always using the '-Wall' switch with gcc and g++, like so:

g++ -Wall testing.cpp -o test

This option turns on all of the warnings which the compiler can give you - by default, most of the diagnostic warnings are turned off, but having them turned on is very helpful in debugging.

As for the second shell command, the reason it can't find the file is because you aren't in the directory the file is in, and you haven't told it which directory to look for it. By default, when you open a terminal in Linux, it starts off in your home directory, '/home/john/' in this instance. If the source file is in a folder on your Desktop, you need to either give it the path to the file, or else change directories so that you are in the same folder as the file. In this case, the latter can be done with the simple command cd Desktop/C++ , which should change your current working directory to '/home/john/Desktop/C++/'. If you get confused as to where you are, you can use the command pwd to get your working directory.

BTW, the tilde ('~') in the path of …

anirudh33 commented: informative and its solved :) +2
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Assuming that you're using one of the commonly used MIPS simulators such as SPIM or MARS, then the print integer system call expects the value to be printed to be in $a0, not a pointer to the value. You'll need to put the pointer to the memory location into a temporary variable and dereference it into $a0, rather than simply loading the pointer into $a0. Thus, you would want to write it as something like this:

lui $t0, 0x1001
addi $t0, $t0, 0
lw $a0, 0($t0)  
addi $v0, $0, 1 
syscall

BTW, just as a way of saving some trouble for you as a coder (by letting the assembler do the heavy lifting), does the MIPS assembler your using support the move , la and li pseudo-instructions? This would let you use a label for the address rather than forcing you to write the address out explicitly:

la $a0, myString
    move $v0, 4
    syscall

Where myString is at some labelled data location.

Even better would be if the assembler allows named constants, as you could give a name for the syscall arguments. This thread discusses the use of equates to simplify coding, and gives the list of the most common constants used (in SPIM specifically; AFAIK, the MARS simulator's assembler does not support equates).

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

You can find extensive information, including sample boot loaders, at OSDev.org. I would recommend being careful about posting to the fora there, however, as they expect you to carry your own weight, and a blanket request such as this one is likely to get negative reactions.

That having been said, I would recommend using GRUB as your bootloader rather than trying to roll your own. GRUB does many of the basic startup tasks for you, and let's you start from a fairly well-developed point.

As for a command-line action, you're on your own.

Zssffssz commented: He seems like the only person that helps people with asembly, he gets there fast and helps you find your answer! +1
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

The logical OR operator is a short-circuiting operator; when a true result is found in the first clause of the operation, it does not process the second clause. This applies to the clauses as a whole. Operator precedence doesn't enter into it, in this instance.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

While I cannot say for certain, I would expect that you would be better off using strncmp() for this, given that you are in fact comparing strings for an exact match. This would also allow you to use the buffer size as the maximum rather than the specific expected size of the string (which as I pointed out earlier, would be one longer than you are allowing for now).

BTW, you may be better off keeping the buffer size as a named constant, rather than having it as a magic number as you do now. That would make it easier to read, and obviate the need to use of the sizeof() operator.

#define BUFSIZE 15

void receiveEvent (int howMany)
 {
  char buf [BUFSIZE];
  byte i = 0;

  while (Wire.available () > 0)
    {
    char c = Wire.receive ();
    if (i < BUFSIZE - 1)  // check for overflow
      buf [i++] = c;
    }  // end of while

   buf [i] = 0;  // terminating null
   
  if (strncmp (buf, "G1", BUFSIZE) == 0)
    digitalWrite (LED, HIGH);
  else if (strncmp (buf, "G28", BUFSIZE) == 0)
    digitalWrite (LED, LOW);
}  // end of receiveEvent
Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Which compiler have you used? I can not run this program in Dev c++.
If you tell your compiler's name I can try it.
Thank you.

Actually, the compiler information was provided in the comments at the top of the program: he is using gcc running under a Unix variant, probably either Linux or MacOS. The compiler is the same as used by Dev-C++ (though the one used by Dev-C++ is now woefully out of date); the issue is the operating system it runs under.

This last part is relevant because the program uses the POSIX regular expression library, which would not be present in a default Dev-C++ package. The system requirement is underscored by the fact that it also uses popen() and setuid() , Unix system calls which are not supported under Windows. In other words, this won't compile with any Windows compiler, even a port of the same compiler the OP is using.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Having tested this out, I found that the problem is in the conditional of the inner loop. As it is, it not only is skipping possible reverses because it only goes up to i, it is overrunning the end of the array. A workable solution would be

for(j=0;j < n - 1;j++)

You can also shave some run time off by checking for whether any swaps were made on a given pass; if there weren't any, you have sorted the list and can stop.

void bubblesort(char** list, int length)
{
    int i, j, swapped;

    for (i = 0; i < length - 1; i++)
    {
        swapped = 0;

        for (j = 0; j < length - 1; j++)
        {
            if(strcmp(list[j], list[j+1]) > 0)
            {
                swapped = 1;
                swap(&list[j], &list[j+1]);
            }
        }
        if (!swapped)
        {
            break;    /* no swaps made on last pass, sorted */
        }
    }

   /* printf("\nCompleted in %d passes\n", i); */
}

Oh, as a matter of note: please place code-tags around your code samples in the future. So far, the moderators have been kind enough to supply them for you, but formatting the code yourself would go far in gaining your their goodwill.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

What is 'correct' all depends on what you are trying to do.

If you are only looking to match the first two characters, then the first one would be correct in both cases - it would match any case where the string begins with the characters 'G' and '1', regardless of what follows them.

OTOH, if you mean to match a whole string, then both of these are incorrect, as they don't take into account the zero delimiter at the end of the string. In C, the endpoint of a string is marked with a null character, '\0', which the string functions need in order to determine the length of the string. When matching a whole string with memcmp() , you would need to include the space for the string delimiter.

However, I should add that you would normally use strcmp() or strncmp() to compare strings, as these are specifically for handling ASCII character strings.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

I see that it was a mistake to make that off-hand comment about relevancy; but no matter. Let's return to the issue at hand, shall we?

Regarding the buffering issue, I agree with Adak about using fgets() and strtol() rather than scanf() for numeric input. Being able to vet input is important, if only so you can handle user mistakes (not to mention malicious users).

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

#define MAXBUF 256

int main(void)
{
    char buffer[MAXBUF], *endpt;
    long num = 1;
    int len = 0;

    for( ; ; )
    {
        printf("Num = %ld Enter X to quit. \n", num);
        endpt = fgets(buffer, MAXBUF - 1, stdin);

        if (endpt == NULL)
        {
            puts("An I/O error has occurred. Exiting.");
            exit(-1);
        }

        buffer[MAXBUF] = '\0';        /* make certain that the str is delimited */
        len = strlen(buffer);
        buffer[len - 1] = '\0';       /* eliminated the newline */

        num = strtol(buffer, &endpt, 10);

        if (toupper(buffer[0]) == 'X')
        {
            break;
        }
        else if (endpt == buffer)
        {
            printf("%s is not a valid integer.\n", buffer);
            num = 1;
            continue;
        }

    }

    return 0;
}

Not so simple a program after that, admittedly, but definitely more robust.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Really? You mean universities no longer teach C++ as a relevant technology? HTML is their relevant technology?

Well, not as their first-semester technology, in most cases, at least, a policy I agree with wholeheartedly - C++ is hardly suited for beginners. Unfortunately, many are dropping C and C++ entirely, which is short-sighted to say the least.

OTOH, it's true that the majority of CS students are likely to do more web-related work than systems or applications programming, so yes, the relevance for most is questionable. Whether we should be basing our curriculum entirely on what students are likely to need for their jobs is another question altogether.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

He has the choice to go to a real university where they teach you relevant technology........

In that case, he'd be studying HTML and either Python or Ruby right now, and we wouldn't be having this conversation (or at least not for another few semesters). While I have used C++ professionally myself, I'd expect that for the current classes of graduates, C++ jobs are the exception rather than the rule.

Seriously, though, when I say 'standardized', I mean it. Every accredited university in those countries is required to teach the same courses, in the same manner, using the same tools, no exceptions. It's a sad situation, but chances are, the OP doesn't have the choice of going to what you would call a 'real university'.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

Here is a simple pseudo-code which represents the logic of the problem; no guarantees are given as to it's correctness.

for x in range(0, 10):
	for y in range(0, 10):
		if x >= y:
			print("X", end='')
		else:
			print("*", end='')
	print("\n")

(OK, so it isn't so pseudo a code, but it should be clear enough, I think. It also doesn't exactly match the described results, but it is close enough to give the OP a head start.)

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

conio.h is pure evil!

It not portable (only works properly under DOS) and isnt standards compliant either

While I agree with you about both <conio.h> and the Turbo C++ compiler, it is my understanding that in both India and Pakistan, the university systems have standardized on Turbo C++ and generally teach DOS style console I/O as part of their coursework. The OP may not have any choice in the matter.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

I think that the problem lies with the getmodelno() function itself, and what you are expecting it to do. As it is written right now, it prints the model number to the screen, but does not return it's value. If you want the function to act as an accessor (also called a getter), then you'd have to write it as:

char* getmodelno()
{
    return lmodelno;
}

You might want to use the string class instead of C-strings, however, as they are much easier to work with.

On an unrelated note: while void main() is accepted by some compilers, strictly speaking the correct usage is int main() according to the standard. While the standard allows compilers to accept void main() for those cases where there is no OS to return to, it is considered a non-portable extension.

I was also curious as to why you were using such an outdated compiler. VC++ 6.0 is from 1998, and there are several more modern compilers available for free, including the newest version of Visual C++ Express. Are you required to use the older version for class? I know several schools use older compilers as a matter of standards (Turbo C++ being the most notorious), but it is in my arrogant opinion a poor practice.

Schol-R-LEA 1,446 Commie Mutant Traitor Featured Poster

There are many different free C++ compilers around, with the two most commonly used free ones being GCC and Visual C++ Express.

VC++ Express is a compiler and IDE (integrated development environment), and has an excellent debugger, but you have to be careful about Microsoft-specific extensions if you intend to write portable code.

GCC is the GNU C++ compiler used in Linux, but has ports to all of the major operating systems including Windows and MacOS. By itself, GCC is just a command-line compiler, but it includes any number of tools with it, and there are several IDEs which use it, with the best probably being Code::Blocks. The debugger that comes with it is a lot less useful than that with VC++ Express, but the rest of it is more than equal to the MS package.

I should add that the version of Borland C++ you're using is also rather dated; Borland itself is now called Embarcadero Technologies, and the current version of their compiler (and IDE) is called "C++ Builder XE". It is not free, and unless you have a specific need for it, probably not worth the money.