Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
Hello i'm from Indonesia. and i'm verry beginner on C++ programming. I have some problem when i learn about string on C++ . First i declared array of char and i want to initialize a value separately in different command. After i initialize the value my compiler say "Invalid Argument".
#include <iostream>
using namespace std;
int main() {
char Name[5];
Name = "Luke";
cout<<"Character 0 :"<<Name[0]<<endl;
cout<<"Character 1 :"<<Name[1]<<endl;
cout<<"Character 2 :"<<Name[2]<<endl;
cout<<"Character 3 :"<<Name[3]<<endl;
cout<<"Character 4 :"<<Name[4]<<endl;
return 0;
}
sorry if my english is bad :(
A character array(including a C string) can not have a new value assigned to it after it is declared.
The C++compiler interprets these assignment statements as attempts to change the address stored in the array name, not as attempts to change the contents of the array.
However you can use
char name[] = "Luke";
A char[] can't be assigned with a string with the = operator, except for on its initialization. That's why char Name[5]; Name = "Luke"; is invalid while char Name[5] = "Luke"; is.
Assigning strings to char[] can be done with strcpy() / memcpy()-like functions.
So you have two ways of action (assuming you want to work with char[]):
char Name[5] = "Luke";
char Name[5]; strcpy(Name, "Luke"); /* don't forget to #include <string.h>*/
Just for sake of education (since the other answers are on-point to answer the question), here's how I would have written your code to do nearly the same thing.
The changes demonstrate:
used a more appropriate container (a string instead of a char[])
checked for access overruns
moved "one unit of work" into its own subroutine
Code was compiled as C++17 with /usr/bin/clang++ -Weverything -Wno-c++98-compat --std=c++1z:
#include <cstddef>
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;
void PrintCharAtPos(string const& s, string::size_type pos);
int main() {
auto Name = string{"Luke"};
PrintCharAtPos(Name, 0);
PrintCharAtPos(Name, 1);
PrintCharAtPos(Name, 2);
PrintCharAtPos(Name, 3);
PrintCharAtPos(Name, 4);
return EXIT_SUCCESS;
}
void PrintCharAtPos(string const& s, string::size_type pos) {
if (pos < s.length())
cout << "Character " << pos << " : " << s[pos] << endl;
else
cout << "Character " << pos << " : (out of bounds)" << endl;
}
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 months ago.
Improve this question
Hi everyone I have a simple task in C++:
-> writing a program that takes a string from user input and loops over the characters in the string via a pointer.
If I understand correctly, then a previously declared string name; variable can also be accessed via const char*, implying that I can declare a pointer in the following manner: const char *pName = &(name[0]);. When printing the pointer, however, not the memory address but the actual variable is displayed in the terminal (see my code below). This prevents me from incrementing the pointer (see for loop).
Filename: countchar.cpp
#include <iostream>
using namespace std;
int main() {
string name;
std::cout << "Provide a string." << endl;
std::cin >> name;
const char *pName = &(name[0]);
cout << pName << endl;
// further downstram implementation
// int len = name.length();
// for(int ii = 0; ii < len; ii++){
// std::cout << "iteration" << ii << "address" << pName << endl;
// std::cout << "Character:" << *pName << endl;
// (pName+1);
// }
return 0;
}
Terminal output:
$ g++ countchar.cpp -o count
$ ./count
$ Provide a string.
$ Test
$ Test
As I am a quite a noob in regard to C++ help and an explanation are both highly appreciated (No material found online that solves my problem). Thanks in advance!
The operator << overloaded for a pointer of the type char * such a way that it outputs the string pointed to by the pointer.
So according to the assignment instead of these statements
const char *pName = &(name[0]);
cout << pName << endl;
you need to use a loop like
for ( const char *pName = &name[0]; *pName != '\0'; ++pName )
{
std::cout << *pName;
}
std::cout << '\n';
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 12 months ago.
Improve this question
#include <bits/stdc++.h>
using namespace std;
int main()
{
char *str;
gets(str);
int size = strlen(*(&str));
//How to iterate through this str which is acting like a string here
return 0;
}
//I'm trying to print each char in a new line.
Ignoring all the other problems, such as using an uninitialized pointer, using gets (it's so bad it's been removed from C and C++), including bits/stdc++.h, not using std::string and std::getline...
Using your size variable, you can use loop like this:
for(int index = 0 ; index < size ; ++index) {
std::cout << "character at index " << index << " is '" << str[index] << "'\n";
}
But note that your code will crash at gets and never get to this loop. Please find better learning material to get started with C++!
PS. To get your code to not crash, change char *str; to char str[10000];... Then that program should run and you are unlikely to accidentally cause a buffer overflow. Still, I repeat, get better learning material!
The character pointer str doesn't point to any char object and has not been initialized.
Second, the function gets has been deprecated in C++11 and removed in C++14.
A better way would be to use std::string instead as shown below:
#include <string>
#include <iostream>
int main()
{
std::string str;
//take input from user
std::getline(std::cin, str);
//print out the size of the input string
std::cout << str.size() << std::endl;
//iterate through the input string
for(char& element: str)
{
std::cout<<element<<std::endl;
}
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
why is casting working in the first case but not in second cout after masking one of the characters in char*
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;
int main()
{
int n = 10;
char* ch = (char*) calloc(6, sizeof(*ch));
ch = strdup("ab");
cout << strlen(ch) << endl;
int* p = (int*) ch;
cout << (char*)p << endl;// works fine it prints "ab"
*p = *p & 65280;
cout << "cast not working\t" << (char*)p << endl; // it does not work here
free(ch);
return 0;
}
Written as hex, 65280 is 0x0000FF00. So, on common systems with int being 4 bytes, you have set ch[0] to be 0. This is a null terminator, so when you try to print the string, you see an empty string.
Note: writing to *p causes undefined behaviour by writing past the end of the allocated area too; strdup("ab") allocates 3 bytes. On common systems this probably will have no ill effect as heap allocations are done in chunks of a certain size.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I want to take argv[(2 in this example)], store it into vector and use it later in program. The problem is that no operand matches those operands std::string == int. So does that mean that the app sees '-r' as int? I'm a bit confused here.
int main(int argc, char* argv[])
{
std::vector<std::string> argList;
cout<<"argc: "<<argc<<endl;
for(int i=2; i<=argc; i++)
{
argList.push_back(argv[i]);
}
if(argList.at(2) == '-r') cout<<" Good job ";
}
There are several issues with your program:
You iterate i until i == argc, that will attempt to construct a string from argv[argc], a NULL pointer due to the requirement by C and C++ standards that argv[argc] be 0 (NULL), see this SO question. argv is an array with argc pointers to null-terminated character strings (terminated by ASCII NUL, 0), the array itself is terminated with a NULL pointer (not counted in argc). Now, in C++ you can construct a string from a pointer to a null-terminated character string, but passing a NULL pointer to a string constructor results in undefined behavior, see this SO question, also see the list of std::string constructors here, you are implicitly using constructor (4) in that list (from c-string).
You start pushing onto argList with i==2, which means argList[0] will contain argv[2], you then reference argList.at(2), which would correspond to argv[4], this is not likely what you meant.
String literals use double quotes
I've corrected these and created a working program, click here
#include <iostream>
#include <vector>
#include <string>
using std::vector;
using std::string;
using std::cout;
using std::endl;
int main(int argc, char* argv[])
{
vector<string> argList;
cout << "argc: " << argc << endl;
for(int i=0; i < argc; ++i)
{
argList.push_back(argv[i]);
}
cout << "Program name is " << argList[0] << endl;
if(argc > 1) {
if(argList.at(1) == "-r") {
cout << " Good job, you supplied -r\n";
} else {
cout << "Unrecognized option " << argList[1]
<< "\nUsage: " << argList[0] << " -r\n";
}
}
return 0;
}
The problem is your use of single quotes in '-r'. You want double quotes here:
if(argList.at(2) == "-r") cout<<" Good job ";
The reason is that in C++, single quotes are used for characters only. There is such a thing as a "multi-byte character constant", which is what '-r' ends up being. This is something completely different from a string constant, which is what you want.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Is there any way to make the following piece of code shorter? Maybe there is a way to use only one sprintf command, but I don't know how. I need to avoid printing x when its value is zero.
char msg[1000];
string s1 = "s1";
string s2 = "s2";
string s3 = "s3";
int x = 0;
if(x == 0)
sprintf(msg, "%s,%s,%s \n", s1.c_str(), s2.c_str(), s3.c_str());
else
sprintf(msg, "%s,%s,%s,%d \n", s1.c_str(), s2.c_str(), s3.c_str(), x);
Since you're using C++, why not use stringstream to build your buffer in pieces:
#include <cstdio>
#include <sstream>
#include <string>
using namespace std;
int main() {
string s1 = "s1";
string s2 = "s2";
string s3 = "s3";
int x = 0;
stringstream ss;
ss << s1 << "," << s2 << "," << s3;
if (x != 0)
ss << "," << x;
ss << " " << endl;
// Don't do this! See link below
//const char* c = ss.str().c_str();
string result = ss.str();
const char* c = result.c_str();
printf("Result: '%s'\n", c);
getchar();
return 0;
}
Don't let std::stringstream.str().c_str() happen to you
Since the printf family of functions evaluate but ignore any unused arguments, this would be one option;
sprintf(msg, x == 0 ? "%s,%s,%s \n" : "%s,%s,%s,%d \n",
s1.c_str(), s2.c_str(), s3.c_str(), x);
For readability and clarity, I would personally keep your current version though. Until really proven to be a problem, readability trumps micro optimization any day.
Simple, break it out into parts:
printf("%s,%s,%s", s1.c_str(), s2.c_str(), s3.c_str()); // no newline
if(x != 0)
printf(",%d", x);
printf(" \n");
When trying to do things like this, think of it as a math problem: Factor out what's in common between the two statements and do it regardless of the if conditional.
If you want to use sprintf (since you changed your question), you'll need to adjust the pointer into the buffer that you pass each time to account for what's already been written. Also, you should use snprintf which takes a length parameter, to make sure you don't over-run your buffer. This length would need adjusted after each step as well.