Following code print integer values:
for ( i=0 ; i<COL ; i++ )
{
fprintf(iOutFile,"%02x ",(int)(iPtr[offset]));
}
I want to store these integer values as a string in a character pointer. To do so, I tried following code but it does not work.
char *hexVal="";
char *temp;
int val;
for ( i=0 ; i<COL ; i++ )
{
fprintf(iOutFile,"%02x ",(int)(iPtr[offset]));
val = (int)(iPtr[offset]);
temp=(char*) val;
hexVal = strcat(hexVal,temp);
}
printf("%s", hexVal);
Thanx.......
When you write
char* hexVal = "";
you are setting hexVal to point to a string literal, later in your code you try to strcat to that address which will cause undefined behavior.
What you need to do is to allocate a large enough area to hold your resulting string and then let hexVal point to that.
E.g.
char* hexVal = malloc(100); // or how much bytes you need
then just do
strcat(hexVal, temp);
alt. allocate on stack
char hexVal[100];
You are approaching this wrong. In general, if you have an int i then you can't just typecast a char *cp to the address (or the value) of i and expect it to magically become a string that you can printf or use in strcat. For one thing, strings are null-terminated and don't have a fixed length, while ints have a fixed size of typically 32 bits long.
You have to create a separate buffer (memory space) where snprintf will happily create a string-representation of your int value for you.
I think that your question is more about understanding how programming, pointers and C work in general, than about ints and strings and their conversion.
You are getting undefined behavior since there is no writable memory at hexVal, which just points at a read-only area containing a character with the value 0. It is a valid string, but it's constant and has length 0, you cannot append to it.
Also, of course you can't cast an integer into a "string", that's just not how C works. This:
temp=(char*) val;
simply re-interprets the value of val as a pointer (i.e. as an address), it doesn't magically compute the proper sequence of digit characters used to represent the address, i.e. it doesn't convert val to a string.
You can use snprintf() to convert an integer to a string.
So, to summarize:
Change hexval's declaration into e.g. char hexval[32] = "";, this declares it as an array of 32 characters, giving you plenty of space into which to build a number as a string. It also initializes the array so the first character is 0, thus making it into an empty string (with space to grow).
Use e.g. snprintf(tmp, sizeof tmp, "%d", 4711); to format a number into a string (which should be e.g. char tmp[16];) in decimal form.
Use strcat(hexval, tmp); to concatenate the newly built numeric string onto hexval.
BEWARE that you can't concatenate forever, you will run out of space if you do it too long. Adjust the sizes, in that case.
Check return values where possible, read the manual pages (Google man FUNCTION where FUNCTION is a standard C library function like strcat).
Related
In c programming when we print a string. We are not using * . But when print a number using printf we are using *. So how it is understanding, i am printing a string or int. Is understanding using %s operator?
Attaching an example code
#include<stdio.h>
int main(int argc,char* argv){
char data[]="This is an example of pointer";
char *pointerstringdata =data;
printf("print the string data is >> %s\n",pointerstringdata); /* Here we are not using * why? case -1*/
int numberdata =100;
int *pointerintdata=&numberdata;
printf("print the int data is >> %d\n",*pointerintdata); /* Here we are using * why? case -2*/
return 0;
}
when we print a string. We are not using * . But when print a number using printf we are using *
Because the d conversion specifier expects an int, whereas the s conversion specifier expects a pointer (to a char and with this to the 1st element of a 0-terminated char array, which in fact is what C uses to mimik what commonly is called a "string").
The C language has no provision for treating a string as a value. You cannot pass a string to function. The pointer pointerstringdata is just a pointer to a char, so *pointerstringdata is one char, not a string. Passing *pointerstringdata will pass only one character, not a string.
To print strings, when %s is used, printf expects the argument to be a pointer. It uses this pointer to read from memory, and it reads and prints characters until it finds null characters.
In contrast, C does support treating numbers as values, so they can be passed to functions directly.
The %s format specifier is expecting a pointer.
If you pass *pointerstringdata the function will receive the first character in the array, which the function will try to dereference, and probably cause a crash.
in
char data[]="This is an example of pointer";
char *pointerstringdata =data;
printf("print the string data is >> %s\n",pointerstringdata); /* Here we are not using * why? case -1*/
if you want to print all the string you have to give its address, no *
if you want to print its first character you do `printf("%c", *pointerstringdata);
in
int numberdata =100;
int *pointerintdata=&numberdata;
printf("print the int data is >> %d\n",*pointerintdata); /* Here we are using * why? case -2*/
you do not want to print the address memorized in pointerintdata but the value same in that address, so you have to dereference
there is no difference with a string ... except that you want to write all the string
a pointer is a pointer, whatever it is a pointer to a char or a pointer to an int
Disclaimer: This is an explanation about how it appear to the developer, this is not how it is after compiling the code (especially because the optimizer might change it all).
C is a very low level language. You need to understand that a variable always contains a value of a few bytes.
C is also one of the languages that made it very convenient to access larger structures.
The content of the variable can be:
A value (e.g: as you mentioned a number)
A address in the RAM
A structure that uses more consecutive ram (and C makes it nice to use it as if it was more than that)
stuct (fixed length)
array with fixed length
There is no real concept of having a dynamic length variable as a value, therefor strings as well as arrays of dynamic length only have the address in the variable.
As stings are variable length, the convention in C is:
Have an address in the variable
Read the real data byte by byte starting at that address
Read data until the byte is 0 (NULL)
That is called a null-terminated string.
This way you can pass data of variable length to printf, and printf will find out the length by looking for the first byte that is 0.
Converting variables containing address to those containing value works like this:
var_with_value = *var_with_address
var_with_address = &var_with_value
"var_with_address" is called a pointer.
In conclusion: You need to pass strings as address not as value, and numbers as value not as address, and that is the difference why you have to use *
Because pointers hold reference to the object. * dereference this object. So if the pointer holds the reference to the char object when we dereference it we get this object. So dereference char pointer is just the single char not the address of the first char in the string.
I am practicing allocation memory using malloc() with pointers, but 1 observation about pointers is that, why can strcpy() accept str variable without *:
char *str;
str = (char *) malloc(15);
strcpy(str, "Hello");
printf("String = %s, Address = %u\n", str, str);
But with integers, we need * to give str a value.
int *str;
str = (int *) malloc(15);
*str = 10;
printf("Int = %d, Address = %u\n", *str, str);
it really confuses me why strcpy() accepts str, because in my own understanding, "Hello" will be passed to the memory location of str that will cause some errors.
In C, a string is (by definition) an array of characters. However (whether we realize it all the time or not) we almost always end up accessing arrays using pointers. So, although C does not have a true "string" type, for most practical purposes, the type pointer-to-char (i.e. char *) serves this purpose. Almost any function that accepts or returns a string will actually use a char *. That's why strlen() and strcpy() accept char *. That's why printf %s expects a char *. In all of these cases, what these functions need is a pointer to the first character of the string. (They then read the rest of the string sequentially, stopping when they find the terminating '\0' character.)
In these cases, you don't use an explicit * character. * would extract just the character pointed to (that is, the first character of the string), but you don't want to extract the first character, you want to hand the whole string (that is, a pointer to the whole string) to strcpy so it can do its job.
In your second example, you weren't working with a string at all. (The fact that you used a variable named str confused me for a moment.) You have a pointer to some ints, and you're working with the first int pointed to. Since you're directly accessing one of the things pointed to, that's why you do need the explicit * character.
The * is called indirection or dereference operator.
In your second code,
*str = 10;
assigns the value 10 to the memory address pointed by str. This is one value (i.e., a single variable).
OTOTH, strcpy() copies the whole string all at a time. It accepts two char * parameters, so you don't need the * to dereference to get the value while passing arguments.
You can use the dereference operator, without strcpy(), copying element by element, like
char *str;
str = (char *) malloc(15); //success check TODO
int len = strlen("Hello"); //need string.h header
for (i = 0; i < len; i ++)
*(str+i)= "Hello"[i]; // the * form. as you wanted
str[i] = 0; //null termination
Many string manipulation functions, including strcpy, by convention and design, accept the pointer to the first character of the array, not the pointer to the whole array, even though their values are the same.
This is because their types are different; e.g. a pointer to char[10] has a different type from that of a pointer to char[15], and passing around the pointer to the whole array would be impossible or very clumsy because of this, unless you cast them everywhere or make different functions for different lengths.
For this reason, they have established a convention of passing around a string with the pointer to its first character, not to the whole array, possibly with its length when necessary. Many functions that operate on an array, such as memset, work the same way.
Well, here's what happens in the first snippet :
You are first dynamically allocating 15 bytes of memory, storing this address to the char pointer, which is pointer to a 1-byte sequence of data (a string).
Then you call strcpy(), which iterates over the string and copy characters, byte per byte, into the newly allocated memory space. Each character is a number based on the ASCII table, eg. character a = 97 (take a look at man ascii).
Then you pass this address to printf() which reads from the string, byte per byte, then flush it to your terminal.
In the second snippet, the process is the same, you are still allocating 15 bytes, storing the address in an int * pointer. An int is a 4 byte data type.
When you do *str = 10, you are dereferencing the pointer to store the value 10 at the address pointed by str. Remind what I wrote ahead, you could have done *str = 'a', and this index 0 integer would had the value 97, even if you try to read it as an int. you can event print it if you would.
So why strcpy() can take a int * as parameter? Because it's a memory space where it can write, byte per byte. You can store "Hell" in an int, then "o!" in the next one.
It's just all about usage easiness.
See there is a difference between = operator and the function strcpy.
* is deference operator. When you say *str, it means value at the memory location pointed by str.
Also as a good practice, use this
str = (char *) malloc( sizeof(char)*15 )
It is because the size of a data type might be different on different platforms. Hence use sizeof function to determine its actual size at the run time.
how do i Initialize my code if all im using are words and no numbers?
I have been trying to just use char * but it is saying that its still not initialized
char *Carson;
printf("Enter a name:\n");
scanf("%s",Name);
printf("%s Hello Carson\n", Carson);
You either have to allocate memory dynamically and assign it to Carson (see e.g. `malloc? ), or make it an array. There's no way around it. And for that, the code must contain a number. The number could be input from the user though, so you won't have any actual numbers in the source.
Remember that in C all strings need an extra terminator character (added automatically by scanf) so remember to add space for it.
A solution without any number, I don't think this must be used for practical applications, just a hack
char Carson[sizeof(long long) * sizeof(long long)];
printf("Size = %d\n", sizeof Carson);
printf("Enter a name:\n");
scanf("%s",Carson);
printf("%s Hello Carson\n", Carson);
In my system it create a char array of 64 bytes = 8 * 8, the size of long long in most systems is 8 bytes although it's size depends on your compiler and operating system
you might like to initialize Carson like this:
char *Carson = malloc(sizeof(char)*200);/* for 200 characters */
Don't forget to add \0 terminator and also, donot forget to free it once you are done using it.
In order to initialize variables in C you need to use constants values, that is, expressions whose value can be known at compile time.
For integer or float types you can use mathematical formulas involving only constant operands, thus you can obtain still a constant value that can be used in a initiaiization.
What you call "words" have been called better "strings".
In C you are able to use strings that are constant at compile time, also called "string literals".
A string literal has to be indicated surrounded by quotes, like these examples:
"Hello world!"
"Peter & John"
"user#gmail.com"
and so on.
There are some rules that you need to remember: some special characters have "escape sequences" to be used inside a string literal.
Now you can use that string literals in order to initialize a char* variable:
char *name = "Mr. Smith";
char *city = "Amsterdam";
The result of the initialization gives a C string style, that is, an array of char object, whose length is the amount of quoted characters in the string literal, plus 1, because a null character is added at the end. Thus, in memory you have:
char *city ----> |A|m|s|t|e|r|d|a|m|\0|
Thus, city points to an array of 10 chars.
The last character, \0, means "null character", whose ASCII code is 0. Since it corresponds to a non-printable character, it has to be indicated with the escape sequence \0.
For more information, take a look on these websites:
Escape sequences in C
Storage of string literals
If you initialize a pointer to char object to a string literal, the compiler reserves memory automatically for you, son you don't need any malloc() at all.
However, you cannot modify the characters of such a string.
If you are interested in modify the characters, you can use better un array of char object:
char name[30] = "Schwarzenegger";
The array reserves 30 chars for the string literal "Schwarzenegger".
Only the first 14 are used for the string, plus 1 holding the null character attached at the end.
The rest of chars of the array have dummy information, but there is no problem because they are not printed. (The standard library functions always stop processing the string when they encounter a null character).
EDITED More information.
About your particular error message: "lack of initialization", the problem is that in the definition of the pointer to char object:
char *name;
you only have a "pointer to" an undefined block of memory.
You have to specify the array of char that name will be point to.
If you initialize with a string literal, there is not any problem, because the address of the string literal is passed to name.
But, since you are planning to use name for data input by means of scanf(), you have to allocate memory enough. You can do that other users have explained yet in their answers, that is, by using malloc().
I think there is need to do changes in your code,
char Carson = NULL;
Carson = (char)malloc(sizeof(char)*256);
printf("Enter a name:\n");
scanf("%s",Carson );
printf("%s Hello Carson\n", Carson);
in place of 256 u can use whatever value you want.
let me know if it works.
I am new to c and learning pointers at the moment what I know is that pointer points to the memory address of whatever it points to.
my question is this how you allocates memory exactly the length of the character or it will take 50 bytes?
Lets say they entered a title: hunger games
BOOL AddNewDVD(Database* data){
}
I am new to c and learning pointers
Pointers are tough for beginners. Make sure you get a solid foundation.
at the moment what I know is that pointer points to the memory address of whatever it points to.
Though that is in practice correct, that's not how I like to think of it. What you are describing is how pointers are typically implemented, not what they are conceptually. By confusing the implementation with the concept you set yourself up for writing bad code later that makes unwarranted assumptions. There is no requirement that a pointer be a number which is an address in a virtual memory system.
A better way to think of a pointer is not as an address, but rather:
A pointer to t is a value.
Applying the * operator to a pointer to t gives you a variable of type t.
Applying the & operator to a variable of type t gives you a pointer to t.
A variable of type t can fetch or store a value of type t.
An array is a set of variables each identified by an index.
If a pointer references the variable associated with index i in an array then p + x gives you a pointer that references the variable associated with index i + x.
Applying the [i] operator to a pointer is a shorthand for *(p+i).
That is, rather than thinking of a pointer as a number that refers to a location in memory, just think of it as something that you can force to give you a variable.
is this how you allocates memory exactly the length of the scanned string or it will take 50 bytes?
char *title = malloc(50 * sizeof(char));
scanf(" %[^\n]s", title);
malloc(50*sizeof(char)) gives you an array of 50 chars.
title is a pointer to char.
When dereferenced, title will give you the variable associated with the first item in the array. (Item zero; remember, the index is the distance from the first item, and the first item has zero distance from the first item.)
scanf fills in the characters typed by the user into your array of 50 chars.
If they type in more than 49 chars (remembering that there will be a zero char placed at the end by convention) then arbitrarily bad things can happen.
As you correctly note, either you are wasting a lot of space or you are possibly overflowing the buffer. The solution is: don't use scanf for any production code. It is far too dangerous. Instead use fgets. See this question for more details:
How to use sscanf correctly and safely
You need to have a buffer to know how long the entered name is. This is your title, which can be filled maximum with 49 chars. Then you compute len and see it is only 6 byte long. You allocate string to have exactely this size + 1.
Of course you can then write the content of title to string, even if title is a 50 byte long buffer, and string only 7 byte long - copying of the content ends with the \0 termination char, and this is guaranteed to be inside capacity of string.
You cannot use scanf to determine the length of a string and then allocate memory for it. You need to either:
Ask the user the length of the string. Obviously, this is a poor choice.
Create a static buffer that is more than large enough and then create a dynamic string that is the exact length you need. The problem is, determining what the maximum length the string may be. fgets might be what you need. Consider the following code fragment:
#define MAX_STR_LEN (50)
char buf[MAX_STR_LEN] = {0};
char *str, *cPtr;
/* Get User Input */
printf("Enter a string, no longer than %d characters: ", MAX_STR_LEN);
fgets(buf, MAX_STR_LEN, stdin);
/* Remove Newline Character If Present */
cPtr = strstr(buf, "\n");
if(cPtr)
*cPtr = '\0';
/* Allocate Memory For Exact Length Of String */
str = malloc(strlen(buf) + 1);
strncpy(str, buf, strlen(buf));
/* Display Result */
printf("Your string is \"%s\"\n", str);
A friend and I are doing a C programming unit for college.
We understand that there is no "string" per se in C, and instead, a string is defined by being an array of characters. Awesome!
So when dealing with "strings" is obvious that a proper understanding arrays and pointers is important.
We were doing really well understanding pointer declaration, when and when not to dereference the pointer, and played around with a number of printf's to test our experiments. All with great success.
However, when we used this:
char *myvar = "";
myvar = "dhjfejfdhdkjfhdjkfhdjkfhdjfhdfhdjhdsjfkdhjdfhddskjdkljdklc";
printf("Size is %d\n", sizeof(myvar));
and it spits out Size is 8!
Why 8? Clearly there are more than 8 bytes being consumed by 'myvar' (or is it)?
(I should be clear and point out that I am VERY aware of 'strlen'. This is not an exercise in getting the length of a string. This is about trying to understand why sizeof returns 8 bytes for the variable myvar.)
8 is the size of the pointer.
myvar is a pointer to char (hence char*) and in 64 bit system pointers are 64 bit = 8 byte
To get size of a null-terminated string use this code :
#include<string.h>
#include<stdio.h>
int main()
{
char *x="hello there";
printf("%d\n",strlen(x));
return 0;
}
Well as AbiusX said, the reason why sizeof is returning 8 is because you are finding the size of a pointer (and I'm guessing you're on a 64-bit machine). For example, that same code-snippet would return 4 on my machine.
Strings in C are kept as an array of characters followed by a null terminator. So when you do this...
const char *message = "hello, world!"
It's actually stored in memory as:
'h''e''l''l''o'','' ''w''o''r''l''d''!''\0'...garbage here
If you read past the null terminator, you'll likely just find whatever garbage happens to be in memory there at the time. So in order to find the length of a string in C, you need to start at the beginning of the string and read until the null terminator.
size_t count = 0;
const char *message = "hello, world!";
for ( ; message[count] != '\0'; count++ );
printf("size of message %u\n", count);
Now this is an O(n) operation (because you have to iterate over the entire array to get the size). Most higher level languages have their upper level abstraction of strings as something similar to...
struct string {
char *c_str;
size_t length;
};
And then they just keep track of how long the string is whenever they do an operation on it. This greatly speeds up finding the length of a string, which is a very common operation.
Now there is one way you can figure out the length of a string using sizeof, but I don't suggest it. Using sizeof on an array (not a pointer!) will return the size of the array multiplied by the data type size. And C can auto-figure out the size of an array as long as it can be figured out at compile-time.
const char message[] = "hello, world!";
printf("size of message %u\n", sizeof(message));
That will print the correct size of the message. Remember, this is NOT suggested. Notice that this will print one greater than the number of characters in the string. That's because it also counts the null terminator (as it has to allocate an array large enough to have the null terminator). So it's not really the real length of the string (you can always just subtract one).
myvar is a pointer. You seem to be on a 64-bit machine, so sizeof returns 8 byte in size. What you're probably looking for instead is strlen().
Like AbiusX said, 8 is the size of the pointer. strlen can tell you the length of the string (man page).