I'm a new Computer Science student, and I have a homework question that is as follows:
Write a Function that passes in a C-String and using a pointer determine the number of chars in the string.
Here is my code:
#include <iostream>
#include <string.h>
using namespace std;
const int SIZE = 40;
int function(const char* , int, int);
int main()
{
char thing[SIZE];
int chars = 0;
cout << "enter string. max " << SIZE - 1 << " characters" << endl;
cin.getline(thing, SIZE);
int y = function(thing, chars, SIZE);
cout << y;
}
int function(const char *ptr, int a, int b){
a = 0;
for (int i = 0; i < b; i++){
while (*ptr != '\0'){
a++;
}
}
return a;
}
First of all welcome to stackoverflow ye0123! I think you are trying to rewrite the strlen() function here. Try giving the following link a look Find the size of a string pointed by a pointer.
The short answer is that you can use the strlen() function to find the length of your string. The code for your function will look something like this:
int function(const char *ptr)
{
size_t length = strlen(ptr);
return length;
}
You should also only need this function and main.
Edit: Maybe I misunderstood your question and you are supposed to reinvent strlen() after all. In that case, you can do it like so:
unsigned int my_strlen(const char *p)
{
unsigned int count = 0;
while(*p != '\0')
{
count++;
p++;
}
return count;
}
Here I am comparing *p from '\0' as '\0' is the null termination character.
This was taken from https://overiq.com/c-programming-101/the-strlen-function-in-c/
Related
I am trying to reverse a char which has been provided in input from an user. I am having issues with the reverse function, particularly the loop. I can't get it to work- can I get advice?
#include <iostream>
using namespace std;
#include <cstring>
char* reverse(char* input) {
int len = strlen(input);
char temp[len];
for(int i=len; i>len; --i) {
temp[i]+=input[i];
}
return temp;
}
int main()
{
char input[100];
while(cin>>input) {
cout << reverse(input);
}
return 0;
}
Your Program has few issues
You're trying to return local variable address i.e. temp array address. The Function will return the address to main function. Since memory might get cleaned so it will print garbage value present at the address.
As Rohan Bari mentioned variable length array might cause undefined behavior. There for you can create a constant length array i.e.
char temp[100];
or you can dynamically allocate array on heap. Memory allocated on heap do not get cleared after termination of block but we have to manually delete it.
char* temp = new char[len];
As array start from 0 it goes till len-1 so loop condition should start from len-1 and has to go till 0 to reverse.
+ operator do not work's with array or char even if you are trying to add just char it preforms normal integer addition of their ASCII value.
Here is improved version of your code
#include<iostream>
using namespace std;
#include <cstring>
char* reverse(char* input) {
int len = strlen(input);
char* temp = new char [len]; // or you can use char temp[100];
int j = 0; //temp variable to enter values from 0th index if we use same as loop it just enter in the same order as original char array.
for(int i=len-1; i>=0; --i) {
temp[j++] = input[i];
}
temp[j] = '\0';
return temp;
}
You have got several errors in the program.
The variable-length arrays are used here:
char temp[len];
This should not be applied in C++ since this invokes undefined-behavior. Note that this is a valid statement in the C99 standard.
There is a better alternative to this. That is to take the std::string built-in type in use.
In the following line:
temp[i] += input[i];
You are not sequentially adding one character after another, but the values of them in a single integer. This could be not a problem if temp was of the type std::string.
The reverse function should look like this:
const char *reverse(char *input) {
int len = strlen(input);
std::string temp;
while (len--)
temp += input[len];
return temp.c_str();
}
len should actually be (len-1) and i should be >= 0 not len, so from (len-1) to 0 your loop should run.
for(int i = len-1; i >= 0; i--){}
You have to allocate the new array with the new keyword if you don't want to use a string. The following code does what you need:
char* reverse(char* input)
{
int len = strlen(input);
char* temp = new char[len + 1];
for (int i = len; i >= 0; --i)
{
temp[len-i-1] = input[i];
}
temp[len] = '\0';
return temp;
}
You could use a std::stack to reverse your input:
std::stack<char> s;
char c;
while (std::cin >> c)
{
s.push(c);
}
while (!s.empty())
{
std::cout << s.top();
s.pop();
}
It's 2021. Use the STL. If your instructor isn't aware of it or doesn't allow you to use it, your instructor is not keeping up-to-date and you should fire your instructor.
#include <algorithm>
#include <iostream>
#include <string>
int main() {
std::string input{};
while(std::getline(std::cin, input)) {
std::reverse(std::begin(input), std::end(input));
std::cout << input << '\n';
}
return 0;
}
There's quite many things wrong with the code as many people have already mentioned! Since you want to implement this without using STL it can be done this way,
#include <iostream>
using namespace std;
#include <cstring>
void reverse(char* input,int len) { //added len as argument
char temp[len];
for(int i=len-1; i>=0; --i) {
temp[len-i-1]=input[i];
cout<<temp[len-i-1]; //printing while reversing
}
cout<<endl;
}
int main()
{
char input[100];
int len=0;
//using do while since it has to run atleast once
do{
cin.getline(input,100);
len=strlen(input);
input[len]='\0';
if(len!=0)
reverse(input,len);
}while(len!=0) ;
return 0;
}
As part of my homework assignment, I have to split a char[] by its indices. So for example, the main function looks like:
int main()
{
char str[] = "A string to be split into given number of parts";
int split_size;
cout << "Enter the size of the part: ";
cin >> split_size;
int size = sizeof(str) / sizeof(str[0]);
SplitString(str, split_size, size);
int wait;
cin >> wait;
return 0;
}
Then using the function SplitString, the first x elements are printed, new line, then the next.
My first idea, was to use two for loops. One loops through the splits (i.e. if there are 4 splits, the range on this loop is 0 to 3), then the second loops through the split itself, iterating over the array elements.
My SplitString() function looks like this:
void SplitString(char str[], int split_size, int size) {
int parts = size / split_size;
for (int i = 0; i < parts; i++) {
for (int j = 0; j < split_size; j++) {
j = split_size * i;
cout << str[j];
}
cout << endl;
}
}
Is there an easier way to do this? I know in Python, you can use the arr[1:] to grab a range of elements from the array. Is there anything similar in C++? Is there some flaw in my logic? Is there something wrong with my code?
cout comes with a write function that takes a pointer and a size argument.
for (int i = 0; i < parts; i++) {
cout.write (str+i*split_size, split_size)
cout << endl;
}
Note that the code above does not check if the string is actually long enough. If the total size is not equal the split_size times a whole number, you will have to add an additional check.
Also, note that this:
int size = sizeof(str) / sizeof(str[0]);
can be written as:
int size = sizeof(str);
instead because the size of a char is always 1.
You can use std::string for this. Alternatively, if your compiler supports C++17, you can use std::string_view as the first argument of SplitString to avoid unnecessary copying.
#include <algorithm>
#include <iostream>
#include <string>
void SplitString(std::string s, std::size_t split_size)
{
while(!s.empty())
{
auto size = std::min(split_size, s.size());
std::cout << s.substr(0, size) << '\n';
s = s.substr(size, std::string::npos);
}
}
int main()
{
char str[] = "A string to be split into given number of parts";
int split_size = 5;
SplitString(str, split_size);
return 0;
}
Live example.
I'm having trouble trying to come up with the pointer version of this function:
void strncpy(char t[], const char s[], const unsigned int n)
{
unsigned int i = 0;
for(i = 0; i < n and s[i]; i++)
t[i]=s[i];
t[i] = '\0'
}
This function is supposed to copy the first "n" characters of one array to another array and then terminate with a null character. I'm sure this is simple but I'm still learning pointers :P
This is what I have right now:
void strncpy(char * t, const char * s, const unsigned int * n)
{
unsigned int i = 0;
for(i = 0; i < *n and *s; i++)
*t = *s;
*t = '\0';
}
Im calling it in main via:
char array_one[5] = "quiz";
char array_two[5] = "test";
unsigned int x = 2;
strncpy(array_one,array_two,x);
You've failed to increment the pointers, so you're always overwriting the same address. There's also no need to pass n via a pointer:
#include <cstddef>
void my_strncpy(char *t, const char *s, std::size_t n) {
while (n && *s) {
*t++ = *s++;
--n;
}
*t = '\0';
}
NB: note use of size_t to duplicate the standard parameter signature
of the standard strncpy function, although the standard version also returns the original value of t rather than void.
#include <iostream>
// changing the function signature to take an int instead of
// pointer to int - cleaner
void my_strncpy(char * t, const char * s, const unsigned int n)
{
unsigned int i = 0;
for(i = 0; i < n; i++)
{
*t++ = *s++; // copy and increment
}
*t = '\0'; // fixing - added terminating char
}
int main(void)
{
char a[] = "string1";
char b[] = "string2";
my_strncpy(a,b,7); // replace 7 with appropriate size
std::cout << a << std::endl;
}
You need to copy over each character from one string to another and then increment the pointers - you were missing that in your implementation.
I also assume that you will not overshoot the array you are copying from.
Hello I'm new to c++ and can't figure out why my code is doing this. I've scoured across the internet and can't find the solution I need. I appreciate all the help. The line that's giving me the problem is when I'm calling the function. According to visual studios it states that "argument of type 'char*' is incompatible with parameter of type 'char**'". It's referring to newArr.
#include <iostream>
#include <string>
#include <stdio.h>
#include <ctype.h>
#include "stdafx.h"
using namespace std;
bool isPalindrome(char *newArr[], int);
//int i = 0;
//char phrase;
//char c;
bool palindrome;
bool tOf;
int numb;
char c;
const int length = 80; //const so that it can't be changed
char inarr[length]; //array set to a const length of 80
char newArr[length]; //array that will have no spaces
string str;
int main()
{
cout << "This program tests if a word/phrase is palindrome.\n\n";
cout << "Please enter your phrase (just letters and blanks,
please):\n\n";
cin.getline(inarr, length);
//cout << array; //spits out the array
str = inarr; //turn into string
numb = str.length();
//cout << numb << "\n"; //how many characters in array
for (int i = 0; i < (numb / 2) + 1; i++)
{
for (int j = 0; j < (numb / 2) + 1; j++)
{
newArr[j] = inarr[i]; //from old array to new array
c = newArr[j];
newArr[j] = toupper(c); //change to all upper case
//cout << newArr[j];
i += 2; //goes to every other index to skip space in string
}
}
tOf = isPalindrome(newArr, numb); //calling of function
if (tOf == true) //the response to true or false
{
cout << "\nYes, the phrase is a palindrome!";
}
else
{
cout << "\nNo, the phrase is not a palindrome!";
}
return 0;
}
bool isPalindrome(char *newArr[], int numb) //function to determine true or
false
{
for (int i = 0; i < (numb / 2) + 1; i++) //within the array...
{
if (newArr[i] != newArr[(numb / 2) - i]) //if first index != last
and etc (iterates)
{
palindrome = false;
}
else
{
palindrome = true;
}
}
return palindrome;
}
You're trying to pass newArr (a char *) into isPalindrome() (which takes a char **). This is what "argument of type 'char*' is incompatible with parameter of type 'char**'" means.
To fix this, simply pass in a char **; you can do this by passing in the address of newArr instead of newArr itself:
tOf = isPalindrome(&newArr, numb); //calling of function
Brief
Change the function signature (both definition and declaration) of the function to
bool isPalindrome(char* newArr, int numb);
Call it
tOf = isPalindrome(newArr, numb);
Detail
If you call isPalindrome(newArr, numb). you are passing address of the first element either &newArr[0] . So you are function defination should be able to pick the address of the element. hence *newArr
Further your function will validate the details by using array arithmetic. which is all right .
Output
$ ./a.out
This program tests if a word/phrase is palindrome.
Please enter your phrase (just letters and blanks, please):
Palindrome
No, the phrase is not a palindrome!
$ ./a.out
This program tests if a word/phrase is palindrome.
Please enter your phrase (just letters and blanks, please):
YeseY
Yes, the phrase is a palindrome!
$
I wrote the following to try to use the qsort() function. My goal is to input several lines of text and print an alphabetical listing of each word. This code crashes every time I run it and i am not sure as to why or how to fix it. I also need to add something to count the number of times a word occurs and print that as well but I an mot too sure how to do that. Any advice would be very helpful. Thanks!
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
struct to_lower
{
int operator() ( int ch )
{
return tolower ( ch );
}
};
int compare (const void * a, const void * b)
{
//return ( *(int*)a - *(int*)b );
return (strcmp(*(const char **)a, *(const char **)b));
}
int main()
{
string list[900];
int nLength;
int i=0, q=0;
string nTemp;
int word[900];
cout
<< "Enter some lines of text "
<< "(Enter Ctrl-Z on a line by itself to exit)\n"
<< endl;
while ( !cin.eof() )
{
cin >> list[i];
transform(list[i].begin(), list[i].end(), list[i].begin(), to_lower());
word[q]=1;
if (list[i]==list[i-1])
{
word[q]=+1;
}
i++;
}
nLength = i;
cout << "The sorted words would be:\n";
qsort(list, nLength, sizeof list[0],&compare);
int n;
for (n = 0; n < nLength; n++)
{
cout <<" \n"<< n << list[n]<< word[n];
}
return 0;
}
std::string is not a char* as your qsort compare function pretends. Also, you should never use qsort with C++ objects. qsort does not know about objects and won't call copy constructors and may damage the internal structure.
When i=0, using list[i-1] is a bug.
You need to count your duplicate words after sorting or you have no guarantee that duplicates are next to each other.