So I have a function that takes in a file input character by character and forms the characters into sentences to be modified. One of the modifications to be done is to make a run on sentence in this instance. It will take two sentences and form a run-on sentences by removing the punctuation between them and concatenating them.
Here is my code:
void runOn(char sentence, ifstream & fin, int counter)
{
char ch;
int sentCounter = 0;
bool sentenceEnd = false;
while(sentCounter<=2)
{
char tempSent[SENT_LENGTH];;
do
{
fin.get(ch);
for(int i = 0; i<SENT_LENGTH;i++)
{
tempSent[i] = ch;
}
if(ch == '.' || ch == '?' || ch == '!')
{
sentCounter++;
sentenceEnd = true;
}
}while(sentenceEnd == false);
strcat(sentence,tempSent);
}
}
The counter passed is only used because the function should only run for the first two sentences.
When I attempt to compile, I get this error:
function.cpp:36:29: error: invalid conversion from 'char' to 'char*' [-fpermissive]
strcat(sentence,tempSent);
Edit: I should add, I'm only allowed to use C style null terminated character arrays
The error is very clear, strcat is declared as char * strcat ( char * destination, const char * source );, however, sentence is not char*, you must convert sentence from char to char*.
Since I don't know where sentence comes from, I can't give further advice, may be you should post the function which called the runOn.
Maybe you can simply change void runOn(char sentence, ifstream & fin, int counter) to void runOn(char* sentence, ifstream & fin, int counter)
See declaration of strcat here
http://www.cplusplus.com/reference/cstring/strcat/ as you can see strcat accepts char * not char in your function you need to take sentence as char* then your function will work.
Related
So I have this issue
//This holds 5 messages submitted prev by the user, temporarily stored
string arrayOfMessages[5];
lets say
arrayOfMessages[0]="This is my message"//The message in the first position.
I need to copy arrayOfMessages[0] to an array of char like this one;
char message [20];
I tried using strcpy(message,arrayOfMessages[0]) but I get this error :
error: cannot convert 'std::__cxx11::string' {aka 'std::__cxx11::basic_string<char>'} to 'const char*'|
Anyone know how I can accomplish this or if I'm doing something wrong, I cant set the string to be a const char bc the message was imputed prev by the user so it changes every time you run the program thus cannot be a constant variable.
There are many ways of doing it
By using the c_str() function of the string class
string message = "This is my message";
const char *arr;
arr = message.c_str();
By copying all the characters from the string to the char array
string message = "This is my message";
char arr[200];
for(int i = 0; i < 200 && message[i] != '\0'; i++){
arr[i] = message[i];
}
Be careful with the array sizes if you use the second approach.
You can also make it a function in order to make it easier to use
void copyFromStringToArr(char* arr, string str, int arrSize){
for(int i = 0; i<arrSize && str[i] != '\0'; i++){
arr[i] = str[i];
}
}
So in your case you can just call the function like this:
copyFromStringToArr(message,arrayOfMessages[0],20);
Also I am sure there are many more ways to do it but these are the ones I would use.
To copy the contents of std::string into a char[], use c_str():
std::string str = "hello";
char copy[20];
strcpy(copy, str.c_str());
But the datatype of copy must be only char* and not const char*. If you want to assign it to a const char*, then you can use direct assignment:
std::string str = "hello";
const char *copy = str.c_str();
The problem enlies with printf(stringOut). It prints an empty array. The function halfstring appears to work correctly but the string it builds never makes it to main.
int main(int argc, char *argv[])
{
char stringIn[30] = "There is no cow level.\0";
char stringOut[sizeof(stringIn)];
halfstring(stringIn, stringOut);
printf(stringOut);
return 0;
}
halfstring is supposed to take every odd character in a char array and put it into a new char array without using ANY system-defined string functions (i.e. those found in the string.h library including strlen, strcat, strcpy, etc).
void halfstring(char stringIn [], char stringOut [])
{
int i = 0;
int modi;
while(stringIn[i] != '\0')
{
if(i % 2 != 0)
{
stringOut[i] = stringIn[i];
}
i++;
}
}
Inside the function halfstring you skipped the first and second characters of stringOut which probably are containing null characters when being declared this is the reason why you got nothing.
You can solve that by adding a new separate indice k for stringOut:
void halfstring(char stringIn [], char stringOut [])
{
int i = 0,k=0; // create a separate indice for stringOut
int modi;
while(stringIn[i] != '\0')
{
if(i % 2 != 0)
{
stringOut[k] = stringIn[i];
k++; // increment the indice
}
i++;
}
stringOut[k]='\0';
}
1) You don't need to NUL terminate a string literal:
char stringIn[30] = "There is no cow level.\0";
^^
2) Your second array (stringOut) results in something like:
{'T', garbage, 'e', garbage, 'e', garbage, 'a', garbage, 'e' ... };
You need to count the number of chars stored in the 2nd array:
void halfstring(char stringIn [], char stringOut [])
{
int i = 0;
int n = 0;
while(stringIn[i] != '\0')
{
if(i % 2 != 0)
{
stringOut[n++] = stringIn[i];
}
i++;
}
stringOut[n] = '\0';
}
There are several drawbacks in the program.
For starters there is no need to include the terminating zero in the string literal
char stringIn[30] = "There is no cow level.\0";
^^^^
because string literals already have the terminating zero.
Secondly usually standard string functions return pointer to the first character of the target string. This allows to chain at least two functions in one statement.
The first parameter is usually declares the target string while the second parameter declares the source string.
As the source string is not changed in the function it should be declared with the qualifier const.
And at last within the function there is used incorrect index for the target string and the string is not appended with the terminating zero.
Taking this into account the function can be written as it is shown in the demonstrative program below
#include <stdio.h>
char * halfstring( char s1[], const char s2[] )
{
char *p = s1;
while ( *s2 && *++s2 ) *p++ = *s2++;
*p = *s2;
return s1;
}
int main(void)
{
char s1[30] = "There is no cow level.";
char s2[sizeof( s1 )];
puts( halfstring( s2, s1 ) );
return 0;
}
Its output is
hr sn o ee.
My function must process strings that look like say hello y(5) or data |x(3)|, and I need to be able to extract the integer shown and store it into a separate int variable called address. However, some strings passing through will not have any integers, and for these the address must default to 0. When a string contains an integer, it will always be in between parentheses. I've attempted to use sscanf, but, being very new to sscanf, I'm encountering problems.. For some reason, the address always reads as 0. Here's my code:
void process(string info)
{
int address = 0; // set to 0 in case info contains no digits
sscanf(info.c_str(), "%d", address);
.
.
.
// remainder of code makes other function calls using the address, etc
}
Any ideas as to why the sscanf fails to find the integer in between parentheses? Thanks!
why the sscanf fails to find the integer in between parentheses
The "%d" in sscanf(info.c_str(), "%d", address) will cause sscanf() to stop scanning once a non-numeric sequence detected. Text like "(5)" will simply stop scanning at the "(".
Instead code need to to skip over non-numeric text.
Pseudo-code
in a loop
search for any of "-+0123456789"
if not found return 0
convert from that point using sscanf() or strtol()
if that succeeds, return number
else advance to next character
Sample code
int address;
const char *p = info.c_str();
for (;;) {
p += strcspn(p, "0123456789+-");
if (*p == 0) return 0;
if (sscanf(p, "%d", &address) == 1) {
return address;
}
p++;
}
Notes:
The strcspn function computes the length of the maximum initial segment of the string pointed to by s1 which consists entirely of characters not from the string pointed to by s2. C11 7.24.5.3 2
If code wants to rely on " it will always be in between parentheses." and input like "abc()def(123)" does not occur which has preceding non-numeric data between ().:
const char *p = info.c_str();
int address;
if (sscanf(p, "%*[^(](%d", &address)==1) {
return address;
}
return 0;
or simply
int address = 0;
sscanf(info.c_str(), "%*[^(](%d", &address);
return address;
You could use something as simple as this where strchr finds the first occurrence of "(" then use atoi to return the integer which will stop at the first non-digit.
char s1[] = "hello y(5)";
char s2[] = "data [x(3)]";
char s3[] = "hello";
int a1 = 0;
int a2 = 0;
int a3 = 0;
char* tok = strchr( s1, '(');
if (tok != NULL)
a1 = atoi(tok+1);
tok = strchr( s2, '(');
if (tok != NULL)
a2 = atoi(tok+1);
tok = strchr(s3,'(');
if (tok != NULL)
a3 = atoi(tok+1);
printf( "a1=%d, a2=%d, a3=%d", a1,a2,a3);
return 0;
When a string contains an integer, it will always be in between
parentheses
To strictly conform with this requirement you can try:
void process(string info)
{
int address;
char c = '5'; //any value other than ) should work
sscanf(info.c_str(), "%*[^(](%d%c", &address, &c);
if(c != ')') address = 0;
.
.
.
}
link to a solution
int address;
sscanf(info.c_str(), "%*[^0-9]%d", &address);
printf("%d", address);
this should extract the integer between the parenthesis
I am getting abpve error at line str.append(ch); in below code.
I basically want to append str with each char 'ch'.
If someone know the issue please correct my error.
int extract(unsigned char data, char i); // Signature of extract function
void decoded(istream& input,ostream& output)
{
int cnt;
int x;
input.read((char*)&x,sizeof(x));
cout<<x;
cnt=x;
string str;
char ch;
for ( ; ; )
{
char c;
input.read((char*)&c,sizeof(char));
if ( input )
{
//read_bit(c,output);
for (int i=7; i>=0; i--)
{
if(cnt)
{
cnt--;
ch=(char)(((int)'0')+extract(c, i));
str.append(ch);// I am getting error at this line.
if(huffmanFindTable[str])
{
output.write((char*)&(huffmanFindTable[str]),sizeof(char));
str.clear();
}
else
{
}
}
}
}
else
break;
}
}
Like the compiler says, there is no member function with the signature
str.append(ch);
You can use either
str.append(1, ch);
or the simpler
str.push_back(ch);
string::append has no member function taking a char as argument. You can append null-terminated char arrays or other stringS.
You can only append a "sequence" of character to a string. "append" is an operation on two (sequence) vector (take the word vector in a more generic sense) like objects.
You can do the following:
str.append(1, ch);
str+=ch;
I want to add a new (fstream) function in a program that already uses char arrays to process strings.
The problem is that the below code yields strings, and the only way i can think of getting this to work would be to have an intermediary function that would copy the strings, char by char, into a new char array, pass these on to the functions in the program, get back the results and then copy the results char by char back into the string.
Surely (hopefully) there must be a better way?
Thanks!
void translateStream(ifstream &input, ostream& cout) {
string inputStr;
string translated;
getline(input, inputStr, ' ');
while (!input.eof()) {
translateWord(inputStr, translated);
cout << translated;
getline(input, inputStr, ' ');
}
cout << inputStr;
the translateWord func:
void translateWord(char orig[], char pig[]) {
bool dropCap = false;
int len = strlen(orig)-1;
int firstVowel = findFirstVowel(orig);
char tempStr[len];
strcpy(pig, orig);
if (isdigit(orig[0])) return;
//remember if dropped cap
if (isupper(orig[0])) dropCap = true;
if (firstVowel == -1) {
strcat(pig, "ay");
// return;
}
if (isVowel(orig[0], 0, len)) {
strcat(pig, "way");
// return;
} else {
splitString(pig,tempStr,firstVowel);
strcat(tempStr, pig);
strcat(tempStr, "ay");
strcpy(pig,tempStr);
}
if (dropCap) {
pig[0] = toupper(pig[0]);
}
}
You can pass a string as the first parameter to translateWord by making the first parameter a const char *. Then you call the function with inputStr.c_str() as the first parameter. Do deal with the second (output) parameter though, you need to either completely re-write translateWord to use std::string (the best solution, IMHO), or pass a suitably sized array of char as the second parameter.
Also, what you have posted is not actually C++ - for example:
char tempStr[len];
is not supported by C++ - it is an extension of g++, taken from C99.
You can use the member function ifstream::getline. It takes a char* buffer as the first parameter, and a size argument as the second.