I need help fixing a C++ white space detector - c++

I need help fixing the following code, it is a c++ whitespace detector that uses different words to produce different outputs:
#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>
using namespace std;
string Line;
string firstWord[99];
string secondWord[99];
int lineFunction(string line) {
string line[199];
for (int i = 0; i < line.length(); i++) {
while (isspace(line[i]) == false) {
firstWord += line[i];
}
secondWord += line[i];
}
}
int main() {
cin >> Line;
lineFunction(Line);
if (firstWord == "A") {
if (secondWord == "B") {
cout << "AB";
}
}
}
The expected result when I input A B (with a space) should be the letters AB (without a space, to test how it works) printed onto the screen, as a result of the if statements, but I am trying to make the output configurable. The errors that I receive when I try to run this are:
main.cpp: In function ‘int lineFunction(std::string)’:
main.cpp:12:20: error: declaration of ‘std::string line [199]’ shadows a parameter
string line[199];
^
main.cpp:13:30: error: request for member ‘length’ in ‘line’, which is of non-class type ‘std::string [199] {aka std::basic_string [199]}’
for (int i = 0; i < line.length(); i++) {
^~~~~~
main.cpp:14:31: error: no matching function for call to ‘isspace(std::string&)’
while (isspace(line[i]) == false) {
^
In file included from /usr/include/c++/6/cctype:42:0,
from main.cpp:2:
/usr/include/ctype.h:118:1: note: candidate: int isspace(int)
__exctype (isspace);
^
/usr/include/ctype.h:118:1: note: no known conversion for argument 1 from ‘std::string {aka std::basic_string}’ to ‘int’
In file included from /usr/include/c++/6/bits/basic_ios.h:37:0,
from /usr/include/c++/6/ios:44,
from /usr/include/c++/6/ostream:38,
from /usr/include/c++/6/iostream:39,
from main.cpp:3:
/usr/include/c++/6/bits/locale_facets.h:2565:5: note: candidate: template bool std::isspace(_CharT, const std::locale&)
isspace(_CharT __c, const locale& __loc)
^~~~~~~
/usr/include/c++/6/bits/locale_facets.h:2565:5: note: template argument deduction/substitution failed:
main.cpp:14:31: note: candidate expects 2 arguments, 1 provided
while (isspace(line[i]) == false) {
^
main.cpp:15:23: error: no match for ‘operator+=’ (operand types are ‘std::string [99] {aka std::basic_string [99]}’ and ‘std::string {aka std::basic_string}’)
firstWord += line[i];
~~~~~~~~~~^~~~~~~~~~
main.cpp:17:20: error: no match for ‘operator+=’ (operand types are ‘std::string [99] {aka std::basic_string [99]}’ and ‘std::string {aka std::basic_string}’)
secondWord += line[i];
~~~~~~~~~~~^~~~~~~~~~
main.cpp: In function ‘int main()’:
main.cpp:24:22: error: comparison between distinct pointer types ‘std::string* {aka std::basic_string*}’ and ‘const char*’ lacks a cast [-fpermissive]
if (firstWord == "A") {
^~~
main.cpp:25:27: error: comparison between distinct pointer types ‘std::string* {aka std::basic_string*}’ and ‘const char*’ lacks a cast [-fpermissive]
if (secondWord == "B") {

Here are some possible solutions to fix the errors.
#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>
// don't use
// using namespace std;
// don't use global variables
// string Line;
// string firstWord[99]; you need strings, not arrays
// string secondWord[99];
// use references to return multiple values and no return value
// alternatively you could return a std::pair
void lineFunction(std::string line, std::string &firstWord, std::string &secondWord) {
// string line[199]; you don't need this variable
// line.length() return unsigned int so you should compare with unsigned int
// this whole loop makes no sense
// for (unsigned int i = 0; i < line.length(); i++) {
// this would result in a infinite loop
// while (isspace(line[i]) == false) {
// if (!std::isspace(line[i])) {
// firstWord += line[i];
// }
// secondWord += line[i];
// }
unsigned int i;
for (i = 0; i < line.length() && !std::isspace(line[i]); ++i) {
firstWord += line[i];
}
for (++i; i < line.length(); ++i) {
secondWord += line[i];
}
}
int main() {
std::string line;
// std::cin only reads until first whitespace
// std::cin >> line;
std::getline(std::cin, line);
std::string firstWord;
std::string secondWord;
lineFunction(line, firstWord, secondWord);
if (firstWord == "A" && secondWord == "B") {
std::cout << "AB";
}
}

Related

Codewars: Solving Kata - Highest and Lowest C++

I was solving kata "Highest and Lowest" in codewars.com and got some issues while testing.
Here is my code:
#include <iostream>
#include <list>
#include <sstream>
#include <vector>
using namespace std;
vector<string> splitString(string str) {
stringstream ssin(str);
long countSpaces = count(str.begin(), str.end(), " ") + 1;
vector<string> numbers(countSpaces);
int i = 0;
while (ssin.good() && i < countSpaces + 1) {
ssin >> numbers[i];
++i;
}
return numbers;
}
string highAndLow(const string& numbers) {
int maxAndMin[] = { 0, 0 };
vector<string> stringNums = splitString(numbers);
int length = static_cast<int>(stringNums.size());
for (int i = 0; i < length; i++) {
int number = stoi(stringNums[i]);
if (number > maxAndMin[0]) maxAndMin[0] = number;
if (number < maxAndMin[1]) maxAndMin[1] = number;
}
string result;
stringstream ss;
ss << maxAndMin[0] << " " << maxAndMin[1];
result = ss.str();
return result;
}
And issues:
In file included from main.cpp:1:
In file included from /usr/local/include/igloo/igloo_alt.h:10:
In file included from /usr/local/include/igloo/igloo_framework.h:12:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/iostream:39:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/ostream:38:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/ios:40:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/char_traits.h:39:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_algobase.h:71:
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/predefined_ops.h:241:17: error: comparison between pointer and integer ('char' and 'const char *')
{ return *__it == _M_value; }
~~~~~ ^ ~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_algo.h:3188:6: note: in instantiation of function template specialization '__gnu_cxx::__ops::_Iter_equals_val<char const[2]>::operator()<__gnu_cxx::__normal_iterator<char *, std::__cxx11::basic_string<char> > >' requested here
if (__pred(__first))
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_algo.h:4115:19: note: in instantiation of function template specialization 'std::__count_if<__gnu_cxx::__normal_iterator<char *, std::__cxx11::basic_string<char> >, __gnu_cxx::__ops::_Iter_equals_val<char const[2]> >' requested here
return std::__count_if(__first, __last,
^
./solution.cpp:10:24: note: in instantiation of function template specialization 'std::count<__gnu_cxx::__normal_iterator<char *, std::__cxx11::basic_string<char> >, char [2]>' requested here
long countSpaces = count(str.begin(), str.end(), " ") + 1;
^
1 error generated.
Could you explain me please, what's wrong here?
Try to understand the error message, it contains all relevant information:
First, what the compiler does not like:
error: comparison between pointer and integer ('char' and 'const char *')
And then, which part of your code causes the issue:
long countSpaces = count(str.begin(), str.end(), " ") + 1;
Deep inside that count function, there is a loop comparing every element of str to the " ", you figure out the rest.

C++ I need to understand where to use pointers and double pointers

I have this basic multi tool program which goal is to complete four functions on a file that contains some strings.. take a string, for example, take a line and put it in uppercase.
I get that it's not perfect yet, but i need to understand why my char* and char** are doing some mess.
thanks a lot for your time
#include <iostream> //to use enter and exit
#include <cstring>
#include <string>
#include <fstream> //to use files
using namespace std;
/*--------------------------FONCTION PART-----------------------------------*/
//define one fonction for each transformation
//FONCTION 1
void fonctionu (char* argv){
char pattern = argv[2];
char file = argv[3];
fstream data(file, ios::in);
if (data){
string line;
while (getline (data ,line)){
unsigned found = line.find(pattern);
if (found != string::npos) {
for (int i = 0; line[i]!='\0'; i++) {
if(line[i] >= 'a' && line[i] <= 'z') {
line[i] = line[i] - (32);// (ASCII)
cout<<line[i];
}} }
if (found == string::npos) {
for (int i = 0; line[i]!='\0'; i++) {
cout<<line[i];
}}}}}
//FONCTION 2
void fonctiond( char* argv){ //remove line with xyz
char pattern = argv[2];
char file = argv[3];
fstream data(file, ios::in);
if (data){
string line;
while (getline (data ,line)){
unsigned found = line.find(pattern); //as a reminder argv[2] is the pattern (warning : it need to be an unsigned to compare two unsigned)
if (found != string::npos) {
//delete the line of the file when there is the pattern
cout<<'\0'; }
if (found == string::npos){
for (int i = 0; line[i]!='\0'; i++) {
cout<< line[i];
}}}}}
//FONCTION 3
void fonctionc( char* argv){
char pattern = argv[2];
char file = argv[3];
fstream data(file, ios::in);
if (data ){
string line;
while (getline (data ,line)){
unsigned found = line.find(pattern); //as a reminder argv[2] is the pattern
if (found != string::npos) {
for (int i = 0; line[i]!='\0'; i++) {
cout<< "\033[31m"<< line[i]; //the line will be red
}
}
if (found == string::npos){
for (int i = 0; line[i]!='\0'; i++) {
cout<< line[i];
}}}}}
//FONCTION 4
//replace the pattern xyz by abc
void fonctions ( char* argv){
char pattern = argv[2];
char file = argv[3];
fstream data(file, ios::in);
if (data ){
string line;
while (getline (data ,line)){
unsigned found = line.find(pattern);
if (found != string::npos) {
for (int i = 0; line[i]!='\0'; i++) {
if(line[i] >= 'a' && line[i] <= 'z') {
line[i] = line[i] - (97); // (ASCII) //we creat a shift that allow to make the x became a 'a' and the y a 'b'...etc
cout<<line[i];}}
}
if (found == string::npos) {
for (int i = 0; line[i]!='\0'; i++) {
cout<<line[i];
}}}}}
/*--------------------------MAIN PART---------------------------------------*/
int main(char* argv){
// ipsacs : argv[0]
//option :
string a = argv[1]; //string ! to compare line 103,108 and 112
// pattern : argv[2];
//file : argv[3];
if (argv[1]=='\0' || argv[2]=='\0'){
cout <<"ERROR"<<'\n';}
if (a == "u"){
char fonctionu (argv);}
if (a== "d"){
char fonctiond(argv);}
if (a == "c"){
char fonctionc(argv);}
if (a == "s"){
char fonctions(argv);}
return 0;
}
/*--------------------------TEST PART--------------------------------------*/
/*
pour compiler : g++ -Wall ipsacs.cpp -o ipsacs
./ipsacs u xyz foo //how the program would receive arguments, basically
Le programme ne renvoie rien.
*/
here is the compiling log:
main.cpp:22:30: error: invalid conversion from ‘char’ to ‘const char*’ [-fpermissive]
fstream data(file, ios::in);
^
In file included from main.cpp:8:0:
/usr/include/c++/6/fstream:902:7: note: initializing argument 1 of ‘std::basic_fstream<_CharT, _Traits>::basic_fstream(const char*, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits; std::ios_base::openmode = std::_Ios_Openmode]’
basic_fstream(const char* __s,
^~~~~~~~~~~~~
main.cpp: In function ‘void fonctiond(char*)’:
main.cpp:46:29: error: invalid conversion from ‘char’ to ‘const char*’ [-fpermissive]
fstream data(file, ios::in);
^
In file included from main.cpp:8:0:
/usr/include/c++/6/fstream:902:7: note: initializing argument 1 of ‘std::basic_fstream<_CharT, _Traits>::basic_fstream(const char*, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits; std::ios_base::openmode = std::_Ios_Openmode]’
basic_fstream(const char* __s,
^~~~~~~~~~~~~
main.cpp: In function ‘void fonctionc(char*)’:
main.cpp:66:29: error: invalid conversion from ‘char’ to ‘const char*’ [-fpermissive]
fstream data(file, ios::in);
^
In file included from main.cpp:8:0:
/usr/include/c++/6/fstream:902:7: note: initializing argument 1 of ‘std::basic_fstream<_CharT, _Traits>::basic_fstream(const char*, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits; std::ios_base::openmode = std::_Ios_Openmode]’
basic_fstream(const char* __s,
^~~~~~~~~~~~~
main.cpp: In function ‘void fonctions(char*)’:
main.cpp:88:29: error: invalid conversion from ‘char’ to ‘const char*’ [-fpermissive]
fstream data(file, ios::in);
^
In file included from main.cpp:8:0:
/usr/include/c++/6/fstream:902:7: note: initializing argument 1 of ‘std::basic_fstream<_CharT, _Traits>::basic_fstream(const char*, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits; std::ios_base::openmode = std::_Ios_Openmode]’
basic_fstream(const char* __s,
^~~~~~~~~~~~~
main.cpp: At global scope:
main.cpp:109:5: warning: first argument of ‘int main(char*)’ should be ‘int’ [-Wmain]
int main(char* argv){
^~~~
main.cpp:109:5: warning: ‘int main(char*)’ takes only zero or two arguments [-Wmain]
main.cpp: In function ‘int main(char*)’:
main.cpp:113:20: error: conversion from ‘char’ to non-scalar type ‘std::string {aka std::basic_string}’ requested
string a = argv[1]; //string ! to compare line 103,108 and 112
~~~~~~^
main.cpp:121:26: error: invalid conversion from ‘char*’ to ‘char’ [-fpermissive]
char fonctionu (argv);}
^
main.cpp:123:25: error: invalid conversion from ‘char*’ to ‘char’ [-fpermissive]
char fonctiond(argv);}
^
main.cpp:125:27: error: invalid conversion from ‘char*’ to ‘char’ [-fpermissive]
char fonctionc(argv);}
^
main.cpp:127:27: error: invalid conversion from ‘char*’ to ‘char’ [-fpermissive]
char fonctions(argv);}
^
A char * is a pointer to a memory address holding a character, and is often used for c-strings.
A char ** is a pointer to a memory address holding a pointer to a memory address holding a character, and is often used for arrays of c-strings.
Your main signature if not a valid form, since there's no form of main which takes in only a character pointer. The form you are most likely looking for is int main( int argc, int **argv ). This takes in two parameters: argc being the number of arguments passed to the program, and argv containing the parameters, as c-strings, passed to the program.
In the main method, you would generally ensure that argc is correct, i.e. you have the correct number of parameters passed into your function (note: it's always at least 1 will argv[0] being the program name).
std::string a = argv[1] is fine, and it will cause the string pointed to by argv to be converted to a string. When calling your functions, you have char functionu(argv);. You will want to remove the char from that line; effectively, the way it is written, you are trying to create a char variable named functionu which has an initial value of argv.
Each of your functions, instead of taking in a char * should take in a char ** instead, then when you have something like char file = argv[3];, you would want to change this to char *file = argv[3];, or std::string file = argv[3];

Compiling error with C++

This is the error and program. I gives me this error, and I cant find any mispelling in main.cpp
ERROR
main.cpp: In member function ‘int GPIO::unexport_gpio()’:
main.cpp:27:45: error: conversion from ‘const char*’ to non-scalar type ‘std::ofstream {aka std::basic_ofstream<char>}’ requested
ofstream unexportgpio = (unexport_str.c_str());
~~~~~~~~~~~~~~~~~~~^~~
main.cpp:28:7: error: ‘exportgpio’ was not declared in this scope
if(!(exportgpio.is_open())
^~~~~~~~~~
main.cpp:29:3: error: expected ‘)’ before ‘return’
return -1;
^~~~~~
main.cpp:30:2: error: ‘exportgpio’ was not declared in this scope
exportgpio<<this->gpionum;
^~~~~~~~~~
main.cpp: In member function ‘int GPIO::setdir_gpio(std::__cxx11::string)’:
main.cpp:36:64: warning: statement has no effect [-Wunused-value]
std::string setdir_str = "/sys/class/gpio/gpio"+this->gpionum;+"/direction";
^~~~~~~~~~~~~
main.cpp:37:41: error: conversion from ‘const char*’ to non-scalar type ‘std::ofstream {aka std::basic_ofstream<char>}’ requested
ofstream setdirgpio = (setdir_str.c_str());
~~~~~~~~~~~~~~~~~^~~
main.cpp: At global scope:
main.cpp:48:2: error: ‘setdirgpio’ does not name a type
setdirgpio.close();
^~~~~~~~~~
main.cpp:49:2: error: expected unqualified-id before ‘return’
return 0;
^~~~~~
main.cpp:50:1: error: expected declaration before ‘}’ token
}
^
main.cpp: In member function ‘int GPIO::setdir_gpio(std::__cxx11::string)’:
main.cpp:47:2: warning: control reaches end of non-void function [-Wreturn-type]
}
^
main.cpp
#include "main.h"
GPIO::GPIO()
{
this->gpionum = "4";
}
GPIO::GPIO(std::string gnum)
{
this->gpionum = gnum;
}
int GPIO::export_gpio()
{
string export_str = "/sys/class/gpio/export";
ofstream exportgpio(export_str.c_str());
if(!(exportgpio.is_open()))
return -1;
exportgpio << this->gpionum;
exportgpio.close();
return 0;
}
int GPIO::unexport_gpio()
{
std::string unexport_str = "/sys/class/gpio/unexport";
ofstream unexportgpio = (unexport_str.c_str());
if(!(exportgpio.is_open())
return -1;
exportgpio<<this->gpionum;
return 0;
}
int GPIO::setdir_gpio(std::string x)
{
std::string setdir_str = "/sys/class/gpio/gpio"+this->gpionum;+"/direction";
ofstream setdirgpio = (setdir_str.c_str());
if(!(setdirgpio.is_open()))
return -1;
if(x == "0")
{
setdirgpio<<"in";
}
if(x == "1")
setdirgpio<<"out";
}
setdirgpio.close();
return 0;
}
int GPIO::setval_gpio(std::string x)
{
string setval_str = "/sys/class/gpio/gpio"+this->gpionum+"/value";
ofstream setvalgpio = (setval_str.c_str());
if(!(setvalgpio.is_open()))
return -1;
if(x == "0")
{
setvalgpio<<"0";
setvalgpio.close();
}
if(x == "1")
setvalgpio<<"1";
setvalgpio.close();
}
return 0;
}
Im trying to make a program that switches the state on my RPI3.
Im used to it on the Arduino, but not on RPI3.
If you know how to fix, then don't hesitate to write.
It is supposed to drive my garten sprinkler
ofstream unexportgpio = (unexport_str.c_str());
should be
ofstream unexportgpio(unexport_str.c_str());
Incidentally this is an odd piece of code
std::string unexport_str = "/sys/class/gpio/unexport";
ofstream unexportgpio(unexport_str.c_str());
Why not do it the simpler way?
ofstream unexportgpio("/sys/class/gpio/unexport");
There's no need to make a std::string from a C string literal, only to get the C string back again.

C++ error: invalid conversion from ‘char’ to ‘const char*’ [-fpermissive]

#include <iostream>
#include <string>
using namespace std;
float findSimilarityScore(string A, string B)
{
string C;
if (A.length() != B.length())
{
return -1;
}
if (A.length() == 0 and B.length() == 0)
{
return -1;
}
else
{
int i;
for (i = 0; A.length() - 1; i = i+1)
{
if (A[i] == B[i])
{
C.append(A[i]);
}
if (A[i] != B[i])
{
return 0;
}
}
cout << C << endl;
}
}
int main()
{
findSimilarityScore("DDS","DAS");
}
when i try to run my code, my IDE show this:
/home/ubuntu/workspace/hmwk4/hmwk4-1.cpp: In function ‘float findSimilarityScore(std::string, std::string)’:
/home/ubuntu/workspace/hmwk4/hmwk4-1.cpp:24:30: error: invalid conversion from ‘char’ to ‘const char*’ [-fpermissive]
Why?
I want : if the first char in A is same to the first char in B, then add this char to the string C. if the second char in A is same to the second char in B, then add this char to the string C. And so on.
In the line
C.append(A[i]);
std::string::append has no overload that takes a single char. Use push_back instead:
C.push_back(A[i]);
This will fix your compilation error, but your function is still logically incorrect. It returns 0 the first time it finds any character that doesn't match between the two strings, and if the two strings are identical then it will invoke undefined behavior by reaching the end of a non-void function without returning a value.
string::append() with a single parameter is expecting a string argument, you are passing a single char. Try
C.append(1, A[i]);
Also, once you find a non-matching char, you return without printing the new string. Move the cout just before the return
if (A[i] != B[i])
{
cout << C << endl;
return 0;
}
And be sure to add a return at the end of your function in case you don't find any characters which are unequal.

expected primary-expression before ‘const’ errors

Please help. I am getting many errors.
sub2.cpp: In function ‘int main()’:
sub2.cpp:11:14: error: invalid conversion from ‘const char*’ to ‘char’ [-fpermissive]
sub2.cpp:12:14: error: invalid conversion from ‘const char*’ to ‘char’ [-fpermissive]
sub2.cpp:16:17: error: expected primary-expression before ‘const’
sub2.cpp:16:36: error: expected primary-expression before ‘const’
sub2.cpp:11:6: warning: unused variable ‘outer’ [-Wunused-variable]
sub2.cpp:12:6: warning: unused variable ‘inner’ [-Wunused-variable]
make: * [sub2] Error 1
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
char *Subtract(const char *outer, const char *inner);
int main()
{
char outer = "Bookkepper";
char inner = "keep";
char *word = new char[50];
word = Subtract(const char &outer, const char &inner);
cout << word << endl;
return 0;
}
char *Subtract(const char *outer, const char *inner)
{
int olen = strlen(outer);
int first_occ_idx = -1;
for(int i=0; i < olen; i++){
if(strncmp(outer+i, inner,strlen(inner)) == 0){
first_occ_idx = i;
}
}
if(first_occ_idx == -1){
return NULL;
}
int ilen = strlen(inner);
int xx = olen - ilen;
char *newstr = new char[xx];
int idx = 0;
for(int i=0; i < first_occ_idx; i++){
newstr[idx++] = outer[i];
}
for(int i=first_occ_idx+ilen; i < olen; i++){
newstr[idx++] = outer[i];
}
newstr[idx] = '\0';
return newstr;
}
In C++, string literals like "Bookkepper" (sic) are const character pointers, it's a little stricter than in C. So it should be:
const char *outer = "Bookkeeper"; // Note also spelling
rather than:
char outer = "Bookkepper";
In addition, you don't include types when calling a function, so:
word = Subtract(const char &outer, const char &inner);
would be better as:
word = Subtract(outer, inner);
Separately (and these are style suggestions only), the correct type for things that represent sizes (such as number of characters in a string) is size_t rather than int.
And it's usually considered good form to clean up all your dynamic memory explicitly so, before returning from main(), you could put:
delete[] word;