- #211
yungman
- 5,755
- 293
Just great, Amazon LOST my book! First time happen to me! Still no book!
What book did Amazon lose?yungman said:Just great, Amazon LOST my book! First time happen to me! Still no book!
I actually copied this link already yesterday, that's the one that I commented about hard to read. I even copy onto a word doc and modified to make it easier to read. I am still checking, seems like the order of the parameters are switched from what Mark44 suggested. I need to play with the program to verify.sysprog said:I just highlighted "definition of strcpy_s" from your post, right-clicked, selected "Search Google for "definition of strcpy_s"" from the context menu, and got this:View attachment 266730
Remarks. The strcpy_s function copies the contents in the address of src, including the terminating null character, to the location that's specified by dest. The destination string must be large enough to hold the source string and its terminating null character.
The link leads to a full explanation. It's true that, as you put it , "It is NOT easy to google and learn C++", but being able to do searches on things is a great aid in learning things, and of course, not everything that is worth learning is easy to learn, by any means.
https://www.amazon.com/gp/product/1484233654/?tag=pfamazon01-20sysprog said:What book did Amazon lose?
Reiterating @Mark44's code, with 2 comment lines added:yungman said:I am still checking, seems like the order of the parameters are switched from what Mark44 suggested. I need to play with the program to verify.
#include <iostream>
#include <string>
#include <string.h>
using std::cout; using std::cin; using std::endl;
using std::string;
int main()
{
cout << " Enter a line of text: ";
string userInput;
// get a line of input from the user
getline(cin, userInput);
char copyInput[20] = { '\0' };
if (userInput.length() < 20)// check bound.
{
// copy user line to copyInput (to-field, length, from-field)
strcpy_s(copyInput, 20, userInput.c_str());
cout << " CopyInput contains: " << copyInput << endl;
}
else
cout << " Bound exceed, won't copy!" << endl;
}
// crt_wcscpy_s.cpp
// Compile by using: cl /EHsc /W4 crt_wcscpy_s.cpp
// This program uses wcscpy_s and wcscat_s
// to build a phrase.
#include <cstring> // for wcscpy_s, wcscat_s
#include <cstdlib> // for _countof
#include <iostream> // for cout, includes <cstdlib>, <cstring>
#include <errno.h> // for return values
int main(void)
{
wchar_t string[80];
// using template versions of wcscpy_s and wcscat_s:
// not strcpy_s but still (to-field, length, from-field)
wcscpy_s(string, L"Hello world from ");
wcscat_s(string, L"wcscpy_s ");
wcscat_s(string, L"and ");
// of course we can supply the size explicitly if we want to:
wcscat_s(string, _countof(string), L"wcscat_s!");
std::wcout << L"String = " << string << std::endl;
}
I was a reviewer of Tony Gaddis's first book, "Starting Out with C++," published in 1998. I'm listed in the Credits section of this book, and I believe, in the subsequent editions of this book.yungman said:I am still waiting for two other books:
https://www.amazon.com/gp/product/1...title_o03_s00?ie=UTF8&psc=1&tag=pfamazon01-20
https://www.amazon.com/gp/product/0...title_o00_s00?ie=UTF8&psc=1&tag=pfamazon01-20
The last one is used in my grandson's C++ class he took.
Mark44 said:........
The first parameter is the source of the copy, the second is the max. number of characters to copy, and the third is the destination of the copy.C++:strcpy_s(copyInput, 20, userInput.c_str());
c_str() is a function that converts a C++-style string to a C-style null-terminated array of type char. One of the very confusing things about C++ and its standard template library is that both types of string are still present -- the C-type array of char, and the C++ string class. The program you showed mixes both types, plus it uses a C function (strcpy) that Microsoft doesn't support any longer.
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <iostream>
#include <string>
using std::cout; using std::cin; using std::endl;
using std::string;
int main()
{
string userInput;
cout << " Enter a line of text: ";
getline(cin, userInput);
cout << " The userInput is: " << userInput << endl;
cout << endl;
cout << "length of userInput = " << userInput.length() << endl;
cout << endl;
char copyInput[20] = { '\0' }; cout << " copyInput = " << copyInput << endl;
cout << endl;
cout << " length of copyInput = " << sizeof(copyInput) << endl;
if (userInput.length() < 20)// check bound.
{
strcpy_s(copyInput, 20 , userInput.c_str());
cout << " CopyInput contains: " << copyInput << endl;
}
else
cout << " Bound exceed, won't copy!" << endl;
return 0;
}
This is backwards ##-## the left-to-right correct order is: destination, length, source ##-## @Mark44's code specifies the parameters in the correct order.Mark44 said:The first parameter is the source of the copy, the second is the max. number of characters to copy, and the third is the destination of the copy.
sysprog said:This is backwards ##-## the left-to-right correct order is: destination, length, source ##-##
@Mark44's code specifies the parameters in the correct order.
Ok, which one is the first parameter? And which is the third parameter? What is the correct direction to read from? Left to right or right to left as the first? This is the point of my confusion.Mark44 said:The first parameter is the source of the copy, the second is the max. number of characters to copy, and the third is the destination of the copy.C++:strcpy_s(copyInput, 20, userInput.c_str());
yungman said:I am still checking, seems like the order of the parameters are switched from what Mark44 suggested. I need to play with the program to verify.
The code using strcpy_s worked as it should, but my explanation misstated which parameter was the destination and which was the source of the copy. I have edited my earlier post to correct this error.yungman said:But you said the first parameter is source of the copy and third is the destination of the copy. I am missing something.
I specifically included left to right as the order.yungman said:Ok, which one is the first parameter? And which is the third parameter? What is the correct direction to read from? Left to right or right to left as the first? This is the point of my confusion.
strcpy_s(copyInput, 20, userInput.c_str());
##-## the parameters are, in left-to-right order, (to-field, length, from-field), or (destination, length, source).strcpy(), strncpy(), and strcpy_s() are three different functions, with different parameters. strcpy_s() is similar to strncpy(), except that the order of the parameters is different and they return different types.yungman said:I took a quick look, the strcpy() have a different name....it's called strncpy(). I tried substituting strcpy_s with strncpy, it gave me an error!
You don't need Codeblocks -- you already have VS. You should be able to type in the programs in the "Dummies" book and run them. The book is for C++, so I don't understand what you're talking about with regard to different spelling of operators and all that.yungman said:But the book instruct to go to:
http://www.dummies.com/extras/beginningprogrammingcplusplus.
and download :codeblocks-13.12mingw-setup.exe
Is different IDE uses different spelling of operators or different names all together?
But when I try to go to the website, it doesn't even work!
In C, strncpy() is like strcpy(), but strncpy() copies only the specified length. I recommend against your using it, for the reasons stated by @Mark44. I also think that you shouldn't use a multitude of different C++ compilers this early in your learning of the language. Despite the Visual Studio IDE and C++ compiler not being the most streamlined offering out there, it is among the very best, it's free, and it's the de facto industry standard.yungman said:I took a quick look, the strcpy() have a different name....it's called strncpy(). I tried substituting strcpy_s with strncpy, it gave me an error!
But the book instruct to go to:
http://www.dummies.com/extras/beginningprogrammingcplusplus.
and download :codeblocks-13.12mingw-setup.exe
Is different IDE uses different spelling of operators or different names all together?
But when I try to go to the website, it doesn't even work!
Those are the C++ versions of the C stdio.h and stdlib.h libraries.#include <cstdio>
#include <cstdlib>
Those are C library functions? That explains it. I am pretty much committed to VS, so if this doesn't work, then wait for the other books. This book is used, I only paid like $8 total including shipping. I am going to read some of the stuff anyway as there's still a lot of stuffs that look right. This book might explain stuffs better than the first book.sysprog said:Those are the C++ versions of the C stdio.h and stdlib.h libraries.
I think that you should avoid using C library functions in C++.
Did you terminate your input strings with /0 ? ##-## that's null termination, and it's important to use it when you use ASCIIZ functions without a length parameter.
That makes sense to me.yungman said:Those are C library functions? That explains it. I am pretty much committed to VS, so if this doesn't work, then wait for the other books. This book is used, I only paid like $8 total including shipping. I am going to read some of the stuff anyway as there's still a lot of stuffs that look right. This book might explain stuffs better than the first book.
It is actually a much better book, a little too simple, but much better so far. I even experimented with one or two programs already. Since I went through 5 chapters and part of the 6th with the other book, I went through the C++ for Dummies very fast, scanned through over 100 pages last night already.sysprog said:That makes sense to me.
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <iostream>
#include <string>
using std::cout; using std::cin; using std::endl;
using std::string;
int main()
{
string userInput;
cout << " Enter a line of text: ";
getline(cin, userInput);
cout << " The userInput is: " << userInput << endl;
cout << endl;
cout << "length of userInput = " << userInput.length() << endl;
cout << endl;
char copyInput[20] = { '\0' }; cout << " copyInput = " << copyInput << endl;
cout << endl;
cout << " length of copyInput = " << sizeof(copyInput) << endl;
if (userInput.length() < 20)// check bound.
{
strcpy_s(copyInput, 20 , userInput.c_str());
cout << " CopyInput contains: " << copyInput << endl;
}
else
cout << " Bound exceed, won't copy!" << endl;
return 0;
}
It's no wonder. Your program is using two different types of strings. userInput is an instance of the C++ template class, while copyInput is a plain old C-style array of type char. The C array is very simple -- it consists of 20 bytes in memory, and nothing else. The C++ class instance is much more complex -- it has class member functions (such as length() and getline() and quite a few more), and operators (such as + for concatenating two string objects).yungman said:I am still confused when to use userInput.length() or sizeof (copyInput)? I thought both are character strings in this program.
If you go on Amazon and look at the first book page 79. That's all the explanation it gives, nothing like what you said. I am going to go back and read the second book on array and strings!Mark44 said:It's no wonder. Your program is using two different types of strings. userInput is an instance of the C++ template class, while copyInput is a plain old C-style array of type char. The C array is very simple -- it consists of 20 bytes in memory, and nothing else. The C++ class instance is much more complex -- it has class member functions (such as length() and getline() and quite a few more), and operators (such as + for concatenating two string objects).
Unless your book, the first one you've been working in, talks about the differences between C-type strings and C++ string objects, mixing the two types in a program is bound to lead to confusion. So far, I'm not very impressed at the quality of that book.
yungman said:I am still confused when to use userInput.length() or sizeof (copyInput)? I thought both are character strings in this program.
Mark44 said:It's no wonder. Your program is using two different types of strings.
Yes.yungman said:If you go on Amazon and look at the first book page 79. That's all the explanation it gives, nothing like what you said. I am going to go back and read the second book on array and strings!
1) userInput is defined as std::string; Is everything defined as std::string all have class member functions (such as length() and getline() etc.)?
An array can have any base type, not just the primitive types such as char, short, int, long, float, double, etc. When an array is declared or defined, the number in the brackets indicates how many elements of the given type will be in the array.yungman said:2) copyInput is defined as char copyInput[20];. Is the [20] telling this is a 20 characters array of characters? The first book mostly talk about int array, how many type of array is there ( I mean like int, char type)?
yungman said:The second book C++ For Dummies is a whole lot better, might be simpler, but it really explain things a lot better. You should really read p79 on the first book on std::string. You'll see why I have so many questions. I am going to read the second book on this.
wle said:C++ has a lot of feature duplication. It often provides two or more different ways of achieving substantially the same thing. This is something you need to accept up front and be ready to deal with if you've made the decision to learn C++.
Much of the feature duplication comes from C++ defining a new way of doing something while also retaining whatever solution the C programming language already had for the same kind of thing; some of it also just comes as a result of C++ accreting many new features since it started as "C with classes" forty or so years ago. Some examples I know, off the top of my head (and this is just what I remember from learning some of C++98 many years ago):
To make things more confusing, sometimes the duplication is exact or nearly so (e.g. the different kinds of strings) and sometimes it's just a significant but partial overlap (e.g., there are important things you can do with macros that you can't with templates, and vice versa).
- C-style strings (null-terminated character arrays) vs. C++ std::string objects.
- More generally, C-style arrays vs. C++ template containers (std::vector<T> and such).
- IO with C-style FILE * streams (printf() and co. work with these) vs. C++ stream objects (std::cout and family).
- C-style pointers vs. C++ references and smart pointers.
- The C malloc() and free() standard library functions vs. C++ new[] and delete[] keywords.
- C functions and function pointers vs. C++ functionals (objects with an operator() method), including those created by lambda expressions since C++11.
- C-style macros and C++ templates.
- C and new C++ syntax for casts.
- struct and class (in C++ these are identical except for different defaults).
- C's setjmp()/longjmp() and C++'s try/catch keywords.
- One specific to C++: function overloading, default arguments, and template specialisation.
This trend looks like it's likely to continue. For example, C++ designers are apparently considering adding multi-methods or open-methods to support multiple (runtime) dispatch (as opposed to single dispatch, which is what virtual methods let you do in C++) so a future version of C++ could very well have two different kinds of class methods.
You won't find simple straight forward answers like this in the first book.Mark44 said:Yes.
An array can have any base type, not just the primitive types such as char, short, int, long, float, double, etc. When an array is declared or defined, the number in the brackets indicates how many elements of the given type will be in the array.
I have more questions, seems like both strings and array look the same: myThing[20] and otherThing[20]. The only thing that tells the different a string and array is the declarationMark44 said:Yes.
An array can have any base type, not just the primitive types such as char, short, int, long, float, double, etc. When an array is declared or defined, the number in the brackets indicates how many elements of the given type will be in the array.
The fact that they are declared differently should be a clue that they aren't the same.yungman said:I have more questions, seems like both strings and array look the same: myThing[20] and otherThing[20]. The only thing that tells the different a string and array is the declaration
First off, myThing[20] is not a string -- it's the element one past the end of the string.yungman said:1) std::string myThing[20] that tell people myThing[20] is a 20 element string. Where char otherThing[20] declare it's a 20 element array of characters. In another word, you have to declare it's a string. Am I right?
otherThing[3] = 'b';
) or get an element of the array (char val = otherThing[8];
).This is a C-style array of type char. It has nothing to do with a C++ string object. This array could also be defined in another way:yungman said:2) If the above is true, how come in the first book page 77, when it talk about character string, it just write:
char sayHello[] = { 'H', 'e', 'l','l','o', '\0'} as character string with 6 characters.
char sayHello2[] = "Hello";
No, you can't have a string object with a base type of int, float, and so on. A string object has a base type of char. However, it's possible to form other types of strings with different base types, using the basic_string template class.yungman said:3) I see array can be declared as int, float, char etc. How about strings? Can it be int, float etc.? How do you declare the string ( syntax).
Thanks for the detail reply. I have to take the time to read first. I have to fix the stuffs in your response as it's hard to read. Attached is what I fix to make it easier for me to read. I am sure I will have more question later as I read both books and none of them are really that good.Mark44 said:The fact that they are declared differently should be a clue that they aren't the same.
First off, myThing[20] is not a string -- it's the element one past the end of the string.
Second, you need to distinguish between (1) an array of char (a C-string), which is a contiguous block of memory containing characters, and (2) a C++ Standard Template Library string instance. string is a keyword in C++ but not in C.
Using your examples, otherThing is the name of the array. There are no methods provided for any type of C-style array. The only things you can do are: set an element of the array (otherThing[3] = 'b';
) or get an element of the array (char val = otherThing[8];
).
In contrast, myThing is an instance of the string class. As such, there are lots of member methods and operators such as size(), clear(), capacity(), append(), push_back(), and many more. A C-style array has none of these. See this documentation page: http://www.cplusplus.com/reference/string/string/
This is a C-style array of type char. It has nothing to do with a C++ string object. This array could also be defined in another way:yungman said:2) If the above is true, how come in the first book page 77, when it talk about character string, it just write:
char sayHello[] = { 'H', 'e', 'l','l','o', '\0'} as character string with 6 characters.
Both definitions store the letters in the first 5 bytes of memory, followed by an ASCII null character. Both arrays have a length of 5, the number of characters up to the null.C++:char sayHello2 = "Hello";
No, you can't have a string object with a base type of int, float, and so on. A string object has a base type of char. However, it's possible to form other types of strings with different base types, using the basic_string template class.yungman said:3) I see array can be declared as int, float, char etc. How about strings? Can it be int, float etc.? How do you declare the string ( syntax).
There are four specializations:
basic_string<char> str_ch; // same as string
basic_string<u16string> str_16bit; // a string of 16-bit characters
basic_string<u32string> str_32bit; // a string of 32-bit characters
basic_string<wstring> str_wchar; // a string of wide characters
If you want an array of floats, use the vector template class, like so:
vector<float> vec = {3.2, 2.7, 5.1};[/icode]
I already fixed my reply and the text you quoted.yungman said:I have to fix the stuffs in your response as it's hard to read.
To verify, unless it is specifically defined as std::string myThing[20] that defines it is a 20 elements string. char otherThing[20] is just defining a 20 elements char array.Mark44 said:The fact that they are declared differently should be a clue that they aren't the same.
First off, myThing[20] is not a string -- it's the element one past the end of the string.
Second, you need to distinguish between (1) an array of char (a C-string), which is a contiguous block of memory containing characters, and (2) a C++ Standard Template Library string instance. string is a keyword in C++ but not in C.
Using your examples, otherThing is the name of the array. There are no methods provided for any type of C-style array. The only things you can do are: set an element of the array (otherThing[3] = 'b';
) or get an element of the array (char val = otherThing[8];
).
I can still use sizeof(array) to find the length of the array. This is useful for dynamic array where the length change.Mark44 said:In contrast, myThing is an instance of the string class. As such, there are lots of member methods and operators such as size(), clear(), capacity(), append(), push_back(), and many more. A C-style array has none of these. See this documentation page: http://www.cplusplus.com/reference/string/string/
This is a C-style array of type char. It has nothing to do with a C++ string object. This array could also be defined in another way:
Both definitions store the letters in the first 5 bytes of memory, followed by an ASCII null character. Both arrays have a length of 5, the number of characters up to the null.C++:char sayHello2 = "Hello";
Mark44 said:No, you can't have a string object with a base type of int, float, and so on. A string object has a base type of char. However, it's possible to form other types of strings with different base types, using the basic_string template class.
There are four specializations:
basic_string<char> str_ch; // same as string
basic_string<u16string> str_16bit; // a string of 16-bit characters
basic_string<u32string> str_32bit; // a string of 32-bit characters
basic_string<wstring> str_wchar; // a string of wide characters
If you want an array of floats, use the vector template class, like so:
vector<float> vec = {3.2, 2.7, 5.1};[/icode]
Yes.yungman said:To verify, unless it is specifically defined as std::string myThing[20] that defines it is a 20 elements string. char otherThing[20] is just defining a 20 elements char array.
The sizeof operator can be used to find the size, in bytes, of any type or any variable. It won't tell you how many elements are in the array. This operator is from C that was carried over to C++.yungman said:I can still use sizeof(array) to find the length of the array. This is useful for dynamic array where the length change.
Too much work, plus there are lots of good books out there (and a fair number of mediocre books).yungman said:You should write a book on C++.
#include <iostream>
using namespace std;void displayString(char szString)
{
for (int index = 0; szString[index] != '\0'; index++)
{
cout << szString[index];
}
}
int main(int nNumberofArg, char* pszArgs[])
{
char szName2[] = "Stephen";// declare char szName[8] = "stephen"
cout << "Output szName2: ";
displayString(szName2);
cout << endl;
return 0;
}
It's always more helpful if you tell us which error VS is reporting.yungman said:I have issue building the solution. VS gives me error. This is from the C++ for Dummies. What's wrong with this?
The displayString function is defined as having a char parameter, not a char array parameter. That's the reason for the error.yungman said:C++:#include <iostream> using namespace std;void displayString(char szString) { for (int index = 0; szString[index] != '\0'; index++) { cout << szString[index]; } } int main(int nNumberofArg, char* pszArgs[]) { char szName2[] = "Stephen";// declare char szName[8] = "stephen" cout << "Output szName2: "; displayString(szName2); cout << endl; return 0; }
I think you asked this before. The main() function is called from the operating system. The OS can use this value, particularly if you program is run from a batch file.yungman said:I also have other questions
1) Why I have to declare int main()? What is int for?
No good reason for this particular program, since the program doesn't do anything with the command line arguments. Perhaps in subsequent lessons the book will have an example where you run the program from the command line, and pass arguments that the program does something with.yungman said:2) Why in the first book, it just declare int main(). But in this book it has parameter like int main(int nNumberofArg, char* pszArgs[])?
Thanks