Converting String to Char

Pages: 12
I have imported an file with ASCII format into a string array. Now I want to convert those ASCII numbers to a character. In the last FOR loop, I tried to typcast the string into a CHAR but it didnt work. Any help would be appreciated.

Thanks,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
  #include <iostream>
#include <ostream>
#include <fstream>
#include <Windows.h>
#include <string>

using namespace std;

#ifndef _MESSAGE_H_
#define _MESSAGE_H_
void message()
{
	ifstream inFile;
	string messageIn[10000];
	
	inFile.open("message.dat", ios::in | ios::binary);

	if(inFile.fail())
		{
			cout << "File did not open!";
			Sleep(2000);
			exit(1);
		}

	else
		{

			for(int i=0;i<10000;i++)
				{					
					getline(inFile,messageIn[i]);									
				}
			inFile.close();

			
		}
	for(int f=0;f<10000;f++)
	{
		cout  << char(messageIn[f]);
	}
	


}

#endif 
closed account (Dy7SLyTq)
a) you dont have include guards in a cpp file
b) if it is a header, you dont define functions in them
c) you cant convert a string to a char. that doesnt make any sense
if you had "Hello, world!" then how would that be a char
d) its (char)messageIn[f]; not char(messageIn[f]);
While I agree with most of what DTSCode said... I must contradict point d.

char(messageIn[f]); is perfectly acceptable.
closed account (Dy7SLyTq)
it is? does it do the same thing? does it work the same way?
Thats the way I was taught, but I'm still learning.

Essentially I've read a file with ASCII numbers into a string array. Now I need to display that sting array but convert it from ASCII to an actual character.
closed account (Dy7SLyTq)
i dont think you can convert a whole string to a single character just do
cout<< messageIn[f] << endl; and you cant "convert from ascii to char". that doesnt make any sense
I tried cout << messageIn[f] << endl; which gives me the ASCII number. Now I want to take that number which looks like this when I print it out:


1
2
89 111 117 32 104 etc.......


extract each of those number from my string then read in each number and type cast it as a character.
I disagree DTSCode you can convert from ascii to char easy.

 
char ch = 65;
chars ARE ascii.
closed account (Dy7SLyTq)
chars ARE ascii.

exactly my point. ch is a char. 65 in an int literal. neither are ascii. ascii is not a type so you cant convert to or from it. ascii dictates what character ch will hold when passed 65.
ascii is the code (number) that stores the letter (character) so technically a character is an integer in programming. He meant convert char to an int though. So what he'd have to do is
 
(int) some_char;


or
static_cast<int>( some_char );
closed account (Dy7SLyTq)
i understand that, but thats not converting between ascii and int
Just to be an asshole, I'll disagree with this:
b) if it is a header, you dont[sic] define functions in them

Typically this is true, but not in the case of templates. As far as I know there's only a few hacky ways to split the implementations of a template class into a seperate .cpp file.

derail :(
closed account (Dy7SLyTq)
i didnt think about that. alright ill rephrase. you should not have include guards in a .cpp file. if it is a .h file, with the exception of templates and inline class methods, you shouldnt define functions in a header file
Essentially I've read a file with ASCII numbers into a string array. Now I need to display that sting array but convert it from ASCII to an actual character.


Question1: what does the file look like?
Question2: why not input the numbers into an integer array?
Last edited on
if it is a .h file, with the exception of templates and inline class methods, you shouldnt define functions in a header file

Another exception is small normal functions; I use this approach for utilities like (maths) sqr(), (string) trim, etc. i.e. functions which you are sure will be inlined.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// geoutils.h
//
// It is good practice to use a namespace when this approach is used in action.

#ifndef INC_GEOUTILS_H // identifers beginning _G, _H (or any other capital
#define INC_GEOUTILS_H // letter) are reserved for library writers.

const double Pi = 3.1415927; // in C++, consts have internal linkage by default

inline double sqr(double x) {
    return (x * x);
}

inline double calc_circle_area(double r) {
    return (Pi * sqr(r));
}

#endif // INC_GEOUTILS_H 


Andy
Last edited on
By the way, while C++ doesn't mind whether you use a C-style

(char)messageIn[f];

or a function style cast

char(messageIn[f]);

neither work here as you're trying to cast a std::string (a class) to a char, which would only work if std::string happened to provide the appropriate char cast operator, which is doesn't. None of static_cast<>, dynamic_cast<> and reinterpret_cast<> can handle this case, either.

MSVC wrote:
For C-style and function style casts, and static) cast (though message starts off with '<function-style-cast>' and 'static_cast' rather than 'type cast'.)

error C2440: 'type cast' : cannot convert from 'std::string' to 'char'
1>          No user-defined-conversion operator available that can perform this conversion,
            or the operator cannot be called

For interpret_cast<> and const_cast<> the error code is the same, but the message is a bit different:

error C2440: 'static_cast' : cannot convert from 'std::string' to 'char'
1>          Conversion requires a constructor or user-defined-conversion operator, which
            can't be used by const_cast or reinterpret_cast


And for completeness, attempting to use dynamic_cast<> results in a different error code:

error C2680: 'char' : invalid target type for dynamic_cast
1>          target type must be a pointer or reference to a defined class


GCC wrote:
For C-style and function style casts, and static_cast<> and reinterpret_cast<>

error: invalid cast from type 'std::string {aka std::basic_string<char>}' to type 'char'

For const_cast<>

error: invalid use of const_cast with type 'char', which is not a pointer, reference,
 nor a pointer-to-data-member type

And for dynamic_cast<>

error: cannot dynamic_cast 'messageIn[f]' (of type 'std::string {aka
class std::basic_string<char>}') to type 'char' (target is not pointer or reference)


What you need to do here is either:

A. First convert the string to an int, and then display that int value as a char.

e.g. (using stoi)

cout << (char)stoi(messageIn[f]);

or

cout << char(stoi(messageIn[f]));

or even

cout << static_cast<char>(stoi(messageIn[f]));

Or...

B. Read the values into a int (or even char?) array, as Yanson suggested above. (This is effectively doing the same work as stoi(), but when you read the value from the file.)

I am assuming here that the file contains the ASCII values as strings, going by line 30 of the original code and the way the values display (i.e. your example 89 111 117 32 104 etc.......)

If you're compiler doesn't support stoi out of the box you will need to either switch to another mechanism or roll your own (see notes below.)

Andy

stoi
http://www.cplusplus.com/reference/string/stoi/

For Visual C++ you need version 2010 or higher for stoi.

For GCC I am not sure of the version stoi appeared in, but I do know that stoi is still broken in the MinGW version (version 4.8.1)

There is a patch, but it is prob. easier to just code your own basic version if it's just for educational reasons. For info and caveats about the patch, see link below. (Prob. something you should only attempt if you're sure fully undertand what you're doing. And you back everything up!)

EDIT: the patch worked easily enough for 4.7.x, but appears to be broken for 4.8.1 :-(

EDIT: with version 4.8.1 I had to make one change in addition to those explained in the post linked to below: see note below.

If you want to write a header which exposes a custom version of stoi (etc) just for MinGW GCC, then you can test against the #define __MINGW32__

Enabling string conversion functions in MinGW
http://tehsausage.com/mingw-to-string

In addition to the changes explained in this post, I had to tweak the C++ config file:

<mingw-root>\lib\gcc\mingw32\4.8.1\include\c++\mingw32\bits\c++config.h

so line 1232 (in my case) read

#define _GLIBCXX_USE_C99 1

rather than

/* #undef _GLIBCXX_USE_C99 */

Macros __MINGW32__ AND __MINGW64__
http://mingw.5.n7.nabble.com/Macros-MINGW32-AND-MINGW64-td26319.html
Last edited on
Yanson -
Question1: what does the file look like?
1
2
89 111 117 32 104 97 118 101 32 114 101 ......etc...
           

Question2: why not input the numbers into an integer array?
Because it is in ASCII format and its not continuous. There are spaces in between the numbers.

Andywestken:
WOW - thank you very much for providing so much information. I'm going to sift through what you gave me and try and figure it out.

I'm very new to C++ and I enjoy it, and while in this class I do look up a lot of stuff on google, but I usually come here for help if I had hit a wall.

Again thanks guys or gals.
closed account (Dy7SLyTq)
Because it is in ASCII format

one more time... that means nothing you can still read in to an int. there is no "int" format for a file. you can read in the character 6 to an int and it will be 6
Given the way your code uses getline, I would hope your file is actually formatted like

89
111
117
32
104
...etc...


as getline reads a line at a time (by default), as it's name suggests.

If your file is formatted as you say, then all the data is probably being read into the first element of your array.

Give operator>> a go, instead of getline.

Andy

PS Given you're using a text file I think you should change your file open statement, which is currently

16
17
18
	inFile.open("message.dat", ios::in | ios::binary);

	//etc 


so it does not use the ios::binary flag (that doesn't really make sense when you're using getline (or operaror>>) to read a text file.)
Last edited on
Ok, so I was able to copy the string to a Cstring, which of course is a char Array. But when I try to display it as a character, it gives me the numbers again. I even tried typecasting (which doesnt make any sense, I know) but it still doesnt give me the char. Am I coping over the actual numbers when I do a string copy into a cstring, or am I coping over something else?


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
void message()
{
	ifstream inFile;
	string messageIn[2000];
	char messageChar[2000];
	
	

	
	
	inFile.open("message.dat", ios::in);

	if(inFile.fail())
		{
			cout << "File did not open!";
			Sleep(2000);
			exit(1);
		}

	else
		{
			for(int i=0; i<2000;i++)
			{
				getline(inFile,messageIn[i]);
				strcpy(messageChar,messageIn[i].c_str());
				cout << messageChar[i];
				//cout << (char)messageChar[i];
			}			
		}
		inFile.close();		
	

	


}
Pages: 12