Modifying strings in an Array of strings - c++

I have an array of strings and I would like to modify its elements at will. This is the code:
char pieces[9][4] = { " ", " o ", " a ", " ", " ", " ", " b ", " ", " " };
pieces[2] = { " x " };
As I know, the elements in pieces[] are string literal, so they can't be changed (I'm not sure why this is like this). Maybe it could be solved using std::string or vectors. However, I would like to know if this kind of operation, or very similar operations, can be done using an array of strings. Can be done something like this using just an array of strings?

In your specific situation, it looks like you always have some character surrounded by spaces, so you could simply do pieces[2][1] = 'x'; to modify that one element. However...
You are correct to assume this can be made easier with std::string and std::vector, but since we already know the size, an std::array will probably be better here:
std::array<std::string, 9> pieces = { " ", " o ", " a ", " ", " ", " ", " b ", " ", " " };
pieces[2] = " x ";
You may notice that the subscript operator still works on std::array's. This means that even if you switch to std::array's, you probably won't even have to change too much in your other code (just the parts dealing with c-strings to be dealing with std::strings)

You can use strcpy();
See following example code. See working code here:
int main(void)
{
char pieces[9][4] = { " ", " o ", " a ", " ", " ", " ", " b ", " ", " " };
printf("At point 1: %s\n",pieces[2]);
strcpy(pieces[2]," x ");
printf("At point 2: %s",pieces[2]);
return 0;
}
Output:
At point 1: a
At point 2: x

Does
pieces[2][0] = ' ';
pieces[2][1] = 'x';
pieces[2][2] = ' ';
pieces[2][3] = '\0';
do what you want?

Firstly, using curly brackets like pieces[2] = { " x " }; is the way of initialization, so you can't do that.
Secondly, pieces[2] is an char array, so it is not modifiable l-value.
You can either change its content element by element or by using strcpy() function.

Just to sumarize the different solutions given by different users, the options are:
Modify one char element at a time. Example: pieces[2][1] = 'x'
Use strcpy(). Example: strcpy(pieces[2]," x ")
Another types: std::array, std::string, std::vector

Related

C++ single quotes syntax

I am learning C++ and just started reading "Programming Principles and Practice" by Bjarne Stroustrup and he uses this code to illustrate a point:
#include "std_lib_facilities.h"
using namespace std;
int main() // C++ programs start by executing the function main
{
char c = 'x';
int i1 = c;
int i2 = 'x';
char c2 = i1;
cout << c << ' << i1 << ' << c2 << '\n';
return 0;
}
I am familiar in general with the difference between double and single quotes in the C++ world, but would someone kindly explain the construction and purpose of the section ' << i1 << '
Thanks
cout << c << ' << i1 << ' << c2 << '\n';
appears to be a typo in the book. I see it in Programming Principles and Practice Using C++ (Second Edition) Second printing. I do not see it listed in the errata.
According to the book, the intended output is
x 120 x
But what happens here is ' << i1 << ' attempts to compress the << i1 << to a multi-byte character and prints out an integer (most likely 540818464-> 0x203C3C20 -> ASCII values of ' ', '<', '<', ' ') because cout doesn't know wide characters. You'd need wcout for that. End result is output something like
x540818464x
and a warning or two from the compiler because while it's valid C++ code, it's almost certainly not what you want to be doing.
The line should most likely read
cout << c << ' ' << i1 << ' ' << c2 << '\n';
which will output the expected x 120 x
In other words, Linker3000, you are not crazy and not misunderstanding the example code.
Anyone know who I should contact to log errata or get a clarification on the off chance there is some top secret sneakiness going way over my head?
Before answering your question, here is a little background on what that is actually doing. Also note that there is a typo in the example, the string constant should have been double quoted:
cout << c << " << i1 << " << c2 << "\n";
In C++, operators can be overloaded so that they mean different things with different functions. In the case of cout, the << operator is overloaded as the "Insertion Operator". Think of it as taking the operand on the right, and inserting it (or sending it) into the operator on the left.
For example,
cout << "Hello World";
This takes the string "Hello World", and sends it to cout for processing.
So what beginners do not get is what something like this means:
cout << "Hello" << " World";
This is doing the same thing, but the operator precedence says to perform the injections from left to right. To make this work, the cout object returns itself as a function return value. Why is this important? Because the above statement is actually two separate operator evaluations:
(cout << "Hello") << " World";
This first injects "Hello" to cout, which outputs it, then continues to evaluate the next inject operator. Because cout returns itself, after the (cout << "Hello") is executed you have the following still to be evaluated:
cout << " World";
This expression injects " World" into the cout object, which then outputs " World", with the net effect being that you see "Hello World" just like the first time.
So in your example, what is it doing?
cout << c << " << i1 << " << c2 << "\n";
This is evaluated left to right as follows:
((((cout << c) << " << i1 << ") << c2) << "\n"); => Outputs value of c
((((cout ) << " << i1 << ") << c2) << "\n"); => Outputs string " << i1 << "
((( cout ) << c2) << "\n"); => Outputs value of c2
(( cout ) << "\n"); => Outputs newline character
( cout ); => No more output
Expression completes and returns the cout object as the expression value.
Assuming c='x' and c2='x', the final output from this expression is the following character string output on a single line:
x << i1 << x
For beginners, all those insertion operators << look a little strange. It is because you are dealing with objects. You could build the string up as a complete formatted object before injecting it into cout, and while that make the cout expression look simpler, we do not do that in C++ because it makes your code more complex and error prone. Note also, there is nothing special about the cout object. If you wanted to output to the standard error stream, you would use cerr instead. If you wanted to output to a file, your would instantiate a stream object that outputs to the desired file. That rest of the code in your example would be the same.
In C, the same thing would be done procedurally using a format string:
printf("%d << i1 << %d\n", i1, c2);
This is allowed in C++ too, because C++ is a superset of C. Many C++ programmers still use this output method, but that is because those programmers learned C first, and may not have fully embraced the object oriented nature of C++
Note that you may also have seen the << operator in the context of mathematical expressions like:
A = A << 8;
In this case, the << operator is the bitwise rotate operation. It has nothing to do with output to cout. It will rotate the bits in A to the left by eight bits.

Looking inside a QStringList for duplicate strings and getting a count of duplicates

Is there a way to get the amount of times a duplicate string is in a QStringList and group it with the string itself?
For example, if a list contains [" a ", " a ", " a ", "a ", " b ", " b ", " b ", " c ", " c "]
would I be able to turn it into something like
a x4
b x3
c x2
My only solution right now is to use QList::contains() and then adding them up with ints but the problem with that is there are 500 strings that can go into the QStringList so I don't want to have to create 500 strings with 500 ints.
Try this:
QMap<QString,int> countOfStrings;
QStringList listOfStrings;
listOfStrings<<"a"<<"b"<<"c"<<"a";
for(int i=0;i<listOfStrings.count();i++)
{
countOfStrings[listOfStrings[i]]++;
}
QMap defaults ints to 0.If it comes up with a string for the first time,it automatically creates an entry with (newStr,0) by invoking countOfStrings[newStr]
You can also do qDebug()<<countOfStrings;

C++ const casting

I am trying to print the value of a const but it is not working. I am making a return to C++ after years so I know casting is a possible solution but I can't get that working either.
The code is as follows:
//the number of blanks surrounding the greeting
const int pad = 0;
//the number of rows and columns to write
const int rows = pad * 2 + 3;
const string::size_type cols = greeting.size() + pad * 2 + 2;
cout << endl << "Rows : " + rows;
I am trying to print the value of 'rows' without success.
You want:
cout << endl << "Rows : " << rows;
Note this has nothing to do with const - C++ does not allow you to concatenate strings and numbers with the + operator. What you were actually doing was that mysterious thing called pointer arithmetic.
You're almost there:
cout << endl << "Rows : " << rows;
The error is because "Rows : " is a string literal, thus is a constant, and generally speaking is not modified as you may think.
Going slightly further, you likely used + (colloquially used as a concatenation operation) assuming you needed to build a string to give to the output stream. Instead operator << returns the output stream when it is done, allowing chaining.
// It is almost as if you did:
(((cout << endl) << "Rows : ") << rows)
I think you want:
std::cout << std::endl << "Rows : " << rows << std::endl;
I make this mistake all the time as I also work with java a lot.
As others have pointed out, you need
std::cout << std::endl << "Rows : " << rows << std::endl;
The reason (or one of the reasons) is that "Rows : " is a char* and the + operator for char*s doesn't concatenate strings, like the one for std::string and strings in languages like Java and Python.

Concatenation operator in C++?

I have an application in which I need to combine strings within a variable like so:
int int_arr[4];
int_arr[1] = 123;
int_arr[2] = 456;
int_arr[3] = 789;
int_arr[4] = 10;
std::string _string = "Text " + int_arr[1] + " Text " + int_arr[2] + " Text " + int_arr[3] + " Text " + int_arr[4];
It gives me the compile error
Error C2210: '+' Operator cannot add pointers" on the second string of the expression.
As far as I can tell I am combining string literals and integers, not pointers.
Is there another concatenation operator that I should be using? Or is the expression just completely wrong and should figure out another way to implement this?
BTW I am using Visual Studio 2010
Neither C nor C++ allow concatenation of const char * and int. Even C++'s std::string, doesn't concatenate integers. Use streams instead:
std::stringstream ss;
ss << "Text " << int_arr[1] << " Text " << int_arr[2] << " Text " << int_arr[3] << " Text " << int_arr[4];
std::string _string = ss.str();
You can do this in Java since it uses the toString() method automatically on each part.
If you want to do it the same way in C++, you'll have to explicitly convert those integer to strings in order for this to work.
Something like:
#include <iostream>
#include <sstream>
std::string intToStr (int i) {
std::ostringstream s;
s << i;
return s.str();
}
int main (void) {
int var = 7;
std::string s = "Var is '" + intToStr(var) + "'";
std::cout << s << std::endl;
return 0;
}
Of course, you can just use:
std::ostringstream os;
os << "Var is '" << var << "'";
std::string s = os.str();
which is a lot easier.
A string literal becomes a pointer in this context. Not a std::string. (Well, to be pedantically correct, string literals are character arrays, but the name of an array has an implicit conversion to a pointer. One predefined form of the + operator takes a pointer left-argument and an integral right argument, which is the best match, so the implicit conversion takes place here. No user-defined conversion can ever take precedence over this built-in conversion, according to the C++ overloading rules.).
You should study a good C++ book, we have a list here on SO.
A string literal is an expression returning a pointer const char*.
std::stringstream _string_stream;
_string_stream << "Text " << int_arr[1] << " Text " << int_arr[2] << " Text " << int_arr[3] << " Text " << int_arr[4];
std::string _string = _string_stream.str();

Spliting std::string and a character array into two halves (efficiently)

How can we split a std::string and a null terminated character array into two halves such that both have same length?
Please suggest an efficient method for the same.You may assume that the length of the original string/array is always an even number.
By efficiently I mean using less number of bytes in both the cases, since something using loops and buffer is not what I am looking for.
std::string s = "string_split_example";
std::string half = s.substr(0, s.length()/2);
std::string otherHalf = s.substr(s.length()/2);
cout << s.length() << " : " << s << endl;
cout << half.length() << " : " << half << endl;
cout << otherHalf .length() << " : " << otherHalf << endl;
Output:
20 : string_split_example
10 : string_spl
10 : it_example
Online Demo : http://www.ideone.com/fmYrO
You've already received a C++ answer, but here's a C answer:
int len = strlen(strA);
char *strB = malloc(len/2+1);
strncpy(strB, strA+len/2, len/2+1);
strA[len/2] = '\0';
Obviously, this uses malloc() to allocate memory for the second string, which you will have to free() at some point.