null terminated char array (c-string) not printing without for loop - c++

**I can't use vectors, or any functions from the standard library with this program. Hence why I am writing it all myself.
Alright, this program is just about finished. All my user defined functions are working fine, except for the reverseCString function. When I run the program, and enter a string of "hello", I can select menu option "rev" to reverse the string. My main function then calls the reverseCString function, and uses the for loop in my main to print out my reversed c-string. The program works fine at this point, until the do-while loop continues..
After the rv function is called though, the program loops to continue to allow the user to modify their string, as it should. However, my c-string vanishes at this point. I can still operate on it if I use the other commands/funtions, but the c-string doesn't print to cout.
I don't understnad what is causing this, but I have isolated the problem down to the reverseCString function.
Here is my code so far:
#include<iostream>
#include<stdlib.h>
#include<cstring>
#include<string>
#include<math.h>
using namespace std;
void shiftLeft(char szString[], size_t shiftBy)
{
const char *p = szString;//
while (*p) ++p;//advance p to point to the the null terminator, found via personal research at http://stackoverflow.com/questions/12201815/what-difference-between-whilepp-while-p-and-whilep
size_t len = p - szString;//len is set to the size of our c-string
if (len > 1 && (shiftBy %= len))
{
char *ends[] = { szString+shiftBy, szString+len, szString+(len - shiftBy) };//create a temporary array for storage
for (size_t i = 0; i < 3; ++i)//use a for loop to flip the first three character
{
char *start = szString, *end = ends[i];
while (start < --end)//now flip the rest of the characters
{
char ch = *start;
*start++ = *end;
*end = ch;
}
}
}
}
void shiftRight (char szString[], int size, int shiftBy)
{
if(shiftBy > size){
shiftBy = shiftBy - size;
}
if(size == 1){
//do nothing, exit function with no change made to myarray
}
else{
char temp;
//for loop to print the array with indexes moved up (to the right) --> by 2
for (int i=0; i < size; i++)
{//EXAMPLE shift by 3 for a c-string of 5
temp = szString[size-shiftBy];//temp = myarray[2]
szString[size-shiftBy] = szString[i];//myarray[2] = myarray[i]
szString[i] = temp;//myarray[i] = temp(value previously at index 2)
}
}
}
void reverseCString(char szString[], const size_t& size){
char temp;
int i = 0;
int j = size-1;
//we can use a simple tep variable to flip everything
while(i < j)
{
temp = szString[i];
szString[i] = szString[j];
szString[j] = temp;
i++;
j--;
}
}
int main(){
string repeat = "";
string userInputString;
cout << "Please eneter your string: " << endl;
//cin >> ws;
getline(cin,userInputString);
char * szString = new char [userInputString.length()+1];
strcpy (szString, userInputString.c_str());
do {
cout << "Your c-string is: " << szString << endl;
string commandString = "";
cout << "Please enter a command: ";
getline(cin,commandString);
if (commandString[0] == 'L'){
cout << "You have chosen to shift your string left by " << commandString[1] << " characters." << endl;
const char * shiftLeftPtr = &commandString[1];
//convert this value to an int for our function
int shiftLeftBy = atoi(shiftLeftPtr);
//run our shifleft function
shiftLeft(szString,shiftLeftBy);
//print the results
cout << "Your c-string, shifted left by " << commandString[1] << endl;
cout << szString;
}
if (commandString[0] == 'R'){
cout << "You have chosen to shift your string right by " << commandString[1] << " characters." << endl;
const char * shiftRightPtr = &commandString[1];
//convert this value to an int for our function
int shiftRightBy = atoi(shiftRightPtr);
//run our shiftright function
shiftRight(szString,userInputString.length(),shiftRightBy);
//print the results
cout << "Your c-string, shifted right by " << commandString[1] << endl;
cout << szString;
}
if (commandString.compare("rev") == 0){
cout << "You have chosen to reverse your string. " << endl;
//run our reverseArray function
reverseCString(szString,userInputString.length()+1);
cout << "Your c-string, reversed: ";
for(int i = 0; i < userInputString.length()+1; i++){
///////////////////////////right her seems to be my issue
cout << szString[i];
}
}
if (!(commandString[0] == 'R' || commandString[0] == 'L' || commandString.compare("rev") == 0)){
cout << "You have entered an invalid selection." << endl;
}
cout << "\nEnter 'quit' to close the program, anything else to continue: ";
getline(cin,repeat);
}while(repeat.compare("quit") != 0);
return 0;
}

Your length logic is broken. Say the string contains "bar\0". You do this:
reverseCString(szString,userInputString.length()+1);
Now, length is 3, and you pass 4 to reverseCString. Then this happens:
void reverseCString(char szString[], const size_t& size){
char temp;
int i = 0;
int j = size-1;
Now, i is 0 and j is 3. So you swap items 0 and 3. Well, what are the items?
0 = b
1 = a
2 = r
3 = \0
When you swap items 0 and 3, you create a string that starts with a terminator, "\0rab". Of course printing that out won't produce anything.

Related

Unable to print the reverse of a user-filled partial array

For an assignment, we were to fill an array with user-defined characters that stops filling once the user enters a full stop ".". Part of the assignment is to print out the characters entered in the array in reverse, but what I have seems to just print nothing.
First time asking, so apologies if it's a silly question. Thanks in advance.
#include <iostream>
using namespace std;
//Function declarations
bool fillArray(char charArray[], int arraySize, int& numberUsed);
void outputInReverse(const char charArray[], int& numberUsed);
int main() {
const int arraySize = 100;
char charArray[arraySize] = { };
int numberUsed = 0;
//Function calls
cout << "\nFILLING ARRAY....\n";
fillArray(charArray, arraySize, numberUsed);
cout << "\nARRAY OUTPUT....\n";
outputInReverse(charArray, numberUsed);
}
//Function definitions
bool fillArray(char charArray[], int arraySize, int& numberUsed) {
char inputChar;
int index = 0;
const char sentinel = '.';
bool sentinelEntered = false;
bool arrayFull = false;
int count = 0;
//Take user input
for (int i = 0; i < arraySize; i++) {
if ((!sentinelEntered)) {
cout << "Enter up to " << arraySize << " character values. Enter full stop to end. " << "Enter char " << (i + 1) << ": " << endl;
cin >> inputChar;
charArray[index] = inputChar;
//How many entries made
numberUsed = i;
count++;
if ((inputChar == sentinel)) {
sentinelEntered = true;
cout << "Number of entries: " << (count - 1) << endl;
return count;
}
}
}
if (numberUsed == arraySize) {
arrayFull = true;
return arrayFull;
}
return sentinelEntered;
return count;
}
// Reverse
void outputInReverse(const char charArray[], int& numberUsed) {
for (int i = numberUsed; i > 0; i--) {
cout << "Output in reverse: " << charArray[i] << endl;
}
}
FILLING ARRAY....
Enter up to 100 character values. Enter full stop to end. Enter char 1:
a
Enter up to 100 character values. Enter full stop to end. Enter char 2:
b
Enter up to 100 character values. Enter full stop to end. Enter char 3:
c
Enter up to 100 character values. Enter full stop to end. Enter char 4:
d
Enter up to 100 character values. Enter full stop to end. Enter char 5:
e
Enter up to 100 character values. Enter full stop to end. Enter char 6:
.
Number of entries: 5
ARRAY OUTPUT....
Output in reverse:
Output in reverse:
Output in reverse:
Output in reverse:
Output in reverse:
Not sure what you are trying to return from fillArray(), but since its a bool type, assuming you are trying to return if the array is empty or not. Observe added comments to see corrections.
int main() {
const int arraySize = 100;
//corrected
char charArray[arraySize] = { NULL };
int numberUsed = 0;
//Function calls
cout << "\nFILLING ARRAY....\n";
fillArray(charArray, arraySize, numberUsed);
cout << "\nARRAY OUTPUT....\n";
outputInReverse(charArray, numberUsed);
return 0;
}
bool fillArray(char charArray[], int arraySize, int& numberUsed) {
char inputChar;
int index = 0;
const char sentinel = '.';
bool sentinelEntered = false;
bool arrayFull = false;
int count = 0;
//Take user input
for (int i = 0; i < arraySize; i++) {
if ((!sentinelEntered)) {
cout << "Enter up to " << arraySize << " character values. Enter full stop to
end. " << "Enter char " << (i + 1) << ": " << endl;
cin >> inputChar;
//corrected: shifted here so before '.' can enter into array we return
if ((inputChar == sentinel)) {
sentinelEntered = true;
cout << "Number of entries: " << (count) << endl;
//correction: update numberUsed before returning and no of
//elements = count
numberUsed = i;
return count;
}
//correction: array index should not be "index" but i
charArray[i] = inputChar;
//How many entries made
numberUsed = i;
count++;
}
}
if (numberUsed == arraySize)
return true;
return false;
}
void outputInReverse(const char charArray[], int& numberUsed) {
for (int i = numberUsed-1; i >= 0; i--) {
cout << "Output in reverse: " << charArray[i] << endl;
}
}

How to end a 2D char array when string is '\0'?

I have a program that queries the user for string inputs that are stored in a 2D char array. The program should stop asking for inputs when 20 strings are entered or when the user hits enter twice.
For some reason no matter what I do, the program will keep displaying all empty strings even though the user hasn't populated them. How can I stop this?
int main()
{
char sentences[20][81] = { '\0' };
cout << "Enter up to 20 sentences - when done, Press ENTER: ";
input(sentences);
for (int i = 0; i < 20; i++)
{
if (sentences[i] == '\0' || sentences[i] == "\n")
break;
else
{
cout << "\nHere is sentence " << i + 1 << ": " << endl << sentences[i] << endl;
menu(sentences[i]);
}
}
cout << "\nPress any key to continue...";
_getch();
return 0;
}
void input(char str[20][81])
{
for (int i = 0; i < 20; i++)
{
cin.getline(str[i], 81, '\n');
if (str[i][0] == '\0')
break;
}
}
There are no error messages, and I expect that the check here
if (sentences[i] == '\0' || sentences[i] == "\n"
break;
should end the program when a blank c-string is encountered, why isn't that happening?
This check here is wrong:
if (sentences[i] == '\0' || sentences[i] == "\n")
You're comparing sentences[i] (a char*) with '\0' (a char). The sentences[i] == "\n" part is entirely wrong - just get rid of that. Your check should look like this:
if (sentences[i][0] == '\0' )
But I would really recommend just using a std::vector<std::string> instead of this multidimensional c-style string construct. You can just use push_back to add a string to the vector and range-based for loop to go through the vector and print its results. You can do this with your input function like this:
void input(std::vector<std::string> &sentences)
{
for (int i = 0; i < 20; i++)
{
std::string s;
std::getline(std::cin, s);
if (s.empty())
break;
sentences.push_back(s);
}
}
And then the main function like that:
int main()
{
std::vector<std::string> sentences;
std::cout << "Enter up to 20 sentences - when done, Press ENTER: " << std::endl;
input(sentences);
for (int i = 0; i < sentences.size(); i++)
std::cout << "Here is sentence " << i + 1 << ": " << std::endl << sentences[i] << std::endl;
std::cout << "Press any key to continue...";
//getch();
return 0;
}
This way you wouldn't even need the hard-coded limit of 20 sentences, you could just remove it and have a while (true) loop instead.

Maximum number of vowels in a word in string array

I have written a program to input 2 strings in a string array.
And then print the maximum vowels stored in the list.
Where am i going wrong here,and is there a more elegant method to this.
#include<iostream.h>
#include<string.h>
int main()
int i,j,c=0,k=0,maxo=0,len1,maxo1=0,len3;
char vow[] = "AEIOUaeiou";
char list[100][100],vow[]={"AEIOUaeiou"};
for(i=0;i<2;i++) {
cout<<"Enter word: ";
gets(list[i]);
for(i=0;i<2;i++) {
len1=strlen(list[i]);
for(k=0;k<len1;k++) {
for(j=0;list[j][k]!='\0';j++)
if(list[j][k]==vow[j])
c++;
}
if(c>maxo)
maxo=c;
c=0;
}
cout<<"Maximum Vowel count:"<<maxo<<endl;
}
fflush(stdin);
getchar();
return 0;
}
The bigger programme where i am trying to incorporate this code.The necessary comments are in the code.I really cannot undertand where i am going wrong in the last part.
Should i include the last bit of code at first so that the program works?
#include<iostream.h>
#include<string.h>
int main()
{
int i,n,len=0,sum=0,j,max,min,c=0,c2=0,k=0,maxo=0,len1,maxi=0,c1=0,len2;
float avg;
char list[100][100] = { 0 };
char vow[] = "AEIOUaeiou";
for(i=0;i<2;i++)
{
cout<<"Enter word: ";
gets(list[i]);
len=strlen(list[i]);
sum=sum+len;
cout<<"Length of word: "<<len<<endl;
if(list[i][len-1]=='s')
{cout<<"The Word "<<list[i]<<" ends with s"<<endl;
c2++;
}
}
//Word input by user.Prints word along with length.
min=strlen(list[0]);
max=strlen(list[0]);
//Initialising max and min.
for(i=0;i<2;i++)
{
if(strlen(list[i])<min)
{min=strlen(list[i]);}
if(strlen(list[i])>max)
{max=strlen(list[i]);}
}
for(i=0;i<2;i++)
{
if(max==strlen(list[i]))
cout<<"The max value of the lengths stored:"<<list[i]<<endl<<"Word count:"<<max<<endl;
if(min==strlen(list[i]))
cout<<"The min value of the lengths stored:"<<list[i]<<endl<<"Word count:"<<min<<endl;
}
//Max and Min value of string lengths are printed.
avg=sum/2;
cout<<"Avg length:"<<avg<<endl;
//Average value printed.
cout<<"The number of words with s:"<<c2<<endl;
//Word ending with s.
{for (i = 0; i <2; i++)
len1 = strlen(list[i]);
for (k = 0; k < len1; k++)
{
for (j = 0; j < strlen(vow); j++)
//if (list[j][k] == vow[j])
if (list[i][k] == vow[j])
c++;
}
cout << "Number of vowels in line " << i << ": " << c << '\n';
if (c>maxo) maxo = c;
c = 0;
cout << "Maximum Vowel count so far:" << maxo << "\n\n";
cout << "Maximum Vowel count:" << maxo << endl;
}
for(i = 0 ;i < 2 ;i++)
{ len3 = strlen(list[i]);
letter = list[i][0];
{for(j=0;j<len3;j++)
if(list[i][j]==letter)
counter++;
}
cout << "Number of identical letters as first letter in line " << i << ":
" << counter << '\n';
if (c>maxo1) maxo1 = counter;
counter = 0;
cout << "Maximum letter count so far:" << maxo1 << "\n\n";
cout << "Maximum letter count:" << maxo1 << endl;
}
PS:
I have edited my code one more time to display the alphabet which has occurred the maximum number of times as starting letter of a word in the list,and the number of times it has occurred.
This won't compile for me for two reasons:
1) gets()
The most recent revision of the C standard (2011) has definitively
removed this function from its specification. The function is
deprecated in C++ (as of 2011 standard, which follows C99+TC3).
And so I can't use the gets() function.
2) You can't declare
char list[100][100], char vow[] = {"AEIOUaeiou"};
both with a comma separator.
You read the input for the first line string into the first row of the array i = 0; then you instantly loop through i, which doesn't make sense. The following is not a good solution as in C++ you should be using std::vectors and std::string, and not generally mixing C and C++ but I've tried to keep it as close to your version, using my telepathic powers to read your mind about what you're trying to do.
#include <iostream>
#include <cstring>
using namespace std;
const int numLinesToGet = 10;
const int maxCharsPerLine = 100;
int main()
{
int i, j, c = 0, k = 0, maxo = 0, len1;
//char list[100][100], char vow[] = {"AEIOUaeiou"};
char list[100][100] = { 0 };
char vow[] = "AEIOUaeiou";
//for (i = 0; i < 2; i++)
for (i = 0; i < numLinesToGet; i++)
{
cout << "Enter word: ";
std::cin.getline(list[i], maxCharsPerLine);
//gets(list[i]);
//for (i = 0; i < 2; i++) Get rid of this second loop entirely
len1 = strlen(list[i]);
for (k = 0; k < len1; k++)
{
//for (j = 0; list[j][k] != '\0'; j++)
for (j = 0; j < sizeof(vow); j++)
//if (list[j][k] == vow[j])
if (list[i][k] == vow[j])
c++;
}
cout << "Number of vowels in line " << i << ": " << c << '\n';
if (c>maxo) maxo = c;
c = 0;
cout << "Maximum Vowel count so far:" << maxo << "\n\n";
}
cout << "Maximum Vowel count:" << maxo << endl;
fflush(stdin);
getchar();
return 0;
}
Online example here
#include<stdio.h>
int main ()
{
char a[] = "i love to code in education";
int i, count = 0, vow = 0, mvow = 0;
for (i = 0; a[i] != '\0'; i++)
{
if (a[i] == 'a' || a[i] == 'e' || a[i] == 'i' || a[i] == 'o'
|| a[i] == 'u')
{
vow++;
}
if (a[i]==' ')
{
count++;
mvow = vow;
vow = 0;
}
}
printf ("Total words: %d\n", count+1);
if(vow>mvow) printf ("Max Vowels in a word: %d", vow);
else printf("Max Vowels in a word: %d", mvow);
return 0;
}

Getting errors in my char array function?

#include <iostream>
using namespace std;
const int SIZE = 20;
char correctAnswers(char [], int);
char userAnswers(char [], int);
void compareArray(char[] , char [], int [], int, int &);
int main(){
char correct[SIZE];
char userArray[SIZE];
int result[SIZE];
int element;
correctAnswers(correct, SIZE);
cout << "Please enter the student's answers for each of the questions." << endl;
cout << "Press Enter after typing each answer." << endl;
cout << "Please enter only an A, B, C, or D for each question." << endl;
userAnswers(userArray, SIZE);
compareArray(correct, userArray, result, element);
cout << "Array 1 and Array 2 are different at" << element<<" positions: " << " ";
for(int i = 0; i < element; i++)
cout << result[i] << " ";
return 0;
}
char correctAnswers(char correct[], int SIZE){
correct[SIZE] = {'B','D','A','A','A','B','B','A','C','D','B','B','D','A','D','D','A','B','D','A'};
}
char userAnswers(char userArray[], int SIZE){
userArray[SIZE];
for(int i = 0; i < 20; i++){
cout << "Question " << (i+1) << ":";
cin >> userArray[i];
while(userArray[i] != 'A' || userArray[i] != 'B' || userArray[i] != 'C' || userArray[i] != 'D'){
cout << "Invalid input. Choose A,B,C or D." << endl;
cin >> userArray[i];
}
}
}
void compareArray(char correct[], char userArray[], int result[], int &element){
int right = 0, wrong = 0;
element = 0;
for(int i = 0; i < SIZE; i++){
if(userArray[i] == correct[i]){
right = right + 1;
}
else
wrong = wrong + 1;
}
if(right >= 15){
cout << "You Passed!";
}
else
cout << "You Fail.";
cout << "Correct answers = " << right << endl;
cout << "Incorrect answers = " << wrong << endl;
for(int i = 0; i < SIZE; i++){
if(userArray[i] != correct[i]){
result[element] = i+1;
element++;
}
}
}
I'm getting 3 errors and can't figure out why. In my char correctAnswers function, I get an error saying "cannot convert from 'braced-init-list' to 'char" and that the initializer contains too many elements. Also, in my last function it tells me function does not take four elements?
correct in correctAnswer is an array of char, so correct[SIZE] is a particular element of that array (although located past the end of the array), which you are trying to assign an array of characters to.
Even if you removed [SIZE], you'd still have a problem, because you are trying to use an initializer (which, as the same suggests, is for initializing) to make an assignment.
Don't understand what you mean about the last function at all.

Invalid Arrary Assignment

im doing a project for my C++ class and I am having problems with this one particular function. I keep getting the error "invalid array assigment and I dont know why. I am just trying to swap positions into a temp variable and swap back to display this information in descending order. the array dateAdded is an array with Chars. I appreciate the help guys
void repAge(){
cout << "You selected Listing by Age" << endl;
int i;
int pos;
string temp;
bool swap;
// Look for empty row
pos = -1;
// look for an empty book row (title[i][0] == '\0')
for (i = 0; i < 20; i++) {
if (bookTitle[i][0] == '\0') {
pos = i;
break;
}
}
// Now pos is last available value.
do
{
swap = false;
for (int count = 0; count < (pos - 1); count++)
{
if (dateAdded[count] < dateAdded[count+1])
{
temp = dateAdded[count];
dateAdded[count] = dateAdded[count+1];
dateAdded[count+1] = temp;
swap = true;
}
}
} while (swap);
for (i = 0; i< pos; i++) {
while (bookTitle[i] != '\0') {
// print it out
cout << "Title: " << bookTitle[i] << endl;
cout << "ISBN: " << isbn[i] << endl;
cout << "Quantity-On-Hand: " << qtyOnHand[i] << endl;
cout << "Wholesale Cost: " << wholesale[i] << endl;
cout << endl;
break;
}
}
The exact error messages that pop up are "invalid array assignment" or "invalid conversion from char* to char".
the array is declared as dateAdded[20][11] and the lines that do not work are the these
temp= dateAdded[count];
dateAdded[count] = dateAdded[count+1];
dateAdded[count+1] = temp;
You say dateAdded is an array of chars - then, at least the following line will fail since temp is declared as string:
dateAdded[count+1] = temp;
Use something like
dateAdded[count+1] = temp[0];
Probably it is even better to declare temp as char - there is no reason to use string to temporarily store an element of a char array.