Splitting char array - c++

I have a char **names array that basically stores names from a file.
This is my .txt file
Mike, Sam, Stuart
Andre, Williams, Phillips
Patels, Khan, Smith
Basically, I want to split and store the names before the , character.
For example, Mike, Sam, Stuart will become...
newName[0] = Mike
newName[1] = Sam
newName[2] = Stuart
I have something like this...
for (int i=0; i<3; i++)
{
for (int j=60, j>0; j--)
{
if(names[i][j] == ',')
{
cout << j << endl; //THIS PRINTS OUT THE POSITION. HOW CAN I STORE THE POSITION AND DO SOMETHING?
}
}
}
I would appreciate it if someone could help me with my code, it is in the right direction. I don't want to use any vectors classes
I have attempted to store marks of these students, however I want to add it to a double *marks[2] array.
This is my .txt file...
69.9, 56.5
29.8, 20.0
35.6, 45.0
This is my code...
char **values;
char * pch;
pch = strtok (values[i], " ,");
while (pch != NULL)
{
sscanf(pch, "%f, %f", &marks[i][0], &marks[i][1]);
pch = strtok (NULL, " ,");
}
I am getting random values such as 1.28277e-307 and 1.96471e+257

look up the strtok command it will be very helpful to you.
This code looks for hyphen characters and prints stuff... change it to commas
#include <string.h>
#include <stdio.h>
int main()
{
const char str[80] = "This is - www.tutorialspoint.com - website";
const char s[2] = "-";
char * newName[100]; /* at most 100 names */
int iCurName = 0;
char *token;
/* get the first token */
token = strtok(str, s);
/* walk through other tokens */
while( token != NULL )
{
printf( " %s\n", token );
newName[iCurName] = malloc (char *) (strlen(token) + 1);
strcpy(newName[iCurName],token);
iCurrName ++;
token = strtok(NULL, s);
}
return(0);
}

Use function strtok() to split input line into tokens; use strcpy_s() to copy each token into name buffer.
Note 1: The strtok() function replaces each separator with '\0' character, so the line variable cannot be declared with const. If your input buffer must be constant, for example if you want to use the whole line for something else, make a copy of it before calling strtok() function.
Note 2: You might want to trim space in addition to splitting your input line.
#define MAX_LINE_LENGTH 80
#define MAX_NAME_LENGTH 20
#define MAX_NAMES_PER_LINE 3
const char constInput = "Mike, Sam, Stewart";
char line[MAX_LINE_LENGTH];
strcpy_s(line, MAX_LINE_LENGTH, constInput);
char *separator = ",";
char newName[MAX_NAMES_PER_LINE][MAX_NAME_LENGTH];
int i = 0;
char *token = strtok(line, separator);
while ((i < MAX_NAMES_PER_LINE) && ((token = strtok(NULL, separator)) != NULL))
{
strcpy_s(newName[i++], MAX_NAME_LENGTH, token);
}

char newName[3][60];
for (int i=0; i<3; i++){
int r=0, c=0;
for (int j=0; j<60; j++){
if(names[i][j] == ',' || names[i][j] == '\0'){
newName[r++][c] = '\0';
c = 0;
if(names[i][j] == '\0'){
cout << newName[0] << '\n'
<< newName[1] << '\n'
<< newName[2] << '\n' << endl;
break;
}
while(names[i][++j] == ' ')
;
--j;
} else {
newName[r][c++] = names[i][j];
}
}
}
#include <fstream>
#include <iostream>
using namespace std;
int main() {
ifstream inf("data.txt");
double marks[2];
char ch;
while(inf.good()){
inf >> marks[0] >> ch >> marks[1];
cout << "mark1:" << marks[0] << endl;
cout << "mark2:" << marks[1] << endl;
}
}

I don't know if this function works fast enough, but here it is:
char** split_quotes(char *input, char separator = ' ', bool keep_quotes = false)
{
if (&input && input)
{
size_t length = strlen(input);
char **chunks = new char*[length];
bool inQuotes = false;
size_t count = 0, from = 0;
for (size_t i = 0; i < length; i++)
{
if (input[i] == '"')
{
inQuotes = !inQuotes;
}
else if (input[i] == separator && !inQuotes)
{
size_t strlen = i - from;
if (strlen > 0)
{
if (!keep_quotes && input[from] == '"' && input[i - 1] == '"')
{
from++; strlen -= 2;
}
chunks[count] = new char[strlen + 1]();
strncpy(chunks[count], &input[from], strlen);
count++;
}
from = i + 1;
}
}
if (from < length)
{
size_t strlen = length - from;
if (!keep_quotes && input[from] == L'"' && input[length - 1] == L'"')
{
from++; strlen -= 2;
}
chunks[count] = new char[strlen + 1]();
strncpy(chunks[count], &input[from], strlen);
count++;
}
// Save chunks to result array //
char **result = new char*[count + 1]();
memcpy(result, chunks, sizeof(char*) * count);
// free chunks //
delete[] chunks;
return result;
}
return NULL;
}
Usage:
wchar_t **name = split_quotes(L"Mike,Donald,\"My Angel\",Anna", L',');
if (name)
{
while (*name++)
{
std::wcout << "Person: " << *name << std::endl;
}
}

Related

My Code for Erasing Empty Spaces in a Sentence in C++ has an Issue

I have made this code such that whatever I type in a sentence has the first letter of the first word capitalized; While reducing any number of spaces in a sentence to just one space. However, my sentences are only reducing by one space. For example, if I put 3 spaces in a sentence, the output has spaces reduced by 1 to 2 spaces, but I want the output of words in a sentence to have only one space. I can't quite figure out what is wrong with my code and hence any help would be greatly appreciated. I have attached my code for reference below:
#include <stdio.h>
#include <cstring>
#include <iostream>
using namespace std;
int main()
{
int i = 0; //i for counter
string str;
//String variable
getline(cin, str); //Get string from user
int L = str.length(); //Find length of string
//Display original string
for (int i = 0; i < 100; i++)
{
str[i] = tolower(str[i]);
}
str[0] = toupper(str[0]);
bool space;
for (int j = i + 1; j < L; j++)
{
str[j] = str[j + 1];
L--;
}
cout << str << endl;
return 0;
}
Or doing it in a more modern way using iterators :
#include <iostream>
#include <cctype>
int main() {
std::cout << "This is the string trimming function.\n" <<
"Throw in a string and I will make sure all extra spaces " <<
"will be reduced to single space.\n";
std::string InputString, TrimmedString;
int head = -1;
int tail = -1;
std::cout << "Please enter the input string :\n" << std::endl;
std::getline(std::cin, InputString);
for(std::string::iterator it = InputString.begin(); it <= InputString.end(); it++){
if (*it != ' ' && head < 0 && tail < 0) {
head = std::distance(InputString.begin(), it);
}
else if (head >= 0 && tail < 0 && (*it == ' ' || it == InputString.end())) {
tail = std::distance(InputString.begin(), it);
TrimmedString.append(InputString, head, (tail-head));
TrimmedString.push_back(' ');
head = -1;
tail = -1;
}
}
TrimmedString[0] = toupper(TrimmedString[0]);
std::cout << "\nThe processed string is :\n\n" << TrimmedString << std::endl;
return 0;
}
Try this:
int main()
{
std::string str;
std::getline(cin, str);
//Change case
str[0] = toupper(str[0]);
std::transform(str.begin() + 1, str.end(), str.begin() + 1, ptr_fun<int, int>(tolower));
//Parsing time
for (int i = 0; i <= str.size() - 1; i++)
{
if (str[i] == ' ' && str[i + 1] == ' ') //if present & next are whitespaces, remove next
{
str.erase(str.begin() + i);
i--; // rechecking condition
}
}
std::cout << '\n' << str << '\n';
}
Output:

Splitting char array into other arrays for using it later and ignoring numbers c++

So I have this assignment where you have to reposition letters in a char array by given number of repositions. The last letter must become first. For example:
Input: Hello 3
Output: lloHe
But if you have a sentence, you have to do it for each word seperately and, what is more, if there are numbers, you must ignore them. So I have trouble dealing with the check for numbers and dealing with seperate words(I use strtok to split them). This is what I have so far:
#include <iostream>
#include <cstring>
using namespace std;
void Reposition(char text[10000], int n, char result[10000])
{
int startIndex = strlen(text)-1;
int k = n-1;
int currentIndex = 0;
for(int i = 0; i < n; i++)
{
result[k] = text[startIndex];
k--;
startIndex--;
currentIndex++;
}
for(int i = 0; i <= startIndex; i++)
{
result[currentIndex] = text[i];
currentIndex++;
}
}
int main()
{
char text[10000];
cin.getline(text,10000);
int n;
cin >> n;
char result[10000];
char *words;
words = strtok(text, " .,");
while(words != NULL)
{
Reposition(text, n, result);
words = strtok(NULL, " .,");
}
for(unsigned i = 0; i <= strlen(result); i++)
cout << result[i];
return 0;
}
Use std::string instead of C-style string
To remove numbers from a string, use std::remove_if from <algorithm>:
std::string s;
. . .
s.erase(std::remove_if(s.begin(), s.end(), ::isdigit), s.end());
To reposition characters in a string, use std::rotate:
std::rotate(s.begin(), s.begin() + 1, s.end());
I did your homework.
Don't know if you are familiar with all this code.
I Also rewrote your reposition code. It looked very messy.....
One time favour from me. Try to learn something from this.
#include <iostream>
#include <cstring>
#include <ctype.h>
using namespace std;
void Reposition(char * text, int len, int n, char * result)
{
int k = n - 1;
for(int i = 0; i < len; i++)
{
result[i] = text[k++];
if(k == len) k = 0;
}
}
int main()
{
char text[10000];
cin.getline(text,10000);
int n;
cin >> n;
char result[10000];
char * word;
char * beginOfWord = text;
char * resultPointer = result;
int wordLen;
while(* beginOfWord)
{
// copy up to somthing from the alphabet
if(!isalpha(* beginOfWord))
{
*resultPointer++ = * beginOfWord++;
continue;
}
// Find the end of this word
word = strpbrk(beginOfWord, " .,0123456789");
if(word != NULL)
{
// len is distance between end of word and begin of word
wordLen = word - beginOfWord;
}
else
{
// Maybe it is the end of the string
wordLen = strlen(beginOfWord);
}
//reposition the word
Reposition(beginOfWord, wordLen, n, resultPointer);
// Move the pointers beyond the word
beginOfWord += wordLen;
resultPointer += wordLen;
}
//Always terminate
*resultPointer ='\x0';
cout << result;
return 0;
}
//reverse will reverse the string starting at position xn and ending at position (yn-1)
void reverse(char *str, int xn, int yn)
{
//positioning the pointers appropriately
char *start = str + xn;
char *end = str + yn - 1;
char temp;
while(start < end)
{
temp = *start;
*start = *end;
*end = temp;
++start;
--end;
}
}
//one of the logic to reposition
void reposition(char *str, int n)
{
int length = strlen(str);
n = (length > n) ? n : (n % length);
reverse(str, 0, n);
reverse(str, n, length);
reverse(str, 0, length);
}
int main()
{
char text[10000];
cin.getline(text,10000);
int n;
cin >> n;
char result[10000];
strcpy(result, text);
cout << "before: " << result << endl;
char *word;
word = strtok(text, " .,");
while(word != NULL)
{
//check if it is not a number
if(isdigit(word[0]) == 0)
{
reposition(word, n);
//find the word postion in text
int word_position = word - text;
//copy the repositioned word in result at its corresponding position.
int i = 0;
while(word[i])
{
result[word_position + i] = word[i];
++i;
}
}
word = strtok(NULL, " .,");
}
cout << "after : " << result << endl;
return 0;
}
Output:
abcd 345 pqrst 321
3
before: abcd 345 pqrst 321
after : dabc 345 stpqr 321

How can I reverse the words in a sentence without using built-in functions?

This was the interview question:
How to convert Dogs like cats to cats like Dogs ?
My code shows: cats like cats. Where am I making the mistakes?
#include <iostream>
using namespace std;
int main()
{
char sentence[] = ("dogs like cats");
cout << sentence << endl;
int len = 0;
for (int i = 0; sentence[i] != '\0'; i++)
{
len++;
}
cout << len << endl;
char reverse[len];
int k = 0;
for (int j = len - 1; j >= 0; j--)
{
reverse[k] = sentence[j];
k++;
}
cout << reverse << endl;
int words = 0;
char str[len];
for (int l = 0; reverse[l] != '\0'; l++)
{
if (reverse[l] == ' ' || reverse[l] == '\0') // not sure about this part
{
for (int m = l; m >= 0; m--)
{
str[words] = reverse[m];
words++;
}
}
}
cout << str;
return 0;
}
I know you can do this using pointers, stack, vectors... but interviewer was not interested in that!
This is a fixed version of your sample code:
Your principal problem is that every time you found and ' ' or '\0' you copy the bytes of the reverse string from the beginning to that point. Example in loop 5 you copy from index 0-5 (stac) from reverse to str in reverse order, but in in loop 10 you copy from index 0-10 (stac ekil) from reverse to str in reverse order, until here you have already the printed result string ('cats like cats'), and the same in loop 15 all of this incrementing the index of str, in the last loop you are written pass the end of the valid memory of str (and because of that not printed as output).
You need to keep track when end the last word reversed to reverse only the actual word, and not the string from the beginning to the actual index.
You don't want to count the special character (' ' and '\0') in the reversing of the words, you would end with cats like\0dogs
Modified sample code provided:
#include <iostream>
using namespace std;
int main() {
char sentence[] = ("dogs like cats");
cout << sentence << endl;
int len = 0;
for (int i = 0; sentence[i] != '\0'; i++) {
len++;
}
cout << len << endl;
char reverse[len];
int k = 0;
for (int j = len - 1; j >= 0; j--) {
reverse[k] = sentence[j];
k++;
}
cout << reverse << endl;
int words = 0;
char str[len];
// change here added last_l to track the end of the last word reversed, moved
// the check of the end condition to the end of loop body for handling the \0
// case
for (int l = 0, last_l = 0; ; l++) {
if (reverse[l] == ' ' || reverse[l] == '\0')
{
for (int m = l - 1; m >= last_l; m--) { // change here, using last_t to
str[words] = reverse[m]; // only reverse the last word
words++; // without the split character
}
last_l = l + 1; // update the end of the last
// word reversed
str[words] = reverse[l]; // copy the split character
words++;
}
if (reverse[l] == '\0') // break the loop
break;
}
cout << str << endl;
return 0;
}
Some code, written with the restriction of using the most simple features of the language.
#include <iostream>
// reverse any block of text.
void reverse(char* left, char* right) {
while (left < right) {
char tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
}
int main() {
char sentence[] = "dogs like cats";
std::cout << sentence << std::endl;
// The same length calculation as sample code.
int len = 0;
for (int i = 0; sentence[i] != '\0'; i++) {
len++;
}
std::cout << len << std::endl;
// reverse all the text (ex: 'stac ekil sgod')
reverse(sentence, sentence + len - 1);
// reverse word by word.
char* end = sentence;
char* begin = sentence;
while (end < sentence + len) {
if (*end != ' ')
end++;
if (end == sentence + len || *end == ' ') {
reverse(begin, end - 1);
begin = end + 1;
end = begin;
}
}
std::cout << sentence << std::endl;
return 0;
}
Dissecting your algorithm in pieces. First, you find the length of the string, not including the null char terminator. This is correct, though could be simplified.
size_t len = 0;
for (int i = 0; sentence[i] != '\0'; i++) {
len++;
}
cout << len << endl;
This could easily be written simply as:
size_t len = 0;
while (sentence[len])
++len;
Next, you reverse the entire string, but the first defect surfaces. The VLA (variable length array) you declare here, (which you don't need and shouldn't use, as it is a C++ extension and non-standard) does not account for, nor set, a terminating null-char.
char reverse[len]; // !! should be len+1
int k = 0;
for (int j = len - 1; j >= 0; j--) {
reverse[k] = sentence[j];
k++;
}
// !! Should have reverse[k] = 0; here.
cout << reverse << endl; // !! Undefined-behavior. no terminator.
This temporary buffer string is not needed at all. There is no reason you can't do this entire operation in-place. Once we calculate len correctly, you simply do something like the following to reverse the entire sequence, which retains the null char terminator in proper position:
// reverse entire sequence
int i = 0, j = len;
while (i < j--)
{
char c = sentence[i];
sentence[i++] = sentence[j];
sentence[j] = c;
}
Next we move to where you try to reverse each internal word. Again, just as before, the buffer length is not correct. It should be len+1. Worse (hard to imagine), you never remember where you left off when finding the end point of a word. That location should be the next point you start checking for, and skipping, whitespace. Without retaining that you copy from current point all the way back to the beginning of the string. which essentially blasts cats over dogs.
int words = 0;
char str[len]; // !! should be len+1
for (int l = 0; reverse[l] != '\0'; l++)
{
if (reverse[l] == ' ' || reverse[l] == '\0') // not sure about this part
{
for (int m = l; m >= 0; m--) {
str[words] = reverse[m];
words++;
}
}
}
cout << str; //!! Undefined behavior. non-terminated string.
Once again, this can be done in-place without difficulty at all. One such algorithm looks like this (and notice the loop that reverses the actual word is not-coincidentally the same algorithm as reversing our entire buffer):
// walk again, reversing each word.
i = 0;
while (sentence[i])
{
// skip ws; root 'i' at beginning of word
while (sentence[i] == ' ') // or use std::isspace(sentence[i])
++i;
// skip until ws or eos; root 'j' at one-past end of word
j = i;
while (sentence[j] && sentence[j] != ' ') // or use !std::isspace(sentence[j])
++j;
// remember the last position
size_t last = j;
// same reversal algorithm we had before
while (i < j--)
{
char c = sentence[i];
sentence[i++] = sentence[j];
sentence[j] = c;
}
// start at the termination point where we last stopped
i = last;
}
Putting It All Together
Though considerably simpler to use pointers than all these index variables, the following will do what you're attempting, in place.
#include <iostream>
int main()
{
char s[] = "dogs like cats";
std::cout << s << '\n';
size_t len = 0, i, j;
while (s[len])
++len;
// reverse entire sequence
i = 0, j = len;
while (i < j--)
{
char c = s[i]; // or use std::swap
s[i++] = s[j];
s[j] = c;
}
// walk again, reversing each word.
i = 0;
while (s[i])
{
// skip ws; root 'i' at beginning of word
while (s[i] == ' ') // or use std::isspace
++i;
// skip until ws or eos; root 'j' at one-past end of word
j = i;
while (s[j] && s[j] != ' ') // or use !std::isspace
++j;
// remember the last position
size_t last = j;
while (i < j--)
{
char c = s[i]; // or use std::swap
s[i++] = s[j];
s[j] = c;
}
// start at last-left posiion
i = last;
}
std::cout << s << '\n';
return 0;
}
Output
dogs like cats
cats like dogs
My advise would be to break up the original string into an array of words, reverse that array. Then add those words to your reversed sentence with a space in between.
Since they asked for no libraries, I assumed no std::string, no vectors, nothing at all and so I wrote it in C.. the only thing used is printf. Everything else is from scratch :l
The idea is that you reverse the array first. Then split the array by space and reverse each word.
Example: http://ideone.com/io6Bh9
Code:
#include <stdio.h>
int strlen(const char* s)
{
int l = 0;
while (*s++) ++l;
return l;
}
void reverse(char* str)
{
int i = 0, j = strlen(str) - 1;
for(; i < j; ++i, --j)
{
str[i] ^= str[j];
str[j] ^= str[i];
str[i] ^= str[j];
}
}
void nulltok(char* str, char tok, int* parts)
{
int i = 0, len = strlen(str);
*parts = 1;
for (; i < len; ++i)
{
if (str[i] == tok)
{
str[i] = '\0';
++(*parts);
}
}
}
char* reverse_sentence(char* str)
{
char* tmp = str;
reverse(str);
int i = 0, parts = 0, len = strlen(str);
nulltok(str, 0x20, &parts);
while(parts--)
{
reverse(str);
str += strlen(str) + 1;
}
for(; i < len; ++i)
if (tmp[i] == '\0')
tmp[i] = 0x20;
return tmp;
}
int main(void)
{
char str[] = "dogs like cats";
printf("%s", reverse_sentence(str));
return 0;
}
My solution
#include<iostream>
#include<string.h>
using namespace std;
int main()
{
string str;
cout<<"enter the sentence"<<endl;
getline(cin,str);
char* pch;
pch = strtok((char*)str.c_str()," ");
string rev = "";
while(NULL != pch)
{
rev.insert(0,pch);
rev.insert(0," ");
pch = strtok(NULL," ");
}
cout<<"the reversed string is :"<<rev<<endl;
return 0;
}

Convert to Pig Latin

Need some help with converting string to PigLatin. Write a program that inputs two string variables, first and last, each of which the user should enter with his or her name. First, convert both strings to all uppercase. Your program should then create a new string that contains the full name in pig latin.
Here is my main func:
char* first = new char[MAX];
char* last = new char[MAX];
char* full = new char[MAX*2];
cout << "Enter first name: ";
cin.getline(first, MAX, '\n');
cout << "Enter last name: ";
cin.getline(last, MAX, '\n');
for(int i = 0; first[i]; i++)
{
first[i] = toupper(first[i]);
}
for(int i = 0; last[i]; i++)
{
last[i] = toupper(last[i]);
}
transformPigLatin(first);
transformPigLatin(last);
int offset = 0;
int i;
for (i=0; i<MAX && first[i]!=0; i++)
full[offset++]=first[i];
full[offset++]=' ';
for (i=0; i<MAX && last[i]!=0; i++)
full[offset++]=last[i];
transformPigLatin(full);
cout << full << endl;
And piglatin func (need help only with this function):
char* transformPigLatin(char* word)
{
int length = strlen(word);
char ch;
for (int i = 0; i < length; i++){
if((length > 1) && (ch == 'a' || ch == 'A' ||ch =='e'||ch =='E'||ch =='i'||ch == 'I'||ch =='o'||ch =='O'||ch =='u'||ch =='U'))
{
strcat(word, "WAY");
}
else
{
strcat(word, "AY");
}
return word;
}
}
These are two things I can't figure out how to do with c-string:
1)If the first letter is a consonant, move it to the end and add “ay” to the end.
2)If the first letter is a vowel, add “way” to the end.
Any tips will be appreciated. Thanks
You are coding in C++, so you should use C++ strings rather than C strings. Things are much easier with C++ strings. The std::string class has many methods for manipulating the string content, including erase() and append().
Try this:
#include <string>
#include <algorithm>
std::string first;
std::string last;
std::string full;
std::cout << "Enter first name: ";
std::getline(std::cin, first);
std::cout << "Enter last name: ";
std::getline(std::cin, last);
std::transform(first.begin(), first.end(), first.begin(), ::toupper);
std::transform(last.begin(), last.end(), last.begin(), ::toupper);
transformPigLatin(first);
transformPigLatin(last);
full = first + " " + last;
std::cout << full << std::endl;
void transformPigLatin(std::string &word)
{
if (word.empty()) return;
char ch = word[0];
if ((ch < 'A') || (ch > 'Z')) return;
if (std::string("AEIOU").find(ch) != std::string::npos)
{
word += "WAY";
}
else
{
if (word.length() > 1)
{
word.erase(0, 1);
word.append(&ch, 1);
}
word += "AY";
}
}
Update: if you must stick with C strings only, then try something more like this:
int getLine(char *prompt, char *word, int maxlen)
{
if (prompt != NULL)
{
printf("%s", prompt);
fflush(stdout);
}
if (fgets(word, maxlen, stdin) == NULL)
{
*word = '\0';
return 0;
}
int length = strlen(word);
if (word[length-1] == '\n')
{
word[length-1] = '\0';
--length;
}
else
{
int ch;
while (((ch = getchar()) != '\n') && (ch != EOF));
}
return length;
}
char* first = new char[MAX];
char* last = new char[MAX];
char* full = new char[(MAX*2)+1];
getLine("Enter first name: ", first, MAX);
getLine("Enter last name: ", last, MAX);
for(int i = 0; first[i]; i++)
{
first[i] = toupper(first[i]);
}
for(int i = 0; last[i]; i++)
{
last[i] = toupper(last[i]);
}
transformPigLatin(first);
transformPigLatin(last);
strcpy(full, first);
strcat(full, " ");
strcat(full, last);
printf("%s\n", full);
void transformPigLatin(char* word)
{
int length = strlen(word);
if (length == 0) return;
char ch = word[0];
if ((ch < 'A') || (ch > 'Z')) return;
if (strchr("AEIOU", ch) != NULL)
{
if ((length+3) >= MAX) return;
strcat(word, "WAY");
}
else
{
if ((length+2) >= MAX) return;
if (length > 1)
{
for (int i = 1; i < length; ++i)
word[i-1] = word[i];
word[length-1] = ch;
}
strcat(word, "AY");
}
}

Strange behavior with getline C++

I am writing a simple program, where all the 'spaces' will be replaced by '%20'.
#include <iostream>
#include <string>
using namespace std;
int main (int argc, char* argv[]){
string input;
cout << "please enter the string where spaces will be replaced by '%20'" << endl;
getline(cin, input);
//count the number of spaces
int countSpaces = 0;
for (int i = 0 ; i < input.length() ; i++){
if (input[i] == ' '){
countSpaces++;
}
}
int size = input.length() + (2 * countSpaces) + 1;
//char cstr1[size];
char *cstr1 = new char[size];
char *cstr = cstr1;
for (int i = 0 ; i < input.length() ; i++){
if(input[i] == ' '){
*cstr++ = '%';
*cstr++ = '2';
*cstr++ = '0';
}
else{
*cstr++ = input[i];
}
}
*cstr == '\0';
cout << cstr1 << endl;
delete[] cstr1;
return 0;
}
I get the following strange behavior:
With the test input "this is strange " I get "this%20is%20strange%20%20his is" , where I just expect "this%20is%20strange%20%20"
If I hard code the same string, I get the correct results.
Replacing char *cstr1 = new char[size]; with char cstr1[size]; & removing the delete[] while still fetching the input via getline also removes the error.
I am using i686-apple-darwin10-g++-4.2.1:
Any help is much appreciated.
The last line must be *cstr = '\0'; not ==
Change the *cstr == '\0'; in the end of your code to *cstr = '\0';
Violà!
*cstr == '\0';
this line checks if *cstr is equal to '\0' or not and return 1 or 0 accordingly
that is wrong as you want to insert the \0 character at the end of the string
so write single = instead of double =