Putting a constant char in a char matrix - c++

I have a char matrix (relation[][]) and I want to put some character in several items of that. look:
char relation[num_obj][num_obj];
for(k1=0; k1<num_obj; ++k1)
for(k2=0; k2<num_obj; ++k2)
if(k1 != k2)
if(Top[i][j]==1)
{
strstr((const char *)relation[i][j], "T");
strstr((const char *)relation[i][j], "B");
}
k1,k2,num_obj are some defined variable.
As you see I am trying to put some constant char (like " T, B) to some elements of matrix, but I receive this warning:
warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
Can any one help me in removing this warning.
Thanks in advance and all the best :)

If you're just trying to write a 'T' into the array, that's just assignment:
relation[i][j] = 'T';
strstr is a method to find a substring in a string. It's only useful for its return-value, so even if you got your code to compile, it just wouldn't do anything.

Related

why it cannot convert char* to char

In c++ we can write
1 char *s="hello"
but the below lines of program produces an error ( cannot convert char* to char)
2 char *s;
*s="hello";
I am confused here, what is difference between 1 and 2
why this error is coming?
In C++, a string literal is a constant array of characters, not just an array of characters like in C. Anyways, to assign to such a variable (Which is best avoided), you do not have to dereference the pointer. Dereferencing it accesses the first element, which is just a char. A char cannot hold an array of characters inside it, causing an error. This is more the reason why you should be using std::string.
Some compilers such as GCC provide extensions to make such code possible since it is not standards compliant code, and it would look like:
char* s = "hello";
s = "new string";
This generates the following warning in GCC (But still gets the expected result):
warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
Clang also has the same behavior with the same output (Also generating a warning)
A string is an array of characters. The start of a string therefore is const char *.
Therefore to reference a string, you can use const char * s = "hello";
However if you dereference a const char*, you get a const char. This isn't a string i.e. *s gives you 'h'.
In your code *s="hello";, you are saying "assign at the dereferened s the value "hello"". Dereferencing s is a character only, to which you are trying to assign a string.
The problem is the second asterisk in your second example.
The first code is this
char *s="hello";
The equivalent code is this
char *s;
s="hello";
No * before s in the second line.
Now as everyone is pointing out neither of these are legal C++. The correct code is
const char *s="hello";
or
const char *s;
s="hello";
Because string literals are constant, and so you need a pointer to const char.
I am confused here, what is difference between 1 and 2 why this error is coming?
As many others * in C++ means different things in different context:
char *s; // * here means that s type is a pointer to char, not just char
*s; // in this context * means dereference s, result of exression is char
int a = 5 * 2; // in this context * means multiply
so case 1 and 2 may look similar to you but they mean very different things hence the error.

My append function does not work as expected. C++

I am writing my own append function to append a dynamic character array of string array2 at the end of another dynamic character array of string array1, using a static char buffer[50]. But the compiler generates the following errors: [Error] incompatible types in assignment of 'char' to 'char[50]'. I have tried to figure out the problem, but I don't seem to find the solution. Your help will be very appreciated. I am using Dev-C++. The code is bellow.
#include <iostream>
using namespace std;
char *Appendstring(char *a, char *b) // will append b to the end of a
{
static char buffer[50];
char *p=buffer=*a++; //[Error] incompatible types in assignment of 'char' to 'char[50]'
//[Error] invalid conversion from 'char*' to 'char'[-fpermissive]
p--;
while(*p++=b++);
p--; //append
while(*p++=*c++);
return buffer;
}
int main ()
{
string str="Displaying: ";
string add=" Summer is coming";
Appendstring(str, add);
return 0;
}
There are multiple errors in your append function, the biggest ones are using an array as a pointer and using a static buffer to merge strings. With a static buffer in place, all your merged strings will be in the same space, so merging two strings and then merging the other two would overwrite the results of the first merge!
You can change your function as follows:
char *Appendstring(const char *a, const char *b) // will append b to the end of a
{
char *buffer = new char[strlen(a)+strlen(b)+1];
char *p=buffer;
while(*p++=*a++); // Copy a into buffer
while(*p++=*b++); // Copy b into buffer right after a
*p=0; // Null-terminate the string
return buffer;
}
Of course the caller is responsible for freeing the results of Appendstring now.
You cannot assign into an array, which is what you do in buffer=*a++. what you meant is probably
static char buffer[50];
char *p=buffer;
*p=*a++;
In addition, here
p--;
while(*p++=*b++);
you are trying to derefence a pointer one element before the beginning of an array - which leads to undefined behaviour.
Moreover, nowhere do you check for the strings' length, so it can easily be more the 49 together and your code will be both incorrect and insecure (easy victim for buffer overflow attacks).
One last problem is that your code is non reentrant in any way, due to the use of static array. you can simply use simple array, if you don't want to adjust it to the strings' length, or allocate it dynamically, as was suggested here.
The best solution of course is to use std::string and forget all these problems.

Operand types are incompatible ("char" and "const char*")

I'm receiving the following error...
Operand types are incompatible ("char" and "const char*")
... when trying to perform an if statement. I'm assuming I'm not understanding how the input value is stored although I'm unsure if I can just cast it into the matching type?
Example code to reproduce is:
char userInput_Text[3];
if (userInput_Text[1] == "y") {
// Do stuff.
}
I'm not sure what's causing this. It would appear that one type is a char and the other is a const char pointer although I'm unsure of what, for reference this error also occurs when I'm not using an array).
And tips / feedback would be much appreciated.
Double quotes are the shortcut syntax for a c-string in C++. If you want to compare a single character, you must use single quotes instead. You can simply change your code to this:
char userInput_Text[3];
if (userInput_Text[1] == 'y') { // <-- Single quotes here.
// Do stuff.
}
For reference:
"x" = const char *
'x' = char

comparing a char to a const char * [duplicate]

This question already has answers here:
c++ compile error: ISO C++ forbids comparison between pointer and integer
(5 answers)
Closed 5 years ago.
string line = "blerdy blah";
for (int i = 0; i < string.size(); i++)
{
line[i] != "n";
}
With this I get the error "cannot convert from char to const char *"
If I replace the last line with
line[i] != *"n";
It works. I get why in one sense, I'm dereferencing a pointer. What I don't get is why it's a pointer in the first place. Is any char written like this actually a pointer to one char somewhere? Like the program has one set of every symbol somewhere and this is what I'm pointing to?
If this is the case, can I do silly things like make the 'n' pointer point to something else?
You have to compare char with char in this case:
line[i] != 'n';
When you say *"n" you actually dereference the first element of the char array with n and \0 elements inside it, which gives you n, that's why it works, but you don't want to write it like that.
"n" is not a character literal, it is a string literal. You want 'n'.
"n" is a char array (string). While 'n' is a char.
"n" is a so called string literal, which has the type const char[2]. string::operator[] (actually basic_string<char>::operator[] returns a const char& or char& depending on the picked overload (the second one in this case). You cannot compare those types. What you want want to compare the result of operator[] to is a character literal, which is written as 'n'.
For your second question
"n" has type const char[2], dereferencing it gives you a char (the first character in the array pointed to). This is equivalent to "n"[0].
Change "n" to 'n'. The difference is that the former is a const char* whereas the latter is char. Since you want to compare one char to another, the latter is the correct form to use.
Why and how this works
Start with "n": lexically it is a null-terminated string literal, which means that the compiler will end up treating it as a char* pointing to a section of memory that holds the string "n".
So when you write *"n", what happens is that you are dereferencing a char* that points to "n", which means that the result of the expression will be 'n' (of type char). That's why the comparison to line[i] (which is also a char) works.
This pointer to "n" is a compile-time constant (so you can't change it) and in all likelihood will point to a read-only memory page (so you won't be able to change what it points to at runtime either).
What you should do instead
line[i] != 'n'; // compare char to char

Beginner C++ Question

I have followed the code example here
toupper c++ example
And implemented it in my own code as follows
void CharString::MakeUpper()
{
char* str[strlen(m_pString)];
int i=0;
str[strlen(m_pString)]=m_pString;
char* c;
while (str[i])
{
c=str[i];
putchar (toupper(c));
i++;
}
}
But this gives me the following compiler error
CharString.cpp: In member function 'void CharString::MakeUpper()':
CharString.cpp:276: error: invalid conversion from 'char*' to 'int'
CharString.cpp:276: error: initializing argument 1of 'int toupper(int)'
CharString.cpp: In member function 'void CharString::MakeLower()':
This is line 276
putchar (toupper(c));
I understand that toupper is looking for int as a parameter and returns an int also, is that the problem? If so how does the example work?
Also,
char* str[strlen(m_pString)];
int i=0;
str[strlen(m_pString)]=m_pString;
is not valid C++ - arrays must be dimensioned using compile time constants - this is a C99 feature. And I really don't think the code would do what you want it to, even if it were legal, as you seem to be accessing one past the end of the array. It would be handy if you posted the complete class definition.
I don't think your code does what you want it to do and in fact if it compiled it would explode.
char* str[strlen(m_pString)]; // you've made an array of X C strings where
// X is the length of your original string.
int i=0;
str[strlen(m_pString)]=m_pString; // You've attempted to assign the C string in your array
// at location X to point at you m_pString. X is the
// same X as before and so is 1 past the end of the array
// This is a buffer overrun.
I think what you actually wanted to do was to copy the content of m_pString into str. You'd do that like so:
char * str = new char[strlen(m_pString)];
memcpy(str, m_pString); // I may have the operands reversed, see the docs.
The easier way to do this though is to stop using C strings and to use C++ strings:
std::string str = m_pString;
There are more issues, but this should get you steer you more toward the right direction.
You need to feed toupper() an int (or a char) instead of a char *, which is how you've declared c.
try:
char c;
Also,
char* str[strlen(m_pString)];
is an an array of pointers to characters, not just a single string.
This line:
str[strlen(m_pString)]=m_pString;
is an assignment to a bad pointer then, since there was no allocation.
I'm going to go with the assumption that m_pString is a C style string (char *). You're doing way more fiddling than you need to be doing.
void CharString::MakeUpper()
{
char* str = m_pString; // Since you're not modifying the string, there's no need to make a local copy, just get a pointer to the existing string.
while (*str) // You can use the string pointer as an iterator over the individual chars
{
putchar (toupper(*str)); // Dereference the pointer to get each char.
str++; // Move to the next char (you can merge this into the previous line if so desired, but there's no need.
}
}
In the example you cite, the reason it works is because of how the variables are declared.
int main ()
{
int i=0;
char str[]="Test String.\n"; // This is a compile time string literal, so it's ok to initialize the array with it. Also, it's an array of `char`s not `char*`s.
char c; // Note that this is also a `char`, not a `char *`
while (str[i])
{
c=str[i];
putchar (toupper(c));
i++;
}
return 0;
}
Because of the error-prone ways of using C strings, your best bet is std::string:
void CharString::MakeUpper()
{
string str(m_pString);
transform(str.begin(), str.end(), ostream_iterator<char>(cout), &toupper);
}
There is not a built-in conversion from char * to int, which is why the error occurs. Since you're trying to capitalize a character, you need to dereference the pointer.
putchar(toupper(*c));