|
//..or do something else
They sought it with thimbles, they sought it with care;
They pursued it with forks and hope;
They threatened its life with a railway-share;
They charmed it with smiles and soap.
|
|
|
|
|
I've tried everything to switch, it all seems to fail. I wanted to switch to web design, but it would be the same kind of thing I'm going through now with no job in it and all. I've done some self-taught codes in java script and html and it doesn't look that hot or appealing to employers, even if I did go some school to teach me more crap that probably is basic and not in-depth with details and examples to get a jump start on a career for myself.
|
|
|
|
|
While some programmers do write about future,
your switch to be a writer about past seems to be good.
I see a possible documentation-piece in your language
as a canny and easy-to-understand thing (adventure)
They sought it with thimbles, they sought it with care;
They pursued it with forks and hope;
They threatened its life with a railway-share;
They charmed it with smiles and soap.
|
|
|
|
|
First priority: Data Structures. This will be useful no matter what language you're programming in, and for any application. There are lots of introductory books on Data Structures.
Second priority: Object-oriented programming. More specifically classes, inheritance, virtual functions, and polymorphism (it sounds harder than it is.) A background in object-oriented programming is essential to understand Design Patterns.
Other priorities: Graphics. Most modern programs involve graphics and if you study web programming, experience with graphics will be valuable. .NET languages all have good graphics capabilities.
If you're interested in web design, start with HTML. It's a display-only language, so is relatively easy. The next step is JavaScript to make your HTML pages interactive. Next, Java or PHP.
Working on an open-source project will look good on your resume, and will be experience that will help you develop your programming skills.
|
|
|
|
|
Timothy Hosey wrote: or do something else
Like compile?
|
|
|
|
|
hello guys....i became confused these days with this simple question, plz excuse me. My question is: what is the difference between return 0 (indicating that function executed successfuly) and some value returned by our function?? here is the example
int func(){
int num1 = 5;
int num2 = 0;
return num1 * num2;
}
Now how does the compiler differenciates between these two return statements?? thnx
|
|
|
|
|
The return statement simply specifies the value that the function will return; it says nothing about the meaning of that value.
Sometimes a return value of 0 means that a function was successful, sometimes a return value of 1 means success. Usually the return value has a meaning entirely different from success or failure. The meaning is determined by the programmer - the compiler doesn't know or care.
Phil
The opinions expressed in this post are not necessarily those of the author, especially if you find them impolite, inaccurate or inflammatory.
|
|
|
|
|
You are returning an integer value of num1*num2
If I had a function that returned a boolean value, it would look like this:
boolean foo() {
boolean x = TRUE ;
return x ;
}
Your return statement must match what the function definition. (e.g. my foo function is defined as a boolean).
|
|
|
|
|
bit of confusion here.
The user (developer) decides whatever is the meaning of the value returned by a function; AFAIK, there is no
official set way to say a function "executed" successfully; could be a returned value, could be a parameter passed by reference (or pointer), could be a try/catch thingy or the function could set the "Last Error" (GetLastError(), SetLastError() )
If you only have access to the header files, there should be some kind of documentation saying what the return value is; if you have access to the source file, then a bit of looking could be needed.
M.
Watched code never compiles.
|
|
|
|
|
I have a method that will take in a char data type if I build it with the methods shown below. If I manually put the template into the variable, it runs fine, but when I build it, it craps out (I never know what the name of the user is, so I have to build the template with just a name given).
char voice_template_g[26] = "" ;
void initiate_voice_rec(char* voice_template) {
strncpy ( voice_template_g, voice_template, sizeof( voice_template_g ) ) ;
}
void get_current_voice_template() {
char template_file_path[100] = "c:\\Dragon\\Speaker\\" ;
char default_template[100] = "c:\\Dragon\\Speaker\\IPART" ;
char temporary_file_path[100] = "";
strncat( temporary_file_path,
template_file_path,
sizeof( temporary_file_path ) ) ;
strncat( temporary_file_path,
voice_template_g,
sizeof( temporary_file_path ) ) ;
if( !_chdir( temporary_file_path ) )
{
strncpy( voice_template_g,
temporary_file_path,
sizeof(voice_template_g) ) ;
}
else
{
strncpy( voice_template_g,
default_template,
sizeof(voice_template_g) ) ;
}
}
now if a template is made (not the default) it crashes, but if I call:
strncpy( voice_template_g, "c:\\Dragon\\Speaker\\TERR2285", sizeof( voice_template_g ) ) ;
right at the end of get_current_voice_template(), it works fine.
is there a difference in the data used between:
strncpy( voice_template_g, temporary_file_path, sizeof(voice_template_g) ) ;
and
strncpy( voice_template_g, "c:\\Dragon\\Speaker\\TERR2285", sizeof( voice_template_g ) ) ;
They produce the same string, but they both don't work!
|
|
|
|
|
Hi,
it is not completely clear to me. Here are some ideas:
1.
as temporary_file_path is initially empty, the first strncat better be a strncpy.
2.
your overrun protection is not effective:
strncat( buffer, data, sizeof(buffer));
if buffer initially holds 10 chars, you will overrun it by 10 (assuming data is a long string).
you should either calculate how many buffer positions remain and use that as count, or use a safer version of strcat/strcpy.
3.
there is something quite illogical in using the same buffer (voice_template_g[26]) for input and output.
Assume it is almost full at input; your code creates a longer path (path+initial content of buffer). then
copies that back into the input buffer.
4.
And then there is the problem of string functions not ensuring there will be a terminating NULL. (When they reach the count limit before reaching the source's NULL, no NULL is copied nor appended).
5.
I can imagine situations where things run fine the first time around, and fail the second time around, maybe because voice_template_g now contains the earlier result.
6.
you should add log statements and/or use your debugger's facilities to inspect the data in the buffers.
|
|
|
|
|
pjdriverdude wrote: If I manually put the template into the variable...
Template? I see no templates or classes. Perhaps you've used the wrong word?
pjdriverdude wrote: ...but when I build it, it craps out...
With what error?
pjdriverdude wrote: They produce the same string...
How have you verified this?
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
|
|
|
|
|
1. I'm building the string to search for my template.
2. If I build the string by using "c:\\Dragon\\speaker\\TERR2285", it works fine. If I build the string with the strncat/strncpy, the function I insert my template string into give me an access violation error.
3. Yes, I've used strcmp to make sure the strings were the same. Is there a better way to do this?
|
|
|
|
|
pjdriverdude wrote: If I build the string with the strncat/strncpy, the function I insert my template string into give me an access violation error.
Which line is doing this?
pjdriverdude wrote: Is there a better way to do this?
Yes. Use the debugger to put a breakpoint on the strncpy() statement(s). Then you can see the values of voice_template_g , temporary_file_path , and default_template .
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
|
|
|
|
|
if( !_chdir( temporary_file_path ) )
{
strncpy( voice_template_g,
temporary_file_path,
sizeof(voice_template_g) ) ;
}
the strncpy here is where the template would be made so that it can be passed to a later function.
|
|
|
|
|
Ok, and?
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
|
|
|
|
|
hehe that's it, the later function that I speak of is a part of naunce's dragon naturally speaking API, so I didn't include it here, since it might just confuse anyone trying to help.
Basically,
strncpy( voice_template_g, "c:\\Dragon\\Speaker\\TERR2285", sizeof( voice_template_g ) ) ;
works, while
strncpy( voice_template_g, temporary_file_path, sizeof(voice_template_g) ) ;
doesn't. I don't see the difference in putting the actual user name in, as opposed to building it with my method listed in the code.
the dragon function looks like
m_dragon_engine->put_Speaker(speaker) ;
where speaker is the template variable I create.
|
|
|
|
|
pjdriverdude wrote: I don't see the difference in putting the actual user name in, as opposed to building it with my method listed in the code.
See my second response here.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
|
|
|
|
|
How long is this string? "c:\\Dragon\\Speaker\\TERR2285"
It looks like 27 characters to me and you're copying it into a 26 character buffer. Try giving voice_template_g a decent size (e.g. 4096) and see if things start working a bit more to your liking. If it does then you can rein it back in again later.
All C programs spend an inordinate amount of effort widdling about with character arrays pretending to be string. You could simplify things a bit if you used a helper function to get rid of the endless sizeof operators and then you'd have a central place where you could check that you're not about to overrun a buffer or truncate a string.
Cheers,
Ash
|
|
|
|
|
The I was using an array of 100, but I got the same results..hehe I thought by making it the exact size, I might get rid of a \0 that might exist.
I've been throwing all kinds of things at this before I posted here, just haven't had time, yet, to test the suggestions. I'm definently going to tweak the size of those sizeof methods to see if that is causing the problem.
|
|
|
|
|
Rather than trying things at random, I suggest two things:
1.
yes you can start heuristically, i.e. guess at what the problem could be, investigate, try an alternative. But that will only solve the simple problems. if you can't find the overall solution, it could well be there is more than one problem; fixing the first may be unnoticeable as long as the others haven't been fixed. And that is exactly why debugging can be tiresome, and programming defensively pays off.
This also implies that "no, this change does not help" is irrelevant, the change may still be an essential part of the fix.
2.
but when heuristics fail, you need a systematic approach, which always start from the facts. Not the things you think hold true, as some of them obviously don't (otherwise your code would run fine). The only facts that count are those that you have observed by looking at intermediate values, either by printing them out (log statements) or by single-stepping and using debugger features.
The first anomaly you encounter must be remedied, it doesn't make much sense to ignore it and continue, it can only confuse you. So, take small steps, observe, and fix everything that is less than perfect.
BTW: with #2, your problem will be history in a couple of minutes. Add log statements (use hex, so you see all those pesky non-printable characters as well), and use the gray cells.
|
|
|
|
|
I see a number of conceptual mistakes here, and some of them might be part of the problem you perceive:
1. You are using statically defined buffers for storing a string of dynamic length. You cannot do that, since the behaviour of your function(s) will be undefined if for whatever reason the total string length exceeds the length of your buffer. Just using an arbitrary 'large' size is exactly the kind of thinking that caused the year 2000 bug histeria. The better solution is to calculate the size you need and dynamically allocate a buffer large enough for your purposes.
2. The third parameter of strncat is the maximum number of characters being appended. If you want to make sure that you don't write past the end of your buffer, you first need to calculate the length of the string currently stored within that buffer, using e. g. the strlen() function, and then calculate the difference.
However, that point is moot if you do what I stated in 1. since you will already know for sure that your buffer is sufficiently large - you made it so!
3. Beyond what I stated in 2., while you tried to avoid writing past the end of the buffer, you didn't care to check whether that actually causes a truncation of the concatenated string. Depending on what you want to do with that string, truncating it might render it unusable, and your function's behaviour becomes unpredictable.
4. Using strncat() or strncpy() instead of strcat and strcopy will truncate the terminating 0-character if the concatenated string is too long. As a result, your buffer will contain a string of undefined length, a length that will be equal or greater than your buffer size. Any followup calls to strncat() or strcat() will inevitably write past your reserved buffer. Not to mention that your buffer, when interpreted as a 0-terminated string, will be invalid for your purposes.
Summary:
(a) Do not use strncat() or strncpy! At all! The strings you are working with must not be truncated. A truncated directory name will cause errors as will truncated file names. There is no point at all in using functions that might truncate your strings without producing any indication that they did!
(b) Always use precise length for your string literals and string buffers! For string literals, just don't supply the length, define them like this instead:
char template_file_path[] = "c:\\Dragon\\Speaker\\" ;
And for dynamically sized buffers, calculate the exact length that you need:
char *temporary_file_path = new char[strlen(template_file_path)+strlen(voice_template_g)+1];
(and don't forget the delete [] temporary_file_path; later)
(or use malloc and free if you must)
(c) Use strcpy and strcat to make sure your path and filenames are not truncated, and your final string will be 0-terminated.
If you have a C++ compiler, it would of course be much easier to just use std:string instead of char* ...
|
|
|
|
|
I took your advice, and came up with this, and it works!
char* voice_template = new char [ strlen(user_voice_template_g) ] ;
char directory[] = "c:\\Dragon\\Speaker\\" ;
char* template_path = new char[ strlen( voice_template ) + strlen( directory ) + 1 ] ;
strcpy( voice_template, user_voice_template_g ) ;
strcpy( template_path, directory ) ;
strcat( template_path, voice_template ) ;
dragon_object = new Dragon_Base(dragon_voice_utility_g, template_path, NULL);
but something interesting came up in the process. I starting moving everything into my code and I put my _chdir function back in and I start getting errors again. It has everything to do with my _chdir function call. MSDN says that using _chdir changes the working directory, but I was thinking that it would stay in the C drive, so that didn't matter. So now, if I call _chdir, it craps out again. But hey, that's workable now. I got a good lesson on dynamic allocation of memory =) thanks!
char* voice_template = new char [ strlen(user_voice_template_g) ] ;
char directory[] = "c:\\Dragon\\Speaker\\" ;
char* template_path = new char[ strlen( voice_template ) + strlen( directory ) + 1 ] ;
strcpy( voice_template, user_voice_template_g ) ;
strcpy( template_path, directory ) ;
strcat( template_path, voice_template ) ;
if( !_chdir( template_path ) )
{
}
else
{
strcpy( template_path, "c:\\Dragon\\Speaker\\IPART" ) ;
}
dragon_object = new Dragon_Base(dragon_voice_utility_g, template_path, NULL);
|
|
|
|
|
Glad to be of help. There's still an error though: when you call strlen(somestring) what you get is not the actual size required to store a 0-terminated string, you only get the number of actual characters, or length of the string stored in this variable. It does not account for the terminating 0-byte. So when using strlen() for the purpose of allocating a sufficiently long block of memory, you always have to add 1! So instead of
pjdriverdude wrote:
char* voice_template = new char [ strlen(user_voice_template_g) ] ;
you should write
char* voice_template = new char [ strlen(user_voice_template_g) + 1 ] ;
You can also see this technique in the second example I gave: there I added the two strlen results and added another 1 on top of that.
That said, the missing byte might not cause any issues: using strcpy and strcat in place of strncpy and strncat makes sure the terminating 0 will be copied even if it's past the buffer. This can cause a lot of trouble if that memory location is being used for something else, but it is entirely possible for a single byte address to remain unused.
|
|
|
|
|
Hello,
Is MFC coding different for different versions of visual studio.
Pritha
modified on Monday, September 27, 2010 5:44 PM
|
|
|
|
|