I want to make a function that will do the same as Strlen does, andI get the error: "string subscript out of range". I tried fixing it but has no idea.
heres the code:
#include "stdafx.h"
#include "stdafx.h"
#include <string>
#include <sstream>
#include <iostream>
using namespace std;
int strlen1( string str)
{
int count=0;
int i=0;
while (str[i]!='\0')
{
count++;
i++;
}
return count;
}
int _tmain(int argc, _TCHAR* argv[])
{
string input;
cin >> input;
cout << strlen1(input) << endl;
return 0;
}
thanks!
In short, for a non-const std::stringaccessing an element beyond the string length has Undefined Behavior (more precisely, when using the non-const operator[] for that).
C++98 §21.3.4/1, about std::string::operator[]:
If pos < size, returns data()[pos]. Otherwise, if pos == size(), the const version returns charT(). Otherwise the behavior is undefined.
And your string is non-const.
You can make it const, which will then invoke a special provision in the standard that guarantees zero result for element n, but that does not address the problem that your function is completely redundant for std::string.
Perhaps you mean to have argument type char const*.
That would make more sense, and then also the function would work.
Cheers & hth.,
You seem to be under the misconception that std::string is the same as a C-style string (char const*). This is simply not true. There is no null terminator.
Here's your strlen function the only way it will work:
int strlen1(string str) { return static_cast<int>(str.size()); }
std::string has a nice size() method for this.
strlen is based on zero terminated strings (char*, or char arrays), C++ string are based on length + data, you can't access to data after the end of string (where a terminal zero would be). Beside that, getting the length is a standard property of C++ strings (size()), hence the standard way of writing strlen is just to call size.
Related
I am learning pointers and i tried this following program
#include <iostream>
#include <cstdlib>
#include <cstdio>
using namespace std;
char* getword()
{
char*temp=(char*)malloc(sizeof(char)*10);
cin>>temp;
return temp;
}
int main()
{
char *a;
a=getword();
cout<<a;
return 0;
}
To my level of understanding, a is a pointer to a character, and in the function getword() I returned temp which I think the base &temp[0]. I thought that the output would be the first character of the string I enter, but I got the entire string in stdout. How does this work?
In the tradition of C, a char* represents a string. Indeed, any string literal in your program (e.g. "hello") will have a type of const char *.
Thus, cout::operator<<( const char * ) is implemented as a string-output. It will output characters beginning at the address it is given, until it encounters the string terminator (otherwise known as null-terminator, or '\0').
If you want to output a single character, you need to dereference the pointer into a char type. You can choose one of the following syntaxes:
cout << *a; // Dereference the pointer
cout << a[0]; // Use array index of zero to return the value at that address
It should be noted that the code you provided isn't very C++ish. For starters, we generally don't use malloc in C++. You then leak the memory by not calling free later. The memory is uninitialised and relies on cin succeeding (which might not be the case). Also, you can only handle input strings of up to 9 characters before you will get undefined behaviour.
Perhaps you should learn about the <string> library and start using it.
It's true that char* "points to a character". But, by convention, and because with pointers there is no other way to do so, we also use it to "point to more than one character".
Since use of char* almost always means you're using a pointer to a C-style string, the C++ streams library makes this assumption for you, printing the char that your pointer points to … and the next … and the next … and the next until NULL is found. That's just the way it's been designed to work.
You can print just that character if you like by dereferencing the pointer to obtain an actual char.
std::cout is an overloaded operator and when it receives a char * as an operand then it treats it as a pointer to c style string and it will print the entire string.
If you want to print the first character of the string then use
cout << *a;
or
cout << a[0];
In your code, std::cout is an ostream and providing a char* variable as input to operator<< invokes a particular operator function overload to write characters to the ostream.
std::ostream also has a operator overload for writing a single character to itself.
I'm assuming you now know how to dereference a char* variable, but you should be using std::string instead of an unsafe char* type.
Here is the correct code
#include <stdio.h>
#include <stdlib.h>
char* getword()
{
char*temp=(char*)malloc(sizeof(char)*10);
scanf("%s",temp);
return temp;
}
int main()
{
char *a;
a = getword();
int currChar = 1;
printf("%c",*(a + currChar)); //increment currChar to get next character
return 0;
}
When we use typeid i.e typeid(variable).name()
Does it give out string as the output because if it does it could be helpful in comparisons with strings.
According to the standard, it is an implementation-defined null-terminated const char*:
18.7.1 Class type_info
....
const char* name() const noexcept;
Returns: An implementation-defined NTBS.
Remarks: The message may be a null-terminated multibyte string (17.5.2.1.4.2), suitable for conversion
and display as a wstring (21.3, 22.4.1.4)
Since the content is implementation-defined, it cannot be compared with other strings in a reliable way, unless we restrict ourselves to specific implementations.
typeid(variable).name() returns a pointer a null terminated string, which can be compared using strcmp(). However a better way to check a type of variable is
if (typeid(a) == typeid(int))
I'm getting Ss when I try this.
#include <string>
#include <typeinfo>
#include <iostream>
using namespace std;
int main(int argc, char** argv) {
string str = "string";
cout << typeid(str).name();
return 0;
}
Try it: http://cpp.sh/4lsw
/* Write a function that returns the length of a string(char *), excluding the final NULL
character.It should not use any standard - library functions.You may use arithmetic and
dereference operators, but not the indexing operator ([]) */
#include "stdafx.h"
#include<iostream>
using namespace std;
int stringLength(const char * str) {
int length = 0;
while (*(str + length) != '\0') {
++length;
cout << length;
return length;
}
int _tmain(int argc, _TCHAR* argv[]){
stringLength({ 'a', 'b', 'c', '\0' });
return 0;
}
Somehow I think I am not calling my function properly in the main function, but I am not sure how else I should do it. What is the proper way of calling a function of this type? (Sorry if this is a stupid question: I am new to C++)
Like: int l = stringLength("abc");
C constant strings are automatically zero terminated, so you don't need to specify the extra zero character.
Pass a string. For instance
int len = stringLength("abc");
FWIW, it would be idiomatic to use size_t for the return type of this function. When you try to work with other code you'll meet resistance to having used int rather than size_t.
The code in the question is also rather poorly formatted and does not compile. You omitted a closing brace. It pays to get this sort of detail just right.
this code throw me an Access violation error
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
string a;
cin >> a;
printf("%s",a.at(1));
return 0;
}
I wrote this line because this function gave me problem with a larger program and i want to figure out what the problem really is...
thanks !
The immediate problem is that "%s" requires a pointer to a C-style string as its corresponding argument. a.at(1) is a single character, not a pointer, so you have undefined behaviour when it's misinterpreted as a pointer. You want "%c" to print a character.
The more general problem is the use of non-typesafe C functions. In C++, you could use a typesafe output stream:
cout << a.at(1);
std::string at returns a char type. Using the %s format specifier for a char type will give you undefined behaviour. Boom!
Two things:
1) Check the size of the string before accessing elements using at: at(1) is accessing the second character of the string as the indexing is zero based.
2) Use the correct format specifier in printf: printf("%c", a.at(1))
at() doesn't return a string, it returns a character. %s is trying to interpret that character as a (very invalid) pointer.
Try:
printf("%c", a.at(1));
(assuming a is at least two characters long).
The printf function expect a char pointer and you give a char. The char value gets interpreted as an address and it is wrong.
If you only want to print a single char, use:
printf("%c", a.at(1))
provided your string is at least 2 characters long.
i have tested two different varianat of similary code ,suppose i have char array
char x[]="snow comes in winter ";
then following code
#include <iostream>
#include <string.h>
using namespace std;
int main(){
char x[]="snow comes in winter ";
int k=0;
int n=3;
cout<<x+n-k+1<<endl;
system("PAUSE");
return EXIT_SUCCESS;
}
prints "comes in winter "
while following
#include <iostream>
#include <string.h>
using namespace std;
int main(){
//char x[]="snow comes in winter ";
int a[]={12,3,2,4,5,6,7};
int k=0;
int n=3;
cout<<a+n-k+1<<endl;
return 0;
}
prints 0xbffd293c
if we change it a bit
#include <iostream>
#include <string.h>
using namespace std;
int main(){
//char x[]="snow comes in winter ";
int a[]={12,3,2,4,5,6,7};
int k=0;
int n=3;
cout<<*(a+n-k+1)<<endl;
return 0;
}
prints number 5.
so my question is why we can access in case of char array so easily?what is main reason of it?i am very curiousy and please could anybody explain me?
why we can access in case of char array so easily?
Because there's a convention that C strings are represented by char*, people assume char* are actually strings. The iostreams follow that and overload output for char* to print the string, whereas for an int* (in your second example), they print the representation of the address.
BTW there is a similar overload for input, which is most unfortunate, since you can't control that to prevent buffer overflows. ie. don't do this:
char x[10];
std::cin >> x;
The reasons for this go back to C.
In C, char* is typically used to represent a NUL-terminated string (as opposed to a pointer to an individual char). Therefore, functions taking char* typically treat the argument as a string. In this case the function is operator<<, and what it does is print the argument out as a string.
No such thing can be said about int*, which is just that, a pointer to an int. Here, operator<< prints out the value of the pointer (i.e. the address). It's only when you explicitly dereference the pointer that the pointed-to value gets printed.
The left shift operator for cout is overloaded to handle char pointers. Meaning, when you give it a pointer to a char, it dereferences the pointer for you and so you get the data pointed to. This does not happen in the case of an int because there is no overload, and so you must dereference the pointer yourself.
Given a variable foo of type Foo*, the expression foo+n is also of type Foo* (assuming n is an integral type).
The default std::ostream mechanism for printing a pointer is to print the pointer. There is an override specifically for const char* pointers, which is to print the (presumably) null terminated string pointed to by that pointer.
Bottom line: Pointers that are not char* will be printed as pointers. Pointers that are char* will be printed as a string.