I have code for using an array to create an ASCII table. I am having trouble compiling the code due to errors:
cannot convert 'char*' to char(*)[95] for argument '1' to void buildTable(char (8)[95], int)
and
cannot convert std::ofstream to char(*)[95] for argument '1' to 'void printTable(char(8)[95], int)
#include <iomanip>
#include <iostream>
#include <fstream>
int main () {
const int MAX_SIZE = 95;
char symbols[MAX_SIZE];
int values[MAX_SiZE], int values);
void buildTable (char [][MAX_SIZE], int values);
void printTable (char [][MAX_SIZE], int values);
void output(std::fstream, std::string, double);
std::string line;
std::ofstream outputFile;
outputFile.open("ascii.log");
if(outputFile.fail()) {
std::cout << "Error opening file. \n";
return 1;
}
else {
buildTable (symbols, values, MAX_SIZE);
printTable (outputFile, symbols, values, MAX_SIZE);
}
outputFile.close();
return 0;
}
The variable symbols is an array of char. It will decay to a pointer to its first element, &symbols[0], which will be of type char*.
The functions you declare takes its first parameter as a pointer to an array of char. A pointer to an array of char is very different from a pointer to char.
The solution is to make the function take the same data-type as you pass, i.e. a pointer to char, char*.
You also have multiple other problems. For example the functions you declare (buildTable and printTable) are currently declared to that this wrong argument as the first argument, and then int value as second argument. But that's not how you call those functions. You need to declare the functions with their actual arguments, and call them as declared.
On a related note: Since you program in C++ please don't use character arrays for strings, use std::string instead. It will save you a lot in the long run.
Related
in the snippet code bellow when I pass a literal string to the function it gives me a warning ISO C++ forbids converting a string constant to 'char*but when I assign a character array to this literal the warning will be gone. I know that the type of string literals in C++ is constant character array but the type of ch variable is just char.(not constant char)
#include <iostream>
using namespace std;
void func(char s[])
{
cout << s;
}
int main() {
char ch[] = "what";
func(ch);
func("what"); //gives warning
return 0;
}
and I have one question more. when I add const to input parameter type of func function there is no warning in this situation too even though I pass a character array to the function not const character array.I thought it should cause a warning for fucn(ch) call because ch is a character array not constant character array.
#include <iostream>
using namespace std;
void func(const char s[])
{
cout << s;
}
int main() {
char ch[] = "what";
func(ch);
func("what");
return 0;
}
const is not about matching exactly, but about what the function is doing to the parameter.
If you define a function with a const parameter, the function promises to not change the passed variable. Therefore, you can call it with constant strings as well as (changable) non-constant variables. The compiler will warn you if you try to modify the value inside the function (because you promised you wouldn't).
If you define a function with a non-constant parameter, it can change the parameter. Therefore, the compiler warns you if you pass a constant string, as that would lead to undefined behavior / crashes.
I am returning the *res (which is value resultant string after concatenating strings) in the function. When I call this function and store the result in the char array then it gives me error [Error] incompatible types in assignment of 'char' to 'char [40]'
.I want to concatenate two strings in the function and return the concatenating string from function.Kindly help to solve to this problem
#include<iostream>
#include<stdio.h>
using namespace std;
int main(){
char strConcat(char *,char *);
char input1[10],input2[12],resultantString[40];
cout<<"Enter the 1st String=";
cin.getline(input1,10);
cout<<"Enter the 2nd String=";
cin.getline(input2,10);
//faulty code
resultantString=strConcat(input1,input2);
cout<<resultantString;
}
// st1 means String1 and St2 means string2 which we want to concat.
char strConcat(char *st1,char *st2)
{
char *res;
while(*st1!='\0')
{
*res=*st1;
*st1++;
*res++;
}
while(*st2!='\0')
{
*res=*st2;
*st2++;
*res++;
}
*res='\0';
return *res;
}
First off, remove using namespace std;, it's a bad habit.
Next up, move the function declaration void strConcat(char *,char *); out of main and make it the same type as the definition, this is your error, you declare strConcat to return void first but then you define it to return char, the compiler still thinks it returns void and thus when you're trying to assign something to it the compiler complains.
Next up, make main return int, your current definition isn't valid.
Next, indent your code so not only the compiler can read it but other humans too.
And the most important tip here, remove all of those static-sized arrays and that homebrewed strCat function and use std::string and it's operator+ for concatenation.
I'm working with a piece of C++ code that reads lines from a txt file and then assign each line to to an array called lines. Then it calls a function that converts each element in the lines array to a char array and then return the resulted char array. This step is where I stuck. How could I return a char array from the function toChar and assign the returned array to another array so I can use it as I need? (the rest of the code should use each returned char array to write it in a pipe, this not important right now but just to clarify why I need to learn to return an array from a function)
Here is the code I'm using:
#include <fstream>
#include <iostream>
#include <string.h>
#include <unistd.h>
#include <cstdlib>
using namespace std;
char * toChar(string line);
int main()
{
string lines[0] = "line1";
char* a = toChar(lines[0]);
return 0;
}
char * toChar(string line)
{
char a[1024];
strcpy(a, line.c_str());
return a;
}
Please note that in this code I'm trying to shrink the code so I'm assigning a simple string value to the array
when I try to compile this code, the error below appears:
warning: address of local variable 'a' returned
any help or suggestion is greatly appreciated..
First use a const & in passing the string to the function to avoid the unnecessary copying, and be able to use temporaries, e.g. toChar("I am temp");
The are the following alternatives:
(1) Return std::string
std::string toChar(std::string const & line)
{
char a[1024];
strcpy(a, line.c_str());
return a;
}
Of course it is assumed that line is smaller than 1024 chars with the null termination symbol
(2) Return an allocated array the
char * toChar(std::string const & line)
{
char * a = new char[1024];
strcpy(a, line.c_str());
return a;
}
but you will have to actually manage it and delete it later.
(3) Allocate the array and pass it to the function
void toChar(string const & line, char a[])
{
strcpy(a, line.c_str());
}
I imagine that you actually want to extract a C-string from an std::string , or some part of it. The proper way to do it is (3).
The warning is correct and practically is an error. You're declaring the char array locally so it will be deleted after going out of scope of that function and its address will be no more valid.
Since you're using c++ avoid char array and use a std::string.
If you want to access to the internal storage of your string you can call line.c_str() which returns a const char *.
Hence you won't need you function toChar that creates a local array that will go out of scope at the end of your function.
You could simply do :
int main()
{
string lines[0] = "line1";
const char* a = lines[0].c_str();
return 0;
}
But I advise you to keep manipulating std::string as they will handle string better than a simple char *.
And if you want a copy, just do it : std::string mycopy = lines[0].
I am new to C++
and I know I shouldn't be using printf in c++ while I have cout but this was for experiment sake.
My Question here is Why we have to convert a string to c_str (c string) while passing to printf in c++ while it works fine without converting in cout.
Below is my code
#include<iostream>
#include<stdio.h>
using namespace std;
class A{
int i;
string str;
public:
A (int value, const string & s) : i(value), str(s){};// constructor
// setters
void setvalue(int value) {i = value;}
void setstr(const string & s) {str = s;}
//geters
int get_value() {return i;}
string get_str() {return str;}
const char *get_str_cstr() {return str.c_str();}// I didn't get why we have to declare constant
};
int main(){
// new code
A obj1 = {11, "Jill"};
cout<<"value is : "<<obj1.get_value()<<" string is "<<obj1.get_str()<<endl;
// Now we wil change the values in A
obj1.setvalue(2);
obj1.setstr("Jack");
cout<<"value after change is : "<<obj1.get_value()<<" string after change is "<<obj1.get_str()<<endl;
// now we will use printf where get_str dosen't not work
//Error: for below commented printf function
/*In function 'int main()':|
error: cannot pass objects of non-trivially-copyable type 'std::string {aka class std::basic_string<char>}' through '...'|
||=== Build finished: 1 errors, 0 warnings (0 minutes, 0 seconds) ===|
*/
//printf("Value is %d and String is %s",obj1.get_value(),obj1.get_str());
// hence we declare a new char * get_str_cstr to make it work in printf;
printf("Value is %d and String is %s",obj1.get_value(),obj1.get_str_cstr());
return 0;}
I have also provided the error in program comments.
Thank you!
printf comes from C library, which predates objects, templates, and function overloading. When you specify %s format, the function takes an address of a null-terminated character sequence, and prints it. printf has no idea where the string comes from. In fact, it has no idea of its parameter types, because it uses variable-length parameter list feature.
std::string is a C++ string. Calling c_str() on it produces a pointer to the beginning of a C string, which is suitable for passing to printf and other functions expecting a C string.
cout, on the other hand, has been built with classes and overloading in mind. There is a special overload for operator << for std::string, which lets cout and other output streams extract characters from a C++ string.
printf is originally from C, which does not have std::string, so the analogous argument type is const char* which is what you get when you call .c_str()
The reason std::cout works with std::string is because operator<< is defined for that class.
Because printf() has no idea what a std::string is. The protypes for printf() are
int printf( const char* format, ... );
int fprintf( std::FILE* stream, const char* format, ... );
int sprintf( char* buffer, const char* format, ... );
int snprintf( char* buffer, std::size_t buf_size, const char* format, ... );
The reason std::string works with cout is that std::string provieds operator << which works with cout
string is a class in c++ stl.
c_str() is a member function of class string .
The signature is:
const _CharT* c_str() const { return _M_start; }
now, coming to printf, its signature is:
int printf ( const char * format, ... );
now, as long as you give it an argument that meets const char * format, it accepts it.
I want to pass an argument to a function, which takes a const char **
#include<iostream>
using namespace std;
void testFunc(const char **test){}
string testString = "This is a test string";
int main()
{
const char *tempC = testString.c_str();
testFunc(&tempC);
return 0;
}
This code works fine, But I dont want to go through the temporary variable tempC. I want to pass testString.c_str() directly. Like the following,
int main()
{
testFunc(&testString.c_str());
return 0;
}
But, it shows error,
error C2102: '&' requires l-value
Is it possible to do it without using the temp variable.
I want to pass testString.c_str() directly.
You can't. std::string::c_str() returns a const char *. In order to make a pointer to a string, you have to put it in a variable and take its address.
That being said, I'm far more concerned about what function you're trying to pass this to. In general, a function that takes a const char ** does so for two reasons:
1: It takes an array of strings. You are passing a single string. Usually, C-style functions that take an array need a second parameter that says how many elements are in the array. I hope you're putting a 1 in there.
2: It is returning a string. In which case what you're doing is not helpful at all. You should create a const char * as a variable, initialize it to NULL, and then pass a pointer to it as the parameter. It's value will be filled in by the function.
You're going to need two temp variables to call glShaderSource, so you might as well wrap them up in one function that takes the string directly.
#include <gl.h>
#include <string>
void setShaderFromString(std::string &instr, GLuint shader)
{
const GLchar *str[1]; // room for one const GLchar *
GLint len[1]; // make this an array, for symmetry
str[0] = instr.c_str();
len[0] = instr.length();
glShaderSource(shader, 1, str, len);
}
Simply - no.
(filling up some space)
You can also do type-casting:
int main()
{
testFunc((const char **)&testString);
return 0;
}