Equal strings (string and string of array)-c++ - c++

I dont understand how to compare between string in c++??
string s1="abc";
string s[]={"abc","vsj"};
int length=sizeof(s)/sizeof(s[0]);//length of s
for(int i=0;i<length;i++)
{
if(s[i].compare(s1))
{
cout<<"One of the string equal to s1";
}
}
Is it possible??
Thanks..

std::string overloads operator==. You can compare 2 string using operato==. Also you can use std::vector instead of array. Using c++11:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main() {
string s1="abc";
vector<string> ss = { "abc", "vsj" };
for (auto &s: ss) {
if (s == s1) {
cout<<"One of the string equal to s1";
}
}
return 0;
}
Using c++98:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main() {
string s1="abc";
vector<string> ss;
ss.push_back("abc");
ss.push_back("vsj");
for (size_t i = 0; i < ss.size(); ++i) {
if (ss.at(i) == s1) {
cout<<"One of the string equal to s1";
}
}
return 0;
}

compare return the same values as strcmp:
<0 - the first character that does not match has a lower value in ptr1 than in ptr2
0 - the contents of both strings are equal
>0 - the first character that does not match has a greater value in ptr1 than in ptr2

Related

string repetition replaced by hyphen c++

I am a beginner at coding, and was trying this question that replaces all repetitions of a letter in a string with a hyphen: i.e ABCDAKEA will become ABCD-KE-.I used the switch loop and it works, but i want to make it shorter and maybe use recursion to make it more effective. Any ideas?
#include<iostream>
#include<string.h>
using namespace std;
int main()
{
char x[100];
int count[26]={0}; //initialised to zero
cout<<"Enter string: ";
cin>>x;
for(int i=0; i<strlen(x); i++)
{
switch(x[i])
{
case 'a':
{
if((count[0]++)>1)
x[i]='-';
}
case 'b':
{
if((count[1]++)>1)
x[i]='-';
}
case 'c':
{
if((count[2]++)>1)
x[i]='-';
}
//....and so on for all alphabets, ik not the cutest//
}
}
Iterate through the array skipping whitespace, and put characters you've never encountered before in std::set, if you find them again you put them in a duplicates std::set if you'd like to keep track of how many duplicates there are, otherwise change the value of the original string at that location to a hyphen.
#include <iostream>
#include <string>
#include <cctype>
#include <set>
int main() {
std::string s("Hello world");
std::set<char> characters;
std::set<char> duplicates;
for (std::string::size_type pos = 0; pos < s.size(); pos++) {
char c = s[pos];
// std::isspace() accepts an int, so cast c to an int
if (!std::isspace(static_cast<int>(c))) {
if (characters.count(c) == 0) {
characters.insert(c);
} else {
duplicates.insert(c);
s[pos] = '-';
}
}
}
return 0;
}
Naive (inefficient) but simple approach, requires at least C++11.
#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>
std::string f(std::string s)
{
auto first{s.begin()};
const auto last{s.end()};
while (first != last)
{
auto next{first + 1};
if (std::isalpha(static_cast<unsigned char>(*first)))
std::replace(next, last, *first, '-');
first = next;
}
return s;
}
int main()
{
const std::string input{"ABCDBEFKAJHLB"};
std::cout << f(input) << '\n';
return 0;
}
First, notice English capital letters in ASCII table fall in this range 65-90. Casting a capital letter static_cast<int>('A') will yield an integer. If after casing the number is between 65-90, we know it is a capital letter. For small letters, the range is 97-122. Otherwise the character is not a letter basically.
Check create an array or a vector of bool and track the repetitive letters. Simple approach is
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
string str("ABCDAKEAK");
vector<bool> vec(26,false);
for(int i(0); i < str.size(); ++i){
if( !vec[static_cast<int>(str[i]) - 65] ){
cout << str[i];
vec[static_cast<int>(str[i]) - 65] = true;
}else{
cout << "-";
}
}
cout << endl;
return 0;
}
Note: I assume the input solely letters and they are capital. The idea is centered around tracking via bool.
When you assume input charactor encode is UTF-8, you can refactor like below:
#include <iostream>
#include <string>
#include <optional>
#include <utility>
std::optional<std::size_t> char_to_index(char u8char){
if (u8'a' <= u8char && u8char <= u8'z'){
return u8char - u8'a';
}
else if (u8'A' <= u8char && u8char <= u8'A'){
return u8char - u8'A';
}
else {
return std::nullopt;
}
}
std::string repalce_mutiple_occurence(std::string u8input, char u8char)
{
bool already_found[26] = {};
for(char& c : u8input){
if (const auto index = char_to_index(c); index && std::exchange(already_found[*index], true)){
c = u8char;
}
}
return u8input;
}
int main(){
std::string input;
std::getline(std::cin, input);
std::cout << repalce_mutiple_occurence(input, u8'-');
}
https://wandbox.org/permlink/UnVJHWH9UwlgT7KB
note: On C++20, you should use char8_t instead of using char.

Word Frequency strcmp working infinitely using struct array

I want to do a read word by word and compare what word with what I have in my struct array. If I don't have one, I want to add in the first empty spot.
#include <iostream>
#include <fstream>
#include <string>
#include<string.h>
using namespace std;
struct cuvinte{
char *cuvant;
int numar;
};
int main()
{
cuvinte multime[100];
ifstream f;
f.open("input.txt");
string str;
while(getline(f,str))
{
char * cuvant = new char[str.size() + 1];
char * abc = new char[str.size() + 1];
copy(str.begin(), str.end(), abc);
cuvant = strtok (abc," ,/_");
while(cuvant!=NULL)
{
for(int i=0;i<10;i++)
{
cout<<cuvant;
if(strcmp(cuvant,multime[i].cuvant)==0)
multime[i].numar++;
else
{
for(int j=0;j<10;j++)
if(multime[j].numar==0)
{
multime[j].cuvant=cuvant;
multime[j].numar=1;
}
}
}
cuvant = strtok ( NULL , " ");
}
}
return 0;
}
Strcmp works infinitely and only takes the first word; I don't know why.
In C++ it should only take a handful of lines:
#include <string>
#include <fstream>
#include <unordered_map>
using WordFrequency = std::unordered_map<std::string, unsigned>;
WordFrequency read_words(std::istream& s) {
WordFrequency wf;
for(std::string word; s >> word;)
++wf[word];
return wf;
}
int main() {
std::fstream f("input.txt");
auto wf = read_words(f);
}
Before using word you may like to lower-case it and remove all punctuation, so that your dictionary doesn't contain separate entries for the same word, e.g. Or, or, or,.

C++ segmentation fault while counting character occurrences in string

I've written a simple function to count occurrences of a character in a string. The compiler is fine. However, as I try to run it, it produced a segmentation fault.
#include <iostream>
using namespace std;
// To count the number of occurences of x in p
// p is a ะก-style null-terminated string
int count_x(char* p, char x)
{
if (p == nullptr)
{
return 0;
}
// start the counter
int count = 0;
while (p != nullptr)
{
if (*p == x)
{
++count;
}
}
return count;
}
int main(int argc, char const *argv[])
{
char myString[] = "Hello";
cout << count_x(myString, 'l');
return 0;
}
There's two mistakes in your code:
You only ever look at the first character in the string.
The last character of a null terminated string is a null character. You're testing the pointer itself.
You need to use std::string
#include <string>
#include <algorithm>
#include <iostream>
int main()
{
std::string str = "Hello";
std::cout << std::count(str.begin(), str.end(), 'l');
}

Why my character array(string) is breaking?

I have written a code to copy from first string's element to second string except space.it simply takes input and if it gets a space then it doesn't insert character of first string into second string. when i am printing second string at the last,the string is partially broken up. But instead of space,if i put any character the second string fully prints out.I am trying but could you fix my bug please?
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
int main()
{
char str1[100];
while(cin>>str1)
{
char str2[100];
int k=0;
for(int i=0; str1[i]!='\0'; i++)
{
if(str1[i]!=' ')
{
str2[k] = str1[i];
k++;
}
}
str2[k] = '\0';
cout<<"result is "<<str2<<endl;
}
return 0;
}
You can use gets() and puts() to read/display a string:
#include <iostream>
#include <string.h>
using namespace std;
int main(void)
{
char s1[100], s2[100];
int k=0;
puts("Insert your string:");
gets(s1);
for (int i=0; i<strlen(s1); i++) {
if (s1[i] != ' ') {
s2[k]=s1[i];
k++;
}
}
puts(s2);
}

Counting occurrences of word in vector of characters

I have written a program to store a text file in vector of characters .
#include<iostream>
#include<fstream>
#include <algorithm>
#include<vector>
using namespace std;
int main()
{
vector<char> vec;
ifstream file("text.txt");
if(!file.eof() && !file.fail())
{
file.seekg(0, std::ios_base::end);
std::streampos fileSize = file.tellg();
vec.resize(fileSize);
file.seekg(0, std::ios_base::beg);
file.read(&vec[0], fileSize);
}
int c = count(vec.begin(), vec.end(), 'U');
cout << c;
return 0;
}
I want to count occurrence of "USER" in the text file , but using count i can only count number of characters . How can i count number of occurrences of "USER" in the vector of character?
For example
text.txt
USERABRUSER#$$* 34 USER ABC RR IERUSER
Then the count of "USER" is 4. Words can only be in uppercase.
std::string has a find member function that will find an occurrence of one string inside another. You can use that to count occurrences something like this:
size_t count(std::string const &haystack, std::string const &needle) {
auto occurrences = 0;
auto len = needle.size();
auto pos = 0;
while (std::string::npos != (pos = haystack.find(needle, pos))) {
++occurrences;
pos += len;
}
return occurrences;
}
For example:
int main() {
std::string input{ "USERABRUSER#$$* 34 USER ABC RR IERUSER" };
std::cout << count(input, "USER");
}
...produces an output of 4.
This is how I would do it:
#include <fstream>
#include <sstream>
#include <iostream>
#include <unordered_map>
#include <string>
using namespace std;
int main() {
unordered_map<string, size_t> data;
string line;
ifstream file("text.txt");
while (getline(file, line)) {
istringstream is(line);
string word;
while (is >> word) {
++data[word];
}
}
cout << data["USER"] << endl;
return 0;
}
Let's try again. Once again, a vector isn't necessary. This is what I would consider to be the most C++ idiomatic way. It uses std::string's find() method to repeatedly find the substring in order until the end of the string is reached.
#include <fstream>
#include <iostream>
#include <string>
int main() {
// Read entire file into a single string.
std::ifstream file_stream("text.txt");
std::string file_contents(std::istreambuf_iterator<char>(file_stream),
std::istreambuf_iterator<char>());
unsigned count = 0;
std::string substr = "USER";
for (size_t i = file_contents.find(substr); i != std::string::npos;
i = str.find(substr, i + substr.length())) {
++count;
}
}