Char array length function - c++

Does anyone know how to write a function that counts length of an array given like in example ?
cout << length(argv[1]) << endl;
I've tried somethig like this but it says that there can't be function lentgh then.
for(int i = 0; myStrChar[i] != '\0'; i++)
{
count++;
}
EDIT1: Here is the rest of code :
#include <iostream>
#include<cstring>
using namespace std;
int i;
int length()
{
for(int i = 0; myStrChar[i] != '\0'; i++)
{
count++;
}
}
int main()
{
cout << "Hello world!" << endl;
cout << "length of first text: ";
cout << length(argv[1]) << endl;
char tab[255] = {"Ana has a cat"};
EDIT2: Now I did something like this but it puts out 108 as length of text
char argv[]="ana has a cat";
int length(char l)
{
int cou= 0;
for(int i = 0; i!=0; i++)
{
cou++;
return cou;
}
}

Hmm, what's wrong? It is a valid code - just wrap it into a function:
size_t length(const char* myStrChar)
{
size_t count = 0;
for(int i = 0; myStrChar[i] != '\0'; i++) {
count++;
}
return count;
}
You can do it a bit shorter:
size_t length(const char* myStrChar)
{
size_t count = 0;
for (; myStrChar[count] != 0; count++)
/* Do nothing */;
return count;
}
UPD:
Here is a code from the question and my comments to author:
// You're passing just a single character to this function - not array
// of char's - not a string.
// Pass char* or better const char*.
int length(char l)
{
int cou= 0;
// Ok, this loop does nothing - it's going to stop at the
// first condition check, because you assign 0 to i
// and immediately check if it is not zero - this check will
// return false and the loop will never start.
// Check the current symbol in string if it is not zero
for(int i = 0; i!=0; i++)
{
cou++;
// Even if you'll fix mistakes above, your loop will stop
// at the first iteration, because of this return.
// You must put it right after the loop.
return cou;
}
// Your function actually returns nothing, because no iterations
// of the loop above is performed - so no return statement reached
// at all - it is undefined behaviour :(
// Put return here out of the loop;
}

Related

filling 2d char array and accessing each element

It's my first question in stack overflow so if there is some mistakes sorry about that. I'm trying to fill a 2d char array and then access each letter. I complied my code, there is no error but when I try to run it doesn't work. Here it's my code.
#include<iostream>
#include<string>
#include<stdlib.h>
using namespace std;
int main() {
char ch[] = "Welcome text in a separate line.";
char strWords[5][7];
int counter = 0;
int a = 0;
for (int i = 0; i < sizeof(ch); i++) {
if (ch[i] == ' ') {
strWords[counter][a] = '\0';
counter++;
a = 0;
}
else
{
strWords[counter][a] += ch[i];
a++;
}
}
for (int i = 0; i <= 5; i++) {
for (int a = 0; a <= 7; a++) {
cout << strWords[i][a] << " ";
}
}
return 0;
}
A few things wrong with your code
int main() {
char ch[] = "Welcome text in a separate line.";
// char strWords[5][7]; <<<=== i would change to be larger that you need, just in case
char strWords[20][20];
int counter = 0;
int a = 0;
for (int i = 0; i < strlen(ch); i++) { // sizeof is wrong, you need strlen
if (ch[i] == ' ') {
strWords[counter][a] = '\0';
counter++;
a = 0;
}
else
{
//strWords[counter][a] += ch[i];
strWords[counter][a] = ch[i]; // you do not need to try to concatenate, you are already walking down the buffer with 'a'
a++;
}
}
for (int i = 0; i < counter; i++) { // use 'counter' as it has the number of lines
// since you 0 terminated the string you do not need to walk character by character
cout << strWords[i] << " ";
}
return 0;
}
You are also not detecting and terminating the last word (since there is no space after it). I will leave that to you. The code I show does not print the word 'line.'
You should really have tests to make sure you do not overflow the length or number of words.
Plus you should ideally use std::string and std::vector
Note - if, for experimentation, you do want to walk through char by char to output the strings you should look for the terminating '0' character and exit the inner loop

what is the issue with this char reverse function?

so I wrote this code to reverse one of the names based on the user option the idea is to use another function to reverse and to use pointers but after trying all I could think of my code return the same name not changed the best I could do was changing the first letter of the name to a weird sign.
#include <iostream>
using namespace std;
void reverse(char* A) {
int count = 0;
char temp[10];
for (int i = 0; A[i] != NULL; i++)
count++;
for (int i = 0; A[i] != NULL; i++) {
temp[count]=A[i];
count--;
}
for (int i = 0; A[i] != NULL; i++) {
A[i] = temp[i];
}
}
int main(){
int x= 0;
int index;
char Name_list[5][10];
cout << "please enter the names of the student " << endl;
for (int i = 0; i < 5; i++) {
cin >> Name_list[i];
for (int j = 0; Name_list[i][j] != NULL; j++) {
x++;
}
while (x > 10)
{
x = 0;
cout << "you have entered more then the allowed number of characters per name enter another name " << endl;
cin >> Name_list[i];
for (int j = 0; Name_list[i][j] != NULL; j++) {
x++;
}
}
x = 0;
}
for (int i = 0; i < 5; i++) {
cout << Name_list[i] << endl;
}
cout << "please enter the index of the name you want to reverse" << endl;
cin >> index;
while (index>4||index <0)
{
cout << "you entered incorrect index please enter a number from 0 to 4 " << endl;
}
reverse(Name_list[index]);
for (int i = 0; i < 5; i++) {
cout << Name_list[i] << endl;
}
system("pause");
}
For starters such a function should return a pointer to the result string. That is it should be declared like
char * reverse( char *s );
Note: do not use variable names consisting from upper case letters.
The type int can be not large enough to store length of a string. Instead use the type size_t.
char * reverse( char *s )
{
size_t count = 0;
//...
It is totally unclear why there is present an array with the number of elements equal to the magic number 10
char temp[10];
To reverse a string there is no need to declare an auxiliary array. Such an approach is principally wrong.
In this for loop
for (int i = 0; A[i] != NULL; i++)
there is compared an object of the type char with the pointer NULL. The compiler should issue a message for such a wrong comparison. It seems you mean
for (int i = 0; A[i] != '\0'; i++)
In any case the introduced variable i in this first for loop is redundant because you already has the variable count.
As you have the array temp with the fixed size equal to 10 then the both loops after the first loop can invoke undefined behavior even if the length of the source string is equal exactly to 10.
And the result string is not zero terminated.
The function can look the following way.
char * reverse( char *s )
{
size_t count = 0;
while ( s[count] ) ++count;
for ( size_t i = 0; i < count / 2; i++ )
{
char c = s[i];
s[i] = s[count - i - 1];
s[count - i - 1] = c;
}
return s;
}
Or using standard functions you could write the function reverse the following way
#include <utility>
#include <cstring>
//...
char * reverse( char *s )
{
for ( size_t i = 0, n = std::strlen( s ); i < n / 2; i++ )
{
std::swap( s[i], s[n-i-1] );
}
return s;
}
Pay attention to that there is the standard algorithm std::reverse. Using it you could reverse a string the following way
std::reverse( s, s + std::strlen( s ) );
for (int i = 0; A[i] != NULL; i++) {
temp[count]=A[i];
count--;
}
If i goes up from 0 to 5, count goes down from 6 to 1.
Ok, a few things.
If you want do some string manipulation, look into the stdlib. Unless you are doing this for class.
Your writing everything to the end of the temp. buffer
You need to add an extra character at the end of the strings for the null byte (I think this implementation may allow for a seg. fault)

unpredictable number of nested loops

I'm trying to make a program that requires nested loops to work properly.
But the number of nested loops depend on the number of character the user inputs also the character to output.
This is my code so far.
#include<iostream>
using namespace std;
int main(){
string str;
cout<<"Enter some string: ";
cin>>str;
// for two characters
for(int i = 0; i < 2; i++){
for(int j = 0; j < 2 ; j++){
cout<<str[i]<<str[j]<<endl;
}
};
// for four characters
for(int i = 0; i<4; i++){
for(int j=0;j<4;j++){
for(int k =0;k<4;k++){
for(int z=0;z<4;z++)
cout<<str[i]<<str[j]<<str[k]<<str[z]<<endl;
}
}
}
return 0;
}
So, is there any way to solve this issue.
You need to do it dynamically:
std::vector<unsigned int> offsets(s.size());
bool isContinue;
do
{
for(auto offset : offsets)
{
std::cout << s[offset];
}
std::cout << std::endl;
isContinue = false;
for(auto offset = offsets.rbegin(); offset != offsets.rend(); ++offset)
{
if(++*offset < s.size())
{
isContinue = true;
break;
}
*offset = 0;
}
}
while(isContinue);
The idea behind is like upcounting numbers (decimally): Once you've reached 9, you increment next digit. Alike, each offset in the vector stands for one loop variable, on 'overflow', increment next offset, and as soon as most significant offset 'overflows', we are done.
High performance variant (using goto, sparing one comparison and the condition variable):
std::vector<unsigned int> offsets(s.size());
NEXT:
for(auto offset : offsets)
{
std::cout << s[offset];
}
std::cout << std::endl;
for(auto offset = offsets.rbegin(); offset != offsets.rend(); ++offset)
{
if(++*offset < s.size())
goto NEXT;
*offset = 0;
}
There are a couple basic ways to do that looping.
The first is the explicit one: you need to use an array of indexes instead of a single variable for the loop index. Then at each step you increment the last index and when that gets past the limit you reset it and increment the previous one:
int n = str.size(); // Get rid of unsigned
std::vector<int> index(n);
for(;;) {
// Generate output
for (int i=0; i<n; i++) {
std::cout << str[index[i]];
}
std::cout << std::endl;
// Increment
int i = n-1; // start from last index
while (i>=0 && index[i] == n-1) {
// I-th index has reached the end of the string, flip over to 0
index[i] = 0;
--i;
}
if (i == -1) break; // all of them returned to 0... that's all, folks
index[i] += 1;
}
The second way is using recursion, for example with a function accepting the partial string being built as argument and that if this prefix is not complete loops over the string and calls itself passing an extended prefix:
std::function<void(const std::string&)> proc = [&](const std::string& prefix) {
if (prefix.size() == str.size()) {
// Prefix is complete, just output result
std::cout << prefix << std::endl;
} else {
// Extend the prefix and call yourself for the nested loops
for (int j=0; j<n; j++) {
proc(prefix + str[j]);
}
}
};
proc("");
The recursive approach is more compact but takes some time to become comfortable and it can be problematic in certain cases.
A different way avoiding nested loops be to use simple counting and math... it's easy to write a function that returns the n-th string you're looking for without looping over the previous ones...
for (int i=0,loops=pow(n, n); i<loops; i++){
std::string s = "";
int k = i;
for (int j=0; j<n; j++) {
s = str[k % n] + s;
k /= n;
}
std::cout << s << std::endl;
}
Let's fold all your N nested loops into one nested loop. First, we need N indices, which will be incremented properly:
class Multiindex
{
public:
Multiindex(int size, int last_) : idx(size,0), last(last_) {}
void inc()
{
for (int i = idx.size() - 1; i >= 0; --i) {
if (idx[i] == last - 1) {
idx[i] = 0;
if (i == 0) complete = true;
}
else {
++idx[i];
break;
}
}
}
const auto& getIdx() const { return idx; }
const auto isComplete() const { return complete; }
private:
std::vector<int> idx;
int last;
bool complete = false;
};
It's a minimal example of a multiindex class. You also may write a decrement method or use a vector of last indices, if you need different indices in your nested loop.
Now everything is ready to replace your nested loop:
std::string s;// From user
Multiindex midx(s.length(), s.length());
while (!midx.isComplete()) { // Your nested loop
const auto& idx = midx.getIdx();
for (int i = 0; i < idx.size(); ++i) { // Replacement for cout << s[i] << s[j] << ... << s[z] << endl;
std::cout << s[idx[i]];
}
std::cout << std::endl;
midx.inc();
}

Runlength Encoding Algorithm[Data Compression]

I am trying to implement the algorithm RLE with simple input like:
ddddddddddhhhhhhhhhhhhhhhttttttttttttt
code:
#include<iostream>
#include<fstream>
#include<vector>
using namespace std;
int main() {
vector<char> read;
ifstream file;
file.open("file.txt");
if (!file) {
cout << "Unable to open";
}
char v;
while(file>>v) {
read.push_back(v);
}
char x;
int count=0;
for(int i=0; i<read.size(); i++) {
x = read[i];
if(x != read[++i]) {
cout << x << "1";
}
while(x == read[++i]) {
count++;
}
cout << x << count;
count = 0;
}
return 0;
}
The output I am getting is:
d9d1h12h1t10t1
Please help me with the code.
Update: I have updated the question as I have realized few things.
Plus: This code produced no output, is there anything wrong which I am doing wrong?
char o;
char n;
int count=0;
for(int i=0; i<read.size(); i++) {
o = read[i];
n = read[++i];
while(o == n) {
count++;
}
cout << o << count;
if(o != n) {
cout << o << "1";
} count = 0;
}
return 0;
This loop:
char x;
int count=0;
for(int i=0; i<read.size(); i++) {
int j=i;
x = read[i];
if(x != read[++j]) {
cout << x << "1";
}
while(x == read[++j]) {
count++;
}
cout << x << count;
}
Has several errors. First, you should use two indices, i and j. i is going through each element of read, but then j is iterating through a subsequence too. What you want is to go through each element only once, and in each case either print or increase the count. However having a for loop and moving the index inside too is not a very good practice, is rather error-prone. Also you have to cout statements that are do not run at the right time (you don't wan to print something on every iteration, only when the character changes). You could do it with a while loop, or using a simpler structure like:
// If there are no characters finish
if (read.empty()) {
return 0;
}
// Get the first character
char lastChar = read[0];
int count = 1; // We have counted one character for now
// Go through each character (note start from 1 instead of 0)
for(int i = 1; i < read.size(); i++) {
// Get the next char
char newChar = read[i];
// If it is different, print the current count and reset the counter
if (lastChar != newChar) {
cout << lastChar << count;
count = 1;
lastChar = newChar;
} else { // Else increase the counter
count++;
}
}
// Print the last one
cout << lastChar << count;
return 0;

copying one element of a char array to another using for loop

I'm trying to write a simple program which takes an array of chars, and spits it out backwards. I know there are plenty of other ways to shorten this using a library header function, but I wanted to do it using for loops just to get used to them.
#include<stdio.h>
#include<iostream>
using namespace std;
char string1[10];
int count = 0;
char stringy[10];
void enterString()
{
cout << "please enter a string: " << endl;
cin >> string1;
}
void stringCounter(const char stringLength[])
{
//initiate for loop i = 0
//if stringLength[i] does not does not equal 'i' then carry on
//increment i
for (int i = 0; stringLength[i] != '\0'; i++)
{
count++;
}
cout << "size of string is: " << count << endl;
}
void reverseString(int arraySize, char string2[])
{
int counter = 0;
for (int i = arraySize; i >= 0; string2[i--])
{
stringy[counter] = string2[i];
counter++;
}
stringy[count] = '\0';
cout << stringy << endl;
}
int main()
{
enterString();
stringCounter(string1);
reverseString(count, string1);
return 0;
}
This is the whole program. The program is failing in function reverseString. I can't work out how to successfully read the last index of the char array string2[] and copy it into the first index of char array stringy.
One, If the user enters a string more than 10 characters long then your enterString() function will access the array out of its bound, at cin>>string1. So better to use getline to make sure you don't read more than what your array can hold.
Two, with your current implementation the reverseString() function will write to the first element of the array with the null terminator character,if the arraySize<=10, and trying to display that string will not show you anything.
This:
cin >> string1;//will try to access the array out of its bound if user give more than it can hold,i.e 10 characters
...
for (int i = arraySize; i >= 0; string2[i--])
{
stringy[counter] = string2[i];//the first iteration will put the '\0' character as the first elements of stringy
counter++;
}
Should be changed to:
cin.getline(string1,10);//make sure to get not more than 10 characters,including the null terminator
.....
for (int i = arraySize-1; i >= 0; i--)
{
stringy[counter] = string2[i];
counter++;
}
There are many mistakes in your program. If this is the exact code you are compiling then it should throw many errors.
Following might help.
#include<iostream>
using namespace std;
void reverseString(int , char *);
int stringCounter(const char );
int stringCounter(const char stringLength[])
{
int count = 0;
for (int i = 0; stringLength[i] != '\0'; i++)
count++;
cout << "size of string is: " << count << endl;
return count;
}
void reverseString(int arraySize, char string2[])
{
int counter = 0;
char stringy[100];
for (int i = arraySize - 1; i >= 0; i--)
{
stringy[counter] = string2[i];
counter++;
}
stringy[counter] = '\0';
cout << stringy << endl;
}
int main()
{
char str[] = "string";
reverseString(stringCounter(str),str);
return 0;
}