Here is the assignment:
Create a Cstring variable that contains a name, age, and title. Each field
is separated by a space. For example, the string might contain “Bob 45
Programmer” or any other name/age/title in the same format. Write a program using only
functions from cstring (not the class string ) that can extract the name,
age, and title into separate variables.
I extracted the name from the string, but I'm having trouble with getting any character after that. I can't use pointers because we haven't learned that yet so no strtok. I just need a direction to go because I am sure there is a function to make this easier. Thank you.
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char y[] = "taylor 32 dentist";
char name[25];
char age[4];
char title[40];
int i = 0;
while (y[i] != ' ')
{
while (y[i] != '\0')
{
if (y[i] == ' ' || y[i + 1] == '\0')
{
break;
}
name[i] = y[i];
i++;
}
}
cout << "Name: " << name << endl
<< "Age: " << age << endl
<< "Title: " << title << endl;
return 0;
}
Solved:
#include <iostream>
#include <cstring>
using namespace std;
void separate_Variables(char y[], char name[], char age[], char title[]);
void output(char name[], char age[], char title[]);
int main()
{
char y[] = "taylor 32 dentist";
char name[25];
char age[4];
char title[40];
separate_Variables(y, name, age, title);
output(name, age, title);
return 0;
}
void separate_Variables(char y[], char name[], char age[], char title[])
{
int i = 0;
int j = 0;
while (y[i] != '\0' && y[i] != ' ') {
name[j++] = y[i++];
}
name[j] = '\0';
j = 0;
i++;
while (y[i] != '\0' && y[i] != ' ') {
age[j++] = y[i++];
}
age[j] = '\0';
j = 0;
i++;
while (y[i] != '\0' && y[i] != ' ') {
title[j++] = y[i++];
}
title[j] = '\0';
j = 0;
}
void output(char name[], char age[], char title[])
{
cout << "Name: " << name << endl
<< "Age: " << age << endl
<< "Title: " << title << endl;
}
You do not need nested loops - all you need is three loops one after the other.
The loops would look the same: take i-th character, compare it to space, and store in one of three destinations. When you see space, replace it with '\0', and move on to the next destination:
int j = 0;
while (y[i] != '\0' && y[i] != ' ') {
name[j++] = y[i++];
}
name[j] = '\0'; // Add null terminator
j = 0; // Reset j for the next destination
i++; // Move to the next character in y[]
... // Do the same thing for age and title
The outer loop needs to be testing for '\0'
The inner loop (now != ' ') can be duplicated for each field. You need a separate index variable to separate i for y and where to put it for field (fi?)
Related
Create a program titled str_compress.cpp. This program will take a sentence input and remove all spaces from the sentence. (A good first step in encryption programs) Make sure that both the input and output strings are all stored in a single variable each. Do not use numbers or symbols. Include both upper-case and lower-case letters. Account for cases with multiple spaces anywhere.
This is what I have so far:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int i = 0, j = 0, len;
string str;
cout << "Enter string: ";
getline(cin, str);
len = str.length();
for (i = 0; i < len; i++)
{
if (str[i] == ' ')
{
for (j = i; j < len; j++)
{
str[j] = str[j + 1];
}
len--;
}
}
cout << str << endl;
system("pause");
return 0;
}
I can eliminate spaces, but only one at a time. If I copy and paste the for loop, I can remove all spaces for how many loops there are. I'm thinking that I can loop the for loop over and over until all spaces are gone, but I'm not sure how to do that. Also, I can't use anything like remove_all() or erase().
This is a strong clue for how the authors of your exercise want you to write your code:
Make sure that both the input and output strings are all stored in a single variable each
You should make a new string:
string new_str;
Use your loop over the input string. For each char in the string, check whether it is a space. If yes, do nothing. If no, append it to the output string:
for (i = ...)
{
char c = str[i];
if (c != ' ')
new_str.push_back(c);
}
Your loop's logic when removing a space is wrong. For instance, after removing a space, you then skip the next char in the string, which may be another space. Also, although you are decrementing the len, you don't resize the string to the new len before printing the new str value.
It should look more like this:
#include <iostream>
#include <string>
using namespace std;
int main()
{
size_t i, j, len;
string str;
cout << "Enter string: ";
getline(cin, str);
len = str.length();
i = 0;
while (i < len)
{
if (str[i] == ' ')
{
for (j = i + 1; j < len; ++j)
{
str[j - 1] = str[j];
}
--len;
}
else
++i;
}
str.resize(len);
cout << str << endl;
/* or, if you are not allowed to use resize():
cout.write(str.c_str(), len);
cout << endl;
*/
/* or, if you are not allowed to use write():
if (len < str.length())
str[len] = '\0';
cout << str.c_str() << endl;
*/
system("pause");
return 0;
}
Live Demo
However, your instructions do say to "Make sure that both the input and output strings are all stored in a single variable each", which implies that separate std::string variables should be used for input and output, eg:
#include <iostream>
#include <string>
using namespace std;
int main()
{
size_t i, j, len;
string str, str2;
cout << "Enter string: ";
getline(cin, str);
str2 = str;
len = str2.length();
i = 0;
while (i < len)
{
if (str2[i] == ' ')
{
for (j = i + 1; j < len; ++j)
{
str2[j - 1] = str2[j];
}
--len;
}
else
++i;
}
str2.resize(len);
cout << str2 << endl;
/* or:
cout.write(str2.c_str(), len);
cout << endl;
*/
/* or:
if (len < str2.length())
str2[len] = '\0';
cout << str2.c_str() << endl;
*/
system("pause");
return 0;
}
Live Demo
Alternatively:
#include <iostream>
#include <string>
using namespace std;
int main()
{
size_t i, j, len;
string str, str2;
cout << "Enter string: ";
getline(cin, str);
len = str.length();
str2.reserve(len);
for(i = 0; i < len; ++i)
{
char ch = str[i];
if (ch != ' ')
str2 += ch;
}
cout << str2 << endl;
system("pause");
return 0;
}
Live Demo
This is what worked for me. Thank you everyone for the help!!
int main()
{
int i, j, len;
string str, str2;
cout << "Enter string: ";
getline(cin, str);
len = str.length();
for (i = 0; i < len; ++i)
{
char ch = str[i];
if (ch != ' ')
str2 += ch;
}
cout << str2 << endl;
system("pause");
return 0;
}
I have a string that contains X words (between each word there is a space) I have to move the words in a circular motion to the left according to the number that the user inserts. For example:
"hi my name is aviv and",
the user entered 2. "name is aviv and hi my" I'm looking for legality that repeats itself but I can not find.
Thanks for the guidance. Most importantly, I can not use built-in libraries
Update:
I see there are examples with libraries, I can not use any library.
So what I've done so far.
I wrote a function that gets a string and a number from the user, to move left.
Before sending the string to the function I try to calculate the number of characters I need to move.
My output is - "name is avivhi my"
Regarding the function:
When it gets a string without spaces it works great.
This is my code:
int main()
{
char str[] = "hi my name is aviv";
char str2[] = "hi my name is aviv";
int CountSpace = 0, CountWord = 0;
int Size = 18, flag = 0;
int MoveLeft, Index = 0;
for (int i = 0; str[i] != '\0'; i++)
{
if (str[i] == ' ')
{
CountSpace++;
}
}
CountWord = CountSpace + 1;//Understand how many words there are in a string.
cin >> MoveLeft;
if (MoveLeft >= CountWord)//
{
MoveLeft = (MoveLeft - ((MoveLeft / CountWord) * CountWord));//the size of movment;//To reduce the amount of moves if there is such a possibility
}
for (int i = Size - 1; i >= 0; i--)
{
if (str[i] == ' ')
{
flag++;
}
if (flag == MoveLeft)
{
Index = Size - 1 - (i + 1);//That's the amount of characters I have to move
break;
}
}
MoveLeft = Index;
//This code belongs to the function that accepts a string and the amount to move the characters
for (int i = 0; i < Size; i++)
{
if (i + MoveLeft < Size)
{
str[i] = str2[i + MoveLeft];
}
else
{
str[i] = str2[(i + MoveLeft) - Size];
}
}
cout << "Move Left: " << MoveLeft << endl << str << endl << str2 << endl;
return 0;
}
Here's a hint:
vector<string> words = Your_Code_To_Split_Input_Into_Words();
int count = words.size();
int shift = Your_Code_To_Read_Users_Input();
// print the sentence with the rotation specified by shift
for (int i = 0; i < count; i++)
{
int shifted_index = (i + shift) % count; // modulo math implements circular rotation
string spacing = (i == 0) ? "" : " "; // add a space before each word, except first word
cout << spacing << words[shifted_index];
}
cout << endl;
One possible answer, i highly recommend using vectors instead of regular arrays, it's easy and more dynamic, but i didn't use it because you said you can't use built-in libraries.
#include <iostream>
#include<string>
using namespace std;
int main() {
string a[10000];
int counter = 0;
string b = "hi my name is aviv and";
string temp = "";
int userNum = 2;
for(int i=0;i<b.length() ; i++){
if(b[i]!=' '){
temp+=b[i];
}
else if(b[i]==' ' && temp.length()){
a[counter]= temp;
temp = "";
counter++;
}
}
if(temp.length()){
a[counter] = temp;
}
for(int i=userNum;i<=counter+userNum;i++){
cout<<a[i%(counter+1)]<<endl;
}
}
If you can make use of std::rotate() from <algorithm>, this is much easy to do with that. Parse the words using std::stringstream and store to std::vector. Then apply the shif directly to the vector.
Sample Output: https://www.ideone.com/rSPhPR
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <sstream>
int main()
{
std::vector<std::string> vec;
std::string str = "hi my name is aviv and";
std::string word;
std::stringstream sstr(str);
while(std::getline(sstr, word,' '))
vec.emplace_back(word);
int shift;
std::cout << "Enter the Shift: ";
std::cin >> shift;
std::rotate(vec.begin(), vec.begin() + shift, vec.end());
for(const auto& it: vec)
std::cout << it << " ";
return 0;
}
Here's a snippet :
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
#define MaxWords 10
int main()
{
stringstream ss;
ss.str("hi my name is aviv and");
string str[MaxWords];
int i;
for (i =0; std::getline(ss, str[i],' ');i++ )
{
cout << str[i] << " ";
}
int n;
cout << "\nEnter pos to split : ";
cin >> n;
for (int j = n; j <= i; j++)
{
cout << str[j] << " ";
}
for (int j = 0; j < n; j++)
{
cout << str[j] << " ";
}
cout << endl;
return 0;
}
Output:
i need a little help with this problem,
How do you break a char array like this "char* text" into individual words based on specific delimiters and save them in the form "char* text[]" without using the strtok function or any libraries besides "iostream".
In a normal situation i would use strings instead of char arrays and the strtok function, but in this situation, i am simply not allowed to.
Thanks,
Update:
i have included what i have attempted
#include <iostream>
#include <fstream>
//#define MAX_CHARS_PER_LINE = 512;
//#define MAX_TOKENS_PER_LINE = 5;
using namespace std;
char stringToken(char* input_string);
int main(int argc, char* argv[])
{
char input_string[512];
ifstream infile;
infile.open(argv[1]);
while(!infile.eof())
{
infile.getline(input_string, 512);
cout << "Main line: " << input_string << endl;
stringToken(input_string);
}
infile.close();
return 0;
}
char stringToken(char* input_string)
{
//char* word;
//cout << "String token function: " << input_string << endl;
/*while(input_string >> word)
{
cout << word << endl;
}*/
char *tempone;
char *temptwo[5];
int ii=0,
jj=0;
while(input_string[ii] != '\0' && jj<5)
{
if((int)input_string[ii]!= 32 && (int)input_string[ii]!= 9 && (int)input_string[ii] != 44)
{
tempone[ii]=input_string[ii];
//cout << "\n\nindiv char" << input_string[ii] << "\t\t" << (int)input_string[ii] << "\n\n";
}
else
{
temptwo[jj]=tempone;
jj++;
//testing
cout << temptwo << endl;
}
ii++;
}
return 0;
}
Here a pseudo code
words split(line, delims)
{
nb_words = cound_words(line);
words = allocate_words(nb_words + 1); // words is a array of pointer
i = 0
j = 0
while true
{
while line[i] in delims // we transform every delims into a end string
{
line[i] = end_string
i++
}
if line[i] not end_string
{
words[j] = line + i // we stock the address of line[i]
j++
while line[i] not in delims and line[i] not end_string
{
i++
}
}
else
{
words[j] = NULL // we end the array by NULL pointer
return words
}
}
}
count_word use a similar loop. I let you find it. The purpose of this algorithm is to transform the line into multiple word. So line must life as long that you use words.
I've tried so many times in different way to concatenate two strings, one way gives me segment fail,and the other way don't give me error but not it's making the correct function of concatenate. I need result is like this aa, what am I doing wrong?
#include <iostream>
using namespace std;
char str1[20], str2[20], str3[20];
void stringConcat(char[], char[], char[]);
void stringConcat(char str1[], char str2[], char str3[])
{
int i = 0, j = 0;
if (str1[i] != '\0') {
str3[i] = str1[i];
i++;
}
if (str2[j] != '\0') {
str3[i + j] = str2[j];
j++;
}
str3[i] = '\0';
}
int main()
{
int compare;
cout << "First string" << endl;
cin >> str1;
cout << "Second string" << endl;
cin >> str2;
stringConcat(str1, str2, str3);
cout << "result: " << str3 << endl;
return 0;
}
Why the example code below can run fine on Visual Studio. In Eclipse, NetBean or CodeBlock the code can run but can't show the Result? Thanks All.
Ex: input one string.
a/ Uppercase first letter.
b/ Remove spaces inside the string.
#include "iostream"
#include "string.h"
using namespace std;
#define MAX 255
//uppercase first letter
char* Upper(char* input)
{
char* output = new char[MAX];
bool isSpace = false;
for (int i = 0; i < strlen(input); i++)
{
output[i] = input[i];
if (isSpace)
{
output[i] = toupper(output[i]);
isSpace = false;
}
if (output[i] == ' ') isSpace = true;
}
output[strlen(input)] = '\0'; // end of the string
output[0] = toupper(output[0]); // first character to upper
return output;
}
//remove space inside the string
char* RemoveSpaceInside(char* input)
{
char* output = new char[MAX];
strcpy(output, input);
int countWhiteSpace = 0;
for (int i = 0; i < strlen(output); i++)
{
if (output[i] == ' ')
{
for (int j = i; j < strlen(output) - 1; j++) // move before
{
output[j] = output[j + 1];
}
countWhiteSpace++;
}
}
output[strlen(output) - countWhiteSpace] = '\0'; // end of the string
return output;
}
int main()
{
char* name = new char[MAX];
cout << "Enter name: "; cin.getline(name, strlen(name));
cout << "Your name: " << name << endl;
cout << "\n******* Q.A *******\n";
char* qa = Format2VN(name);
cout << qa << endl;
cout << "\n******* Q.B *******\n";
char* qb = RemoveSpaceInside(name);
cout << qb << endl;
return 0;
}
char* name = new char[MAX];
cout << "Enter name: ";
cin.getline(name, strlen(name));
Calling strlen(name) will invoke undefined behavior, because you haven't initialized the array. Poor strlen will try to find the NUL character in an uninitialized byte mess. Definitely not a good idea.
What you probably want is:
cin.getline(name, MAX); // not sure if MAX or MAX-1 or whatever
In general, do yourself a favor and replace char* with std::string. Also, get a good C++ book.
Here is how your example would look like in actual C++:
#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>
std::string upper_first_letter(std::string s)
{
if (!s.empty()) s[0] = toupper(s[0]);
return s;
}
std::string remove_spaces(std::string s)
{
s.erase(std::remove_if(s.begin(), s.end(), isspace), s.end());
return s;
}
int main()
{
std::string name;
std::cout << "Enter name: ";
std::getline(std::cin, name);
std::cout << name << '\n';
std::cout << upper_first_letter(name) << '\n';
std::cout << remove_spaces(name) << '\n';
}