Simple General Questions about C++ [closed] - c++

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
Ive moved from autoit and am now learning C++ and some problems keep coming up.
The first one is storing character input. The problem is that I have no idea how many characters are in that line of the file (if you are reading a file) or how many letters a user is going to type (in a console application).
What is the best way to approach this problem?? I have heard about the string class, but I want to avoid it becuase I dont know how it works and that leads to vunerabilities etc.
Secondly...
In C you can load shellcode into memory, create a function pointer, and execute that code.
Is there any mechanism for this in C++???
Thirdly...
How does the interpreter iterate through char arrays for string output??? (char array[3];) Does the compiler keep track of the size of the array, or does it just keep reading from memory until it hits that \0 thing???
Lastly...
If Char * are just pointers to data in memory, then why does:
char * title = "Program Title";
this work??? where is the string literal stored in memory?? how is it referenced???
Thankyou very much. I greatly appreciate your help.
-Hyperzap

Investing your time in learning std::string is well worth the effort, as it takes care of a lot of hassle for you. If you don't want to take advantage of the features in C++, then why use C++ and not just C?
You can use the same code for this as you would in C.
Yes, iostream-output of C-style strings outputs until terminating zero. Once again, if you use std::string you do not have to care about such details.
Correct me if I'm wrong, but I think title would be a const char[] stored on the stack.
Example:
const char* hello = "Hello\0World";
cout << hello; // Prints only "Hello", i.e. up to terminating zero (\0)
The reason this works:
const char* hello = "Hello world";
cout << hello;
is because hello is really "Hello world\0"; - in other words, the compiler inserts a terminating zero.
Note that std::string doesn't do any magic. It too reads until the terminating zero:
string hello = "Hello\0World\n";
cout << hello; // Still only gives "Hello"

char* title = "String Literal" works because the compiler preallocates a memory location to store your string literal, thus you then get back a pointer to this memory location.
In c++, an array for which you know the size at compile time (as in your example: char array[3] is a type in itself, so the compiler does keep track of the size. However, if you do not know the size (ie. char array[]), it is just a pointer to char. However, you should be using std::vector in c++ (better safety and performance).
I'm not too sure about your other two questions (didn't quite understand them)

Related

Modifying string literals for recursive function [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I've got a recursive function that is supposed to check if a given word is a palindrome, which works by comparing the first and last value, then strips them off and passes them recursively into checkPalindrome, but whenever I try to assign word[size-1] to '\0', I get a Bus Error.
Here is my code:
bool checkPalindrome(char word[]){
int size = std::strlen(word);
//Parts removed...
word[size-1]='\0'; //This is the line causing the issue
return checkPalindrome(word+1);
}
}
Here is an example of a call to this function:
checkPalindrome("racecar");
Thank you!
There are two ways I can think of to solve this problem:
The obvious one would be to use a std::string instead of a string literal and just .pop_back() (C++11) to remove the last character.
The second would be to pass the length of the string to the function as a parameter, instead of computing it. Then, just decrease the length by 1 so now you have a new "fake end point" to the string. Since you're using this number to check the last character, you don't really need to actually modify the string, just change where the "last" character is.
But since you're using C++, I don't see why not use std::string and avoid overcomplicating the problem.
So as stated in the comments you can't modify a string literal.
So before passing it to the function, make a copy of it.
std::size_t len = std::strlen(word);
char* copy = new char[len + 1];
std::strncpy ( copy, word, len + 1 );
isPalindromeR(copy);
delete[] copy;
other solution would be to not use recursion, thus not needing to modify the string.
anyway outside of assignments use a std::string

C++ Multi-Dimensional Array saving/loading to file error [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I've been working on this C++ project for roughly 2 weeks now and I'm stumped on a couple things regarding 2D Arrays. To start off here is the code I wrote as of now:
http://pastebin.com/vCsz947Q
I decided to provide this as a pastebin link due to the fact that it's rather large (it uses 8 functions) and I thought it would save space in this post. I'm new to this site so I apologize if there's a better way that I'm not aware of.
The Problem:
When I go to save my "char seating" array to a .dat file using the "save seats" function that I created, I get a file that gives me the following garbage character " Ì " instead of the intended ' # ' (for open seats) or ' * ' (if a seat is bought).
My functions will save the intended amount of rows (15) and columns (30) despite this though. Also an asterisk will be placed when I go to "purchase a seat" in this program in the file. Additionally my program loads the files as intended, except for the fact that... Well... There's garbage data stored in the seat array.
I feel like this relates to another problem I'm having where if I go to the "purchase seats" function and I say to purchase a seat, it should replace a # with a *, but it doesn't, yet in the saved file it will show an asterisk in the intended spot... Which is very strange.
I have absolutely no idea why this occurs, and what's frustrating is this one thing that's preventing me from finishing this program. I want to believe that my original array in int main that's being called by other functions isn't being updated properly, but I don't know, which is why I came here to seek assistance.
Thank you for your assistance whoever can help.
Well for a start you have some undefined behaviour here inside your displaySeatingChart (char displaySeats[ ][30], float displayPrices[ ]) function with the following:
const int rowDisplay = 15;
const int colDisplay = 30;
as later within one of your loops you have
cout << displaySeats[rowDisplay][colDisplay];
which is clearly reading beyond the array bounds since in main() you define
const int rowMain = 15;
const int colMain = 30;
char seating[rowMain][colMain];
float seatPrices[15];
and pass both seating and seatPrices to the displaySeats function. There may well be other problems with your code but this at least is a clear example of undefined behaviour. Consider stepping through the code with a debugger to get a clearer idea of the source of the issue.
On another note given that you are working with C++ consider working with std::vector instead of arrays. This will give you more scope to ascertain the dimensions of the items that arrays that you are working with from within your utility functions and result in less potential for errors in array access.

Convert std::string to char* debate [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
In C++ 98, is this a legitimate method to cast from a string to a char *?
char * n = (char *) someString.c_str();
(In my original wording, the function above was recommended by a senior programmer)
Namely, is it a better method than:
s2 = (char *)alloca(s0.size() + 1);
memcpy(s2, s0.c_str(), s0.size() + 1);
(courtesy of convert string to char*)
If so, why?
Use Case:
I need to use a char*, but I don't need to alter the data after it is in the char*. I'm passing it to a display library.
I'm just looking for a short and sweet answer. Thanks!
Edit: I changed the wording to this question because it got down voted. I hope my rewording makes it a better question. I think the answers were interesting and insightful.
For the record: Anyone interested in this question, should look at all the responses. I could only pick one, but I found them all interesting.
string::c_str() returns a const pointer to a null-terminated C-style string that contains the same contents as the original string. In most common implementations, c_str() simply returns a pointer to the string's internal data if it is not empty, but that is not required by the C++ standard.
If you just need to read the content of the string and not modify it, there is no need to allocate a separate buffer, just use c_str() by itself. The returned char* will remain valid as long as the string is not altered, either by the =/+=/[] operator, or the insert() or erase() method, or an iterator, etc.
If you need to modify the string via the char* pointer, then you have to allocate a separate buffer, copy the string content into it, modify it as needed, and then copy the new content back to the string using its own methods.
Your senior programmer is wrong. Casting away const-ness like that at the very least is wrong (no guarantees that it points to the actual memory of the string for example), and yields undefined behavior if the underlying objects happen to be const.
The answer here depends on whether you need a mutable string or just to be able to read it.
If all you want to do with your char* is to look at the contents then, as the comments have pointed out, you need to assign it to a const char* (and drop the cast).
Your method works, but if all you need to do is read the string, there is no point in copying it to a new location.
If you need to modify the string, then your copy would be appropriate. However, you need to be aware that changes will not be reflected in the original string.
First off, memcpy does not allocate memory. It only copies things from one place to another.
In C++ the idiom, using memcpy is:
std::string my_string = "California Needs Rain!\n";
char * p_text_string = new char [my_string.length() + 1U];
memcpy(p_text_string,
my_string.c_str(),
my_string.length());
// Add the nul terminator
p_text_string[my_string.length()] = '\0';
Remember that the memory allocated needs to be 1 more than the length of the string because of the nul, '\0', terminator character that needs to be appended.
The std::string is not required to be nul terminated.

String in WinAPI and c++ I/O [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I'm teaching my self WinAPI in c++, but as I progress I notice that every functions in WinAPI returns either char*, DWORD, LPCSTR and etc. My concern is I like using string, so what am I doing is after I get the return value I convert it to string. Is it good or bad? or does it make any difference if I convert it every time? or will it make the process slow or any bad stuffs. And for the I/O in c++, what is better cout or printf considering the size of exe or performance/functionality issue?
Start by learning the various string types. For example char*, LPSTR, and LPCSTR are all related and store ANSI characters; the last is a pointer to a const string. Similarly wchar_t*, WCHAR*, LPWSTR, and LPCWSTR are all related and store Unicode characters; again the last is a pointer to a const string.
Then watch what you mean when you say something like "returns char*" as most Windows APIs do nothing of the sort. Instead they take a LPSTR (a pointer to a char buffer) or LPWSTR (a pointer to a WCHAR buffer), and write into the buffer. Those APIs again almost always either take a count of characters available in the buffer, or have a documented buffer size requirement such as MAX_PATH.
You can use this to your advantage. C++11 requires that a std::wstring or std::string store its characters contiguously, and all known implementations did so well before that. So given an API like GetEnvironmentVariable, you can use the string as the buffer directly and sidestep most conversions. Use code similar to this, but feel free to modify how it interacts with the rest of your code:
std::wstring GetEnvironmentVariable(const std::wstring& strName)
{
DWORD cchValue = MAX_PATH;
std::wstring strValue;
// call API once or twice, to get required buffer size
strValue.resize(cchValue);
cchValue = GetEnvironmentVariable(strName.c_str(), &strValue[0], cchValue);
if (cchValue > MAX_PATH)
{
strValue.resize(cchValue);
cchValue = GetEnvironmentVariable(strName.c_str(), &strValue[0], cchValue);
}
// process errors such as ERROR_ENVVAR_NOT_FOUND
if (0 == cchValue)
{
// throw exception? return empty string? (current code does latter)
}
// remove null character and any extra buffer
strValue.resize(cchValue);
return strValue;
}
There are a lot of further enhancements you can make to this approach.
If you need to support old Windows 9x era operating systems, you can use LPTSTR instead by creating a typedef tstring that maps to std::wstring or std::string per the definition of UNICODE (otherwise I'd suggest just doing wide strings like I showed above). You can do explicit A and W function calls that either overload in C++, or follow the Windows naming convention.
You might be able to refactor the double call into some helper, or at least factor out some of the steps it requires.
You can handle APIs that take an in-out parameter for the buffer size.
You can figure out a way to handle APIs such as GetWindowText that only return a success/failure but do not return their required buffer size, and hide that dance behind your new wrapper function. See the related question and answer for an example approach. (Also note that other approaches may be better for that specific case.)
As far as I/O, there isn't a clear winner. You'll find that it's fairly rare to use the console and console I/O in Windows, so perhaps the question isn't very interesting after all. Aside from that, there are significant tradeoffs when it comes to internationalization; namely it's a lot easier to translate full sentence format strings than to translate the fragments that tend to result from uses of iostream. But if translation isn't a concern for you, that won't influence your decision.
Nearly everything you asked is opinion based. Yes, converting every char* you get to an std::string will be slower, but no it won't make much of a difference. Of course that is completely up to how often you're doing that, and where you'll be running this program. There's absolutely no problem with converting things to std::string in this case, but be warned, you're not going to have a fun time fighting against any API( it's going to be a lot more tedious to convert to and from types all the time. ) In the end, it's completely up to you. Just remember, just because you converted a char* that you allocated with new or malloc into an std::string doesn't mean you don't have to free, or delete it.
I don't see a problem with either printf or std::cout. Once again that's completely opinion based. However, std::cout might be a little easier to use and is certainly more type-safe.

What's the purpose of the char data type in C++? Why not just use strings? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I don't see the point of having the use of single quotes reserved for single characters. So, when is this used? i.e char a = 'a'; Coming from Javascript and PHP, I'm used to being able to use single quotes for entire strings, but after learning that single quotes are reserved for characters in C++, I'm curious to know why? Why would you need a single character?
PHP and JavaScript are languages that operate at quite a high level. This means that the basic types are essentially just a few different types, whose implementation is hidden inside a set of functions in the actual script engine.
C and C++, as well as most other low level languages expose more of "how the machine works". A string, in C, is a sequence of characters. If you want to deal with strings, you need to be able to deal with their components, which is char. A single character becomes useful when you want to build strings, compare the contents of strings, etc. Naturally, for normal string operations in C++, you'd use std::string, and then, like in script languages, most aspects of how the string is actually represented is hidden inside the std::string class implementation, so you don't really need to care about it. But if you were to "look inside" a std::string, it would somewhere sooner or later, become a char *, which is a pointer to a piece of memory that contains a sequence of characters, individual char elements.
One could look at it like going from having "ready made big lumps of Lego" to having only small pieces to work with. You can still build the same things, but it requires more pieces, and requires a bit more effort to construct. What you win is flexibility and speed. A char is really easy to deal with for the processor, where a single character in PHP is still represented as a string - it just happens to be one element long. As such, there is extra overhead in keeping track of this one character string, where it's stored, how long it is, etc, because the functionality in the language doesn't make any distinction between a single character and a string of a megabyte.
The purpose of C, and to a large degree also C++, is to closely represent the hardware. So your basic types are much closer to what the actual hardware representation is, and this is something you will need to learn more about if you are going to understand C and C++ well. Unfortunately, to cover ALL of that would be far beyond a single answer in SO. You will need to get yourself a good C and/or C++ book.
To run things faster and efficient you must learn how to use less space needed. When you have an 'a', this is actually a number (see ASCII table), but when you got "a" it is an array of 2 characters {'a','\0'}. The zero is to know when your string ends because the computer is not sure when the string ends. Do you want to add a length property like in javascript, to know directly the string's length? You use more space that may not be needed. Somehow you have to distinguish these two values to run efficient code. Learning C/C++ first you actually learn how things work on the low level of your computer and understand more than by learning php/javascript/ruby/python first. C++ is more customizable than higher level programming languages.
Javascript and PHP are scripting languages while C++ (and especially its predecessor C) is quite low-level native programming language where you have to consider how your variables are stored in memory.
char a = 'a'; creates a 8-bit-long numeric variable that can hold character value (ASCII code) and put the value of the character a into it. So char a = 97; does the same work.
const char* s = "a"; creates a null terminated string which is an array with two elements: the value of character a and the terminating 0 character (just number 0 or the character '\0'). The * means we create a pointer to the array. Its type is const char because it contains string literal which is constant. We could create an identical array using const char s[2] = { 97, 0 }; or const char s[2] = { 'a', '\0' };.
By the way, single quotes are not reserved exclusively for single characters. You can put a few characters into single quotes. See What do single quotes do in C++ when used on multiple characters?.
The language C++ inherited scalar types from the language C. So you should get a good book about C++ or C to get the details.
The type char is a numeric type. It's an integer that can old a character. It's usually signed but can be overwritten with the signed or unsigned prefix. Additionally the signedness can be configured at the compiler. The 'A' literal defines a number that is identical to the code of the character A.
The "a" string is an array of char's and has a zero termination. In the example you have two bytes 'a','\0'. When you use the literal the compiler passes the address as a pointer to the array. This pointer can be assigned to pointer variable
char *s = "A";
or passed to a function
foo("A");
Additionally there are all the pointer arithmentics possible that you can grasp when you got the meaning of a char array.
Edit Both the number literal 'a' and the char array "A" are const objects. It's obvious that you can't assign anything to a number like
'a' = 23; // wrong!
When you assigned the literal to variable you can change the variable later tough.
But when you stored the pointer in a pointer variable it's illegal and you get undefined behavior when you try to modify the char array:
char *s = "A";
*s = 'B'; // try to change the first byte of the char array, causes undefined behavior.
To express this it's good style to use a pointer to const char variable:
const char *s = "A";
*s = 'B'; // compiler diagnostic says: not allowed