invalid conversion from ‘char*’ to ‘char’ - c++

I have a,
int main (int argc, char *argv[])
and one of the arguements im passing in is a char. It gives the error message in the title when i go to compile
How would i go about fixing this?
Regards
Paul

When you pass command line parameters, they are all passed as strings, regardless of what types they may represent. If you pass "10" on the command line, you are actually passing the character array
{ '1', '0', '\0' }
not the integer 10.
If the parameter you want consists of a single character, you can always just take the first character:
char timer_unit = argv[2][0];

If you only ever want the first character from the parameter the folowing will extract it from string:
char timer_unit = argv[2][0];
The issue is that argv[2] is a char* (C-string) not char.

You are probably not passing in what you think (though this should come from the command line). Please show the complete error message and code, but it looks like you need to deal with the second argument as char *argv[], instead of char argv[] -- that is, as a list of character arrays, as opposed to a single character array.

Everything stays strings when you pass them in to your program as arguments, even if they are single characters. For example, if your program was called "myprog" and you had this at the command line:
myprog arg1 53 c a "hey there!"
Then what you get in the program is the following:
printf("%d\n", argc);
for(int i = 0; i < argc; i++)
{
printf("%s\n", argv[0]);
}
The output of that would be:
6
myprog
arg1
53
c
a
hey there!
The point being that everything on the command line turns into null-terminated strings, even single characters. If you wanted to get the char 'c' from the command line, you'd need to do this:
char value = argv[3][0];
not
char value = argv[3]; // Error!
Even the value of "53" doesn't turn into an int. you can't do:
int number = argv[2]; // Error!
argv[2] is { '5', '2', '\0' }. You have to do this:
int number = atoi(argv[2]); // Converts from a string to an int
I hope this is clear.
Edit: btw, everything above is just as valid for C (hence the printf statements). It works EXACTLY the same in C++.

Related

I am not sure why I am getting output for this?

I was learning some string handling in C++ and was doing hit and trail on a code and surprisingly got output for the given code.
#include<bits/stdc++.h>
using namespace std;
int main(){
char str[12]={'\67','a','v','i'};
cout<<str;
return 0;
}
Surprisingly I get 7avi printed .
But if I replace '\67' with '\68'. The following error is shown on Repl.it (https://repl.it/languages/cpp)
#include<bits/stdc++.h>
using namespace std;
int main(){
char str[12]={'\68','a','v','i'};
cout<<str;
return 0;
}
main.cpp:6:19: warning: multi-character character constant [-Wmultichar]
char str[12]={'\68','a','v','i'};
^
main.cpp:6:19: error: constant expression evaluates to 1592 which cannot
be narrowed to type 'char' [-Wc++11-narrowing]
char str[12]={'\68','a','v','i'};
^~~~~
main.cpp:6:19: note: insert an explicit cast to silence this issue
char str[12]={'\68','a','v','i'};
^~~~~
static_cast<char>( )
main.cpp:6:19: warning: implicit conversion from 'int' to 'char' changes
value from 1592 to 56 [-Wconstant-conversion]
char str[12]={'\68','a','v','i'};
~^~~~~
2 warnings and 1 error generated.
compiler exit status 1
Please someone explain this behavior.
The \nnn notation, where nnn are digits between 0 and 7, is for octal (base 8) notation. So in \68, 68 is not a valid octal number. The number one more than 67 is 70. The way it's interpreting the code is that you have '\6' as character 6 in octal, but then an additional '8' ASCII character inside your character literal - hence a multi-character constant, which can not be stored in a char variable. You could store it in a "wide character":
wchar_t str[12]={'\68','a','v','i'};
But, there is no operator<< overload to display an array of wchar_t, so your cout << str line will match the void* overload and just display the memory address of the first element in the array, rather than any of the characters themselves.
You can fix that using:
wcout << str;
Separately, I recommend putting a newline after your output too. Without it, your output may be overwritten by the console prompt before you can see it, though that doesn't happen in the online REPL you're using. It should look like:
wcout << str << '\n';
I think you're trying to type in an ASCII character using either octal or hex.(octal usually begins with a 0, but hex with a 0x). Just don't put the the ASCII code in quotes, instead put the code straight into the array, like so:
char str[12] = {68, 'a', 'v', 'i'}; //decimal
char str[12] = {0x44, 'a', 'v', 'i'}; //hex
char str[12] = {0104, 'a', 'v', 'i'}; //octal
Side Note
Please don't use <bits/stdc++.h>. It's not standardized(see here, for a more detailed explanation.) Instead include <iostream> for cout and the other requisite libraries for your other needs.

How to convert a std::string which contains '\0' to a char* array?

I have a string like,
string str="aaa\0bbb";
and I want to copy the value of this string to a char* variable. I tried the following methods but none of them worked.
char *c=new char[7];
memcpy(c,&str[0],7); // c="aaa"
memcpy(c,str.data(),7); // c="aaa"
strcpy(c,str.data()); // c="aaa"
str.copy(c,7); // c="aaa"
How can I copy that string to a char* variable without loosing any data?.
You can do it the following way
#include <iostream>
#include <string>
#include <cstring>
int main()
{
std::string s( "aaa\0bbb", 7 );
char *p = new char[s.size() + 1];
std::memcpy( p, s.c_str(), s.size() );
p[s.size()] = '\0';
size_t n = std::strlen( p );
std::cout << p << std::endl;
std::cout << p + n + 1 << std::endl;
}
The program output is
aaa
bbb
You need to keep somewhere in the program the allocated memory size for the character array equal to s.size() + 1.
If there is no need to keep the "second part" of the object as a string then you may allocate memory of the size s.size() and not append it with the terminating zero.
In fact these methods used by you
memcpy(c,&str[0],7); // c="aaa"
memcpy(c,str.data(),7); // c="aaa"
str.copy(c,7); // c="aaa"
are correct. They copy exactly 7 characters provided that you are not going to append the resulted array with the terminating zero. The problem is that you are trying to output the resulted character array as a string and the used operators output only the characters before the embedded zero character.
Your string consists of 3 characters. You may try to use
using namespace std::literals;
string str="aaa\0bbb"s;
to create string with \0 inside, it will consist of 7 characters
It's still won't help if you will use it as c-string ((const) char*). c-strings can't contain zero character.
There are two things to consider: (1) make sure that str already contains the complete literal (the constructor taking only a char* parameter might truncate at the string terminator char). (2) Provided that str actually contains the complete literal, statement memcpy(c,str.data(),7) should work. The only thing then is how you "view" the result, because if you pass c to printf or cout, then they will stop printing once the first string terminating character is reached.
So: To make sure that your string literal "aaa\0bbb" gets completely copied into str, use std::string str("aaa\0bbb",7); Then, try to print the contents of c in a loop, for example:
std::string str("aaa\0bbb",7);
const char *c = str.data();
for (int i=0; i<7; i++) {
printf("%c", c[i] ? c[i] : '0');
}
You already did (not really, see edit below). The problem however, is that whatever you are using to print the string (printf?), is using the c string convention of ending strings with a '\0'. So it starts reading your data, but when it gets to the 0 it will assume it is done (because it has no other way).
If you want to simply write the buffer to the output, you will have to do this with something like
write(stdout, c, 7);
Now write has information about where the data ends, so it can write all of it.
Note however that your terminal cannot really show a \0 character, so it might show some weird symbol or nothing at all. If you are on linux you can pipe into hexdump to see what the binary output is.
EDIT:
Just realized, that your string also initalizes from const char* by reading until the zero. So you will also have to use a constructor to tell it to read past the zero:
std::string("data\0afterzero", 14);
(there are prettier solutions probably)

"strncpy_s" Not Working

I'm trying to use strncpy_s to characters from one word to an array (I cannot use strncpy in Visual Studio 2013 and I'm totally new to strncpy_s). I keep getting these errors whatever I do:
Error 1 error C2660: 'strncpy_s' : function does not take 3 arguments
Error 2 IntelliSense: no instance of overloaded function "strncpy_s"
matches the argument list argument types are: (char *, char, int)
The purpose of my code is:
If user inputs, for example, "HELLO" (that is, text = HELLO)
Then ->
Copy HELLO to first_array [0]
Copy ELLO to first_array [1]
Copy LLO to first_array [2]
Copy LO to first_array [3]
Copy O to first_array [4]
And here's my code:
int _tmain(int argc, _TCHAR* argv[])
{
char text[32];
cin >> text;
char* first_array[] = {""};
int n = strlen(text);
for (int i = 0; i < n; i++)
{
strncpy_s(first_array[i], text[i], n-i);
}
}
EDIT 1. Modified the code a bit more, now the program runs, but after inputing a text, it suddenly gives me the "example.exe stopped working" error.
int _tmain(int argc, _TCHAR* argv[])
{
char* text[32];
cin >> *text;
char* first_array[] = {""};
//int n = strlen(text);
int n = sizeof(text);
for (int i = 0; i < n; i++)
{
strncpy_s(first_array[i], n - i, text[i], 32);
}
Your code has several issues.
First of all, your call to strncpy_s does not follow the declaration of strncpy_s, which lists four parameters (if the first parameter is a char * as in your case):
errno_t strncpy_s(
char *strDest,
size_t numberOfElements,
const char *strSource,
size_t count
);
But much more importantly, you state that you would like to end up with multiple strings in an array first_array[], each holding a shorter version of the input string than the last. But the first_array[] you declared only holds one char * string, the one you initialized first_array[0] to, which is exactly one character long (the terminating null byte):
char* first_array[] = {""};
Even if you declared it to hold five char * (the initialization is not necessary as you copy the contents over anyway)...
char * first_array[5];
...you still haven't allocated memory space for each of the five char * strings. You just have five pointers pointing nowhere, and would have to allocate memory dynamically, depending on user input.
Because I haven't even talked about what happens if the user enters more than five characters, let alone 32...
At this point, even if I would post "working" code, it would teach you little. You are apparently following some kind of tutorial, or actually attempting to learn by trial & error. I think the right answer here would be:
Get a different tutorial. Even better, get a good book on C or a good book on C++ as online tutorials are notoriously lacking.

How to convert an ASCII char to its ASCII int value?

I would like to convert a char to its ASCII int value.
I could fill an array with all possible values and compare to that, but it doesn't seems right to me. I would like something like
char mychar = "k"
public int ASCItranslate(char c)
return c
ASCItranslate(k) // >> Should return 107 as that is the ASCII value of 'k'.
The point is atoi() won't work here as it is for readable numbers only.
It won't do anything with spaces (ASCII 32).
Just do this:
int(k)
You're just converting the char to an int directly here, no need for a function call.
A char is already a number. It doesn't require any conversion since the ASCII is just a mapping from numbers to character representation.
You could use it directly as a number if you wish, or cast it.
In C++, you could also use static_cast<int>(k) to make the conversion explicit.
Do this:-
char mychar = 'k';
//and then
int k = (int)mychar;
To Convert from an ASCII character to it's ASCII value:
char c='A';
cout<<int(c);
To Convert from an ASCII Value to it's ASCII Character:
int a=67;
cout<<char(a);
#include <iostream>
char mychar = 'k';
int ASCIItranslate(char ch) {
return ch;
}
int main() {
std::cout << ASCIItranslate(mychar);
return 0;
}
That's your original code with the various syntax errors fixed. Assuming you're using a compiler that uses ASCII (which is pretty much every one these days), it works. Why do you think it's wrong?

Remove leading % from integer

Just a simple problem here: I have a char** argv[] that holds all of my arguments...in one of these arguments, I get an integer proceeded by a %
For example:
bg %2
I really just want the integer....is there an easy way to get this?
This is for homework, so I am willing to do some more digging if anyone can prod me in the right direction.
Thanks
Here is a way to do it using c++ methods:
lets assume you have one of the char* in the list char** argv[]
std::string tempString(argv[the one with the %]);
int position = tempString.find_first_of('%');
int = atoi(tempString.substr(position, tempString.size()-position).c_str());
A quick explination, the first line converst the char* into a std::string, the second line gets the position of the %, the third line gets the sub-string of the number (assuming it ends at the end of the char*), converts it back to a char* and passes it through atoi to get the int.
Hope this helps.
Here is one way to do it using atoi:
for (int i = 0 ; i != argc ; i++) {
if (argv[i][0] == '%') {
int num = atoi(&argv[i][1]);
printf("Got a number: %d\n", num);
}
}