C++ string to fixed sized char array possible? - c++

Hi i have the following code:
char msg[10000];
string mystr = "hello";
I want to put mystr into msg. Is there a way to do that? I tried all sorts of methods, but keep getting:
incompatible types in assignment of 'const char*' to char [10000]'
I tried:
msg = mystr.c_str();
and
msg = (char[10000])mystr;
to no avail.

You can try std::copy for this. Something like:
std::copy(mystr.begin(), mystr.end(), msg);
I would avoid C string functions like mempcy and strcpy in C++.

Take a look at string::copy - it takes a string an puts it into an array.
In your case it would be:
std::size_t length = mystr.copy(msg,10000);
msg[length]='\0';

char msg[10000];
string mystr = "hello";
strcpy(msg, mystr.c_str());
cout<<msg;

Use copy member function of std::string:
size_t len = mystr.copy(msg, (sizeof msg)-1);
msg[len] = 0;

String assignment in C is different. You have to copy the bytes into your destination string.
memcpy_s(msg, 1000, mystr.c_str(), mystr.length()) // safe windows version
memcpy(msg, mystr.c_str(), mystr.length()) // unix version

Use strcpy function :
http://www.cplusplus.com/reference/clibrary/cstring/strncpy/
strncpy(msg, mystr.c_str(), sizeof msg / sizeof msg[0]);
msg[sizeof msg / sizeof msg[0] - 1] = 0; // null-terminate in case of truncation

Compilers sometimes produce wonky error messages for array types.
Here's an accumulation of previous answers into a paste-and-compile program.
#include <string>
#include <iostream>
#if 1
int main(int argc, char **argv)
{
using std::cout;
using std::endl;
char msg[1000] = {0}; // initialize to 0 here since we're printing below
// the <type> <array-name>[<size>] = {0} just fills a POD struct or an array with 0s
std::string mystr = "hello";
// if, at some point, you have things changing "mystr"
// you'll need to make sure that it will fit in msg[]
cout << "Before strcpy: \"" << msg << "\"" << endl;
// I'll just finish the statement in mystr...
mystr += " world!";
if(mystr.length() < sizeof(msg)){
strcpy(
msg, // <- put in here until we find a '\0'
mystr.c_str() // <- take from here (which could be a temporary buffer)
);
}
//MSC will complain about strcpy being unsafe
//
// you can use the below instead (if you really feel the need to), which is
// the MS-specific equivalent to the above.
/*
strcpy_s(
msg, // <- put in here until we find a '\0' or the size limit is reached
sizeof(msg), // <- don't put any more than this many chars in msg
mystr.c_str() // <- take from here
);
*/
cout << "After strcpy: \"" << msg << "\"" << endl;
return 0;
}
#else
// Similarly, using wchar_t (a usually non-byte-sized character type)
//
// note where the divisions occurr
int main(int argc, char **argv)
{
using std::wcout;
using std::endl;
wchar_t msg[1000] = {0};
std::wstring mystr = L"hello";
wcout << "Before strcpy: \"" << msg << "\"" << endl;
mystr += L" world";
if(mystr.length() < (sizeof(msg)/sizeof(wchar_t))){
// mystr wil fit!
wcscpy(
msg, // <- put in here until we find a '\0'
mystr.c_str() // <- take from here (which could be a temporary buffer)
);
}
// Similar to the char case in the first preprocessor block
/*
wcscpy_s(
msg, // <- put in here until we find a '\0' or the size limit is reached
sizeof(msg)/sizeof(wchar_t), // <- don't put any more than this many wchar_ts in msg
mystr.c_str() // <- take from here
);
*/
wcout << "After strcpy: \"" << msg << "\"" << endl;
return 0;
}
#endif
I shall leave it to you to read the documentation on all related functions.

Related

C++ String to byte

so i have a string like this:std::string MyString = "\\xce\\xc6";
where when i print it like this:std::cout << MyString.c_str()[0] << std::endl;
as output i get:\
and i want it to be like this:std::string MyDesiredString = "\xce\xc6";
so when i do:
std::cout << MyDesiredString.c_str()[0] << std::endl;
// OUTPUT: \xce (the whole byte)
so basically i want to identify the string(that represents bytes) and convert it to an array of real bytes
i came up with a function like this:
// this is a pseudo code i'm sure it has a lot of bugs and may not even work
// just for example for what i think
char str_to_bytes(const char* MyStr) { // MyStr length == 4 (\\xc6)
std::map<char*, char> MyMap = { {"\\xce", '\xce'}, {"\\xc6", 'xc6'} } // and so on
return MyMap[MyStr]
}
//if the provided char* is "\\xc6" it should return the char '\xc6'
but i believe there must be a better way to do it.
as much as i have searched i haven't found anything useful
thanks in advance
Try something like this:
std::string teststr = "\\xce\\xc6";
std::string delimiter = "\\x";
size_t pos = 0;
std::string token;
std::string res;
while ((pos = teststr.find(delimiter)) != std::string::npos) {
token = teststr.substr(pos + delimiter.length(), 2);
res.push_back((char)stol(token, nullptr, 16));
std::cout << stol(token, nullptr, 16) << std::endl;
teststr.erase(pos, pos + delimiter.length() + 2);
}
std::cout << res << std::endl;
Take your string, split it up by the literals indicating a hex. value is provided (\x) and then parse the two hex. characters with the stol function as Igor Tandetnik mentioned. You can then of course add those byte values to a string.

error converting const char* to char

I am trying to convert one char variable to a const char variable but I have the below error . Content of variable char is ok, in this case is a "H" and "e" but when I convert to const char* I have the letter + something else after. Can you guys please tell me where I did something wrong ?
Please see the picture from link !
#include <iostream>
#include <Windows.h>
#include <lmcons.h>
#include <stdio.h>
#include <stdlib.h>
char Body[] = { 'H', 'e', 'l', 'l', 'o' }; // elements of char array
int size = sizeof(Body); // get size of Body array
char Line;
std::cout << "Size : " << size << "\n"; // view the size of Body array
for(int i=0; i<=size; i++) // for statement : from first element to the last element of array
{ // beginning of for statement
Line = Body[i]; // get each element from Body array and put to char variable
std::cout << "Char : " << Line << "\n"; // view the content of char variable
const char *Line2 = &Line ; // convert from from char to const char*
std::cout << "Const char : " << Line2 << "\n"; // view the content of const char* variable
} // end of for statement
enter image description here
const char *Line2 = &Line ;
Doesn't magically create a string from your character; as a string must be Null (or 0) terminated you can't pass this pointer to cout as it's expecting multiple characters to be processed. If you were to change it to be
char Line[2] = {0}; // 0 initialise all the chars
Line[0] = Body[i];
Line[1] = 0; // completely not required, but just making the point
char* Line2 = &Line[0]; // there are other cleaner ways, but this shows explicitly what is happening
std::cout << Line2;
You would not have UB.
The problem is that you are not terminating Body with a null char(\0). And the second problem is your loop you are trying to access something that is out of range. The code should be like this:
char Body[] = { 'H', 'e', 'l', 'l', 'o', '\0' }; // elements of char array
int size = sizeof(Body); // get size of Body array
char Line;
std::cout << "Size : " << size << "\n"; // view the size of Body array
for(int i=0; i<size; i++) // for statement : from first element to the last element of array
{ // beginning of for statement
Line = Body[i]; // get each element from Body array and put to char variable
std::cout << "Char : " << Line << "\n"; // view the content of char variable
const char *Line2 = &Line ; // convert from from char to const char*
std::cout << "Const char : " << Line2 << "\n"; // view the content of const char* variable
} // end of for statement
You need null char at the end of the any raw string in c/c++ language because this helps it understand the ending of the string.
The problem is that you are accessing Body[5], when running the loop as
for(int t=0;t<=sizeof(Body);t++){}
if you remove that = sign it will be okay.
for(int t=0;t<sizeof(Body);t++){}
Also, try to convert
std::const char *Line2 = const_cast<const char *>(&Line );
Use std::const_cast<>() to convert non constant to constant data types.
Also to remove those extra things from console you need to dereference the const char *, if you directly use it. std::cout tries to print everything until null is encountered in case you pass it const char *
So,
std::cout << "Const char : " << *Line2;

How to ignore new lines while reading blocks of data from file

Im trying to read blocks of data from a file, but I couldn't know how to ignore the newline character when I use istream::read.
Im aware that I can use for loop to load the characters to a cstring one by one with condition to ignore new lines character, but I hope there is clever way to solve this problem.
My intention to avoid using strings or vectors.
#include <iostream>
#include <fstream>
#include <cstring>
void readIt(char* fileName) {
std::ifstream seqsFile;
seqsFile.open(fileName) ;
if (seqsFile.fail()) {
std::cout << "Failed in opening: " << fileName << std::endl;
std::exit(1);
}
seqsFile.seekg(84);
char *buffer;
buffer = new char [7];
seqsFile.read(buffer, 7);
buffer[7] = 0;
std::cout << buffer << std::endl;
}
int main(int argc, char** argv) {
readIt(argv[1]);
return 0;
}
file:
gsi|33112219|sp|O
GACATTCTGGTGGTGGACTCGGAGGCATGATAGCAGGTGCAGCTGGTGCAGCCGCAGCAGCTTATGGAGC
GCAGCAGCTTATGGAGC
current output:
GAGC
GC
desired output:
GAGCGCA
modified version:
void readIt(char* fileName) {
std::ifstream seqsFile;
seqsFile.open(fileName) ;
if (seqsFile.fail()) {
std::cout << "Failed in opening: " << fileName << std::endl;
std::exit(1);
}
seqsFile.seekg(84);
char *buffer;
buffer = new char [7];
char next ;
for ( int i = 0 ; i < 7; i++) {
seqsFile.get(next);
if (next=='\n') {
i--;
continue;
}
buffer[i] = next;
}
buffer[7]=0;
std::cout << buffer << std::endl;
}
Your program has undefined behavior since you are modifying buffer using an out of range index. You have:
buffer = new char [7]; // Allocating 7 chars.
seqsFile.read(buffer, 7); // Reading 7 chars. OK.
buffer[7] = 0; // 7 is an out of range index. Not OK.
Allocate memory for at least 8 chars.
buffer = new char [8];
Also, when you intend to read the contents of a file using istream::read, it is recommended that you open the file in binary mode.
seqsFile.open(fileName, std::ios_base::binary) ;
Well, you can not tell not to read newlines - they will appear in your buffer variable anyway and you have to handle it.
Also, you have to fix the buffer size, as R Sahu mentioned
Regarding your question, i can suggest following snippet:
while ((index = strlen(buffer)) < 7)
{
seqsFile >> &buffer[index];
}
strlen here will return size of buffer upto /0 or newline character as well
You didn't tell what to do with whitespaces, so they will be ignored as well

C++ Concatenating const char * with string, only const char * prints

I am trying to cout a const char *
This is how I convert an int to a string and concatenate it with the const char*
char tempTextResult[100];
const char * tempScore = std::to_string(6).c_str();
const char * tempText = "Score: ";
strcpy(tempTextResult, tempText);
strcat(tempTextResult, tempScore);
std::cout << tempTextResult;
The result when printing is: Score:
Does anyone know why the 6 is not printing?
Thanks in advance.
As the docs for c_str say, "The pointer returned may be invalidated by further calls to other member functions that modify the object." This includes the destructor.
const char * tempScore = std::to_string(6).c_str();
This makes tempScore point to a temporary string that no longer exists. You should do this:
std::string tempScore = std::to_string(6);
...
strcat(tempTextResult, tempScore.c_str());
Here, you're calling c_str on a string that continues to exist.
You have marked this post as C++.
One possible C++ approach: (not compiled, not tested)
std::string result; // empty string
{
std::stringstream ss;
ss << "Score: " // tempText literal
<< 6; // tempScore literal
// at this point, the values placed into tempTextResult
// are contained in ss
result = ss.str(); // because ss goes out of scope
}
// ss contents are gone
// ... many more lines of code
// ... now let us use that const char* captured via ss
std::cout << result.c_str() << std::endl;
// ^^^^^^^ - returns const char*

C++ Character Array Error Handling

If I declare a string array in c++ such as
char name[10]
how would you error handle if the input is over the character limit?
Edit: My assignment says to use cstring rather than string. Input will be the person's full name.
Here is an example where setName checks the size is OK before assigning the char[10] attribute.
Note char[10] can only store a 9-characters name, because you need one character to store the end-of-string.
Maybe that's what you want:
#include <iostream>
#include <cstring>
using namespace std;
#define FIXED_SIZE 10
class Dummy
{
public:
bool setName( const char* newName )
{
if ( strlen( newName ) + 1 > FIXED_SIZE )
return false;
strcpy( name, newName );
return true;
}
private:
char name[FIXED_SIZE];
};
int main()
{
Dummy foo;
if ( foo.setName( "ok" ) )
std::cout << "short works" << std::endl;
if ( foo.setName( "012345678" ) )
std::cout << "9 chars OK,leavs space for \0" << std::endl;
if ( !foo.setName( "0123456789" ) )
std::cout << "10 chars not OK, needs space for \0" << std::endl;
if ( !foo.setName( "not ok because too long" ) )
std::cout << "long does not work" << std::endl;
// your code goes here
return 0;
}
I'm piecing together that your instructions say to use <cstring> so you can use strlen to check the length of the string prior to "assigning" it to your name array.
so something like...
const int MAX_NAME_LEN = 10;
char name[MAX_NAME_LEN];
// ...
// ...
if (strlen(input)+1 >= MAX_NAME_LEN) {
// can't save it, too big to store w/ null char
}
else {
// good to go
}
First of all your question is not clear. Anyway I assume you want to ask for a way to ensure array index does not get out of bound.
Anything outside of that range causes undefined behavior. If the index was near the range, most probably you read your own program's memory. If the index was largely out of range, most probably your program will be killed by the operating system.
That means undefined behaviour could mean program crash, correct output etc.
Since others mentioned how to do this with a predefined input string, here's a solution which reads a c-string from input:
#include <iostream>
#define BUF_SIZE 10
using namespace std;
int main()
{
char name[BUF_SIZE];
cin.get(name, BUF_SIZE-1);
if (cin) //No eof
if (cin.get() != '\n')
cerr << "Name may not exceed " << BUF_SIZE-1 << " characters";
}