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.
Related
#include <iostream>
using namespace std;
int main() {
int * a[5];
char * b[5];
cout<<a[1]; // this works and prints address being held by second element in the array
cout<<b[1]; // this gives run time error . why ?
return 0;
}
Can anyone please explain to me cout<<b[1] gives run-time error ?
Shouldn't both int and char array behave similar to each other ?
Because IOStreams are designed to treat char* specially.
char* usually points to a C-string, so IOStreams will just assume that they do and dereference them.
Yours don't.
As others have said, iostream formatted output operators consider char* to point to C-style string and attempt to access this string.
What others have not said so far, is that if you are interested in the pointer, you need to cast the pointer in question to void*. For example:
std::cout << static_cast<const void*>(buf[1]);
An output stream such as cout gives special consideration to char * that it does not give to other pointers. For pointers other than char *, it will simply print out the value of the pointer as a hexadecimal address. But for char *, it will try to print out the C-style (i.e. null terminated array of char) string referred to by the char *. Therefore it will try to dereference the char pointer, as #AlexD points in the comment to your post.
C++ (inheriting it from C) treats character pointers specially. When you try to print a[1] of type int* the address is printed. But when you try to print b[1] of type char* the iostream library - following the rest of the language - assumes that the pointer points to the first character of zero-terminated string of characters. Both your output statements are initialised behaviour, but in the case of char* crash is much more likely because the pointer is dereferenced.
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;
}
I cannot understand the unusual behavior of this code output.
It prints:
hellooo
monusonuka
Code is here:
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
printf(" hellooo \n");
char name[7]="sonuka";
char name1[4]={'m','o','n','u'};
printf("%s",name1);
system("pause");
return 0;
}
Your name1 array is not terminated with a zero character ('\0'). The printf function prints characters until it finds a zero. In your case it goes past the end of the array. What happens is undefined behaviour. A likely outcome is that other variables or garbage is printed to the screen until eventually a \0 somewhere else in memory is hit, but anything could happen including your program crashing.
name1 must be NULL-terminated, otherwise printf will print as many bytes, as it find, till hitting the \0.
It must be
char name1[5]={'m','o','n','u', '\0'};
What you have is undefined behaviour : printf prints memory after the memory, allocated for name1.
In this case, it seems like your compiler has placed the memory for name after name1, that's why they are both printed (name is correctly NULL-terminated, as all literals are).
name1 is not null-terminated, so printf just keeps printing chars until a \0 is reached.
printf("%s",name1);
s conversion specifier requires the argument to be a pointer to a C string.
char name1[4]={'m','o','n','u'};
is not a C string in because the array is not null terminated. Violating the requirement of the conversion speicier invokes undefined behavior and this is why you get this unexpected result.
You're trying to print a char array as a string with printf. Try this code:
int pointer=0;
while(pointer < 4){
printf("%c",name1[pointer]);
pointer++;
}
i am trying to determine what does this code?
#include <cstdlib>
#include <iostream>
#include<string.h>
using namespace std;
char *skip(char *p,int n)
{
for (;n>0;p++)
if (*p==0) n--;
return p;
}
int main(int argc, char *argv[])
{
char *p="dedamiwa";
int n=4;
cout<<skip(p,n)<<endl;
}
When I run it om dev c++,it wrotes
`basic_string::copy`
When i run it on ideone.com,it wrotes
prog.cpp: In function ‘int main(int, char**)’:
prog.cpp:15: warning: deprecated conversion from string constant to ‘char*’
prog.cpp:18: warning: ignoring return value of ‘int system(const char*)’, declared with attribute warn_unused_result
It searches for a certain number of \0 (n number of \0). It is undefined behaviour because it goes after the end of the string.
For the const part, string literals are const in c++. In c they aren't but still they mustn't be modified otherwise you get an undefined behavior (often a crash) (so even in c it's normally better to declare them as const and live happy)
The reason of the result of basic_string::copy is that in your (compiler/implementation specific, but quite common) compiled program there is an area where all the constant strings are saved "together". So if you go after the end of one, you go to the beginning of another. So someplace in your executable there is something like:
dedamiwa\0something\0somethingelse\0somethingelseelse\0basic_string::copy
It interpret the first parameter as a pointer to an array of character containing at least n null characters, and return a pointer after the n-th such null-character. Per se, there is no undefined behavior if you pass correct input to it.
Since you pass a simple null terminated string, it has undefined behavior, as there is only one such null-character in its input. It will access memory after the end of the string.
Concerning the compilation errors, in C++ a constant string is of type const char*, not char*, and you should check the return of the system function for error.
It skips n characters of the char array.
It interpret the first parameter as a pointer to an array of character
containing at least n null characters, and return a pointer after the
n-th such null-character. Per se, there is no undefined behavior if
you pass correct input to it.
Since you pass a simple null terminated string, it has undefined
behavior, as there is only one such null-character in its input. It
will access memory after the end of the string.
Concerning the compilation errors, in C++ a constant string is of type
const char*, not char*, and you should check the return of the system
function for error. by -- Sylvain Defresne
A version of the code with explicit braces is maybe a little bit
more readable for you:
using namespace std;
char *skip(char *p,int n){
for (;n>0;p++)
if (*p==0) {
n--;
}
return p;
}
To get rid of the error:
int main(int argc, char *argv[])
{
// cast the string which is of the type const char* to the
// type of the defined variable(char*) will remove your warning.
char *p= (char*) "dedamiwa";
int n=4;
cout<<skip(p,n)<<endl;
}
The skip procedure is asking for a segfault.
Basically, it increments p until the next '\0' is found, and repeats that n times.
In the best case, nothing will be printed because '\0...' is an empty string for std::cout(std::ostream&, const char *).
In the worst case, there be nasal dragons, to quote comp.lang.c.
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.