I am quite new with C.
#include <string.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
char* c=argv[1];
for (int i=0;i<sizeof(c);i++)
{
printf("%c\n",c[i]);
}
return 0;
}
I am trying to write a program to print every character of a word.
When I try with test: It displays
t
e
s
t
When I try with testtesttest: It displays:
t
e
s
t
I don't understand why, can you tell me why please?
Two problems: Using the sizeof operator on a pointer returns the size of the pointer and not what it points to. If you want the length of a string you should use strlen.
The second problem is what will happen if there are no arguments to your program. Then argv[1] will be NULL.
sizeof(c) is the memory size used by c, which is a char*, that is, a pointer on a char. This type takes 4 bytes of memory, hence the t e s t (4 chars). What you want is strlen, which gives you the length of a string.
#include <string.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
char* c=argv[1];
int length = strlen(c);
for (int i=0;i<length;i++)
{
printf("%c\n",c[i]);
}
return 0;
}
You should also test that your program gets at least one argument. argc is the length of argv, so you need to ensure that argc > 1.
sizeof operator returns the size of the type of operand. c is of type char *, therefore sizeof(c) will return the size of char * instead of the string. You should use strlen(c).
Related
I am a beginner in C language. I want to copy a char array to another, but I cannot. I got these errors:
Line 10 - [Warning] passing argument 1 of 'insert' makes pointer from integer without a cast
Line 4 - [Note] expected 'char *' but argument is of type 'char'
Can you help me with finding the errors in this code?
#include <stdio.h>
#include <string.h>
void insert(char d[100]);
int main( ) {
char m[100];
scanf("%s", &m);
insert(m[100]);
return 0;
}
void insert (char d[100]) {
char s[200];
strcpy(s, d);
}
You should pass m to insert() not m[100]. In that context, m[100] represents a single element of the m array and not the array itself. That's why the "integer to pointer without a cast" warning, because char is an integer after all.
The function signature of main() should be one of:
int main(void) {}
or
int main(int argc, char *argv[]) {}
or equivalently,
int main(int argc, char **argv) {}
There is no need to use the address operator & with an array argument in scanf(), since arrays decay to pointers to their first elements in most expressions, including function calls.
Note that you should specify a maximum field width when using the %s conversion specifier with scanf() to avoid buffer overflows:
scanf("%99s", m);
It is adquate to declare the insert() function as:
void insert(char d[]);
When you call the insert() function, only use the name of the array that you want to pass as an argument; this will decay to a pointer to the first element of the array. It is worth pointing out that the original code had undefined behavior with:
insert(m[100]);
This attempts to access the element at index 100 of the array m[], which is out of bounds.
The code now looks like this:
#include <stdio.h>
#include <string.h>
void insert(char d[]);
int main(void)
{
char m[100];
scanf("%99s", m);
insert(m);
return 0;
}
void insert (char d[])
{
char s[200];
strcpy(s, d);
}
Now, I don't know what you intend to do with the copied string s, but it no longer exists after insert() returns control to main().
Hello I am wondering why this works since on tutorials and such it always lists that arrays must be of fixed size except when dynamically making one with malloc.
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv) {
if(argc < 2)
return 0;
int tmp[ atoi(argv[1]) ];
printf("sizeof tmp equals to %d\n", sizeof tmp);
return 0;
}
What happens in the background at ASM-level when doing this? And how does it work?
Does it allocate the size given at starting the program on the stack and what's the max for the stack?
Also is this more memory expensive than using malloc?
Thanks in advance.
C99 introduces variable length array whose length is not a constant expression. The declaration
int tmp[ atoi(argv[1]) ];
declares tmp as VLA.
I want to find size or length of an unsigned char pointer in a function where that pointer is an argument to that function.Near the pointers declaration size is coming correctly.
But when i am trying to find size in function it is giving 4.
How can i do this ?
#include <stdio.h>
//void writeFile(unsigned char *da);
void writeFile(char *da);
int main(int arc,char **argv)
{
unsigned char block_bmp[]=
{
0x0,0xff,0xff,0xff,0x0,0x0,0x0,0xff,0xff,0xff,0x0,0x0,0x0,0xff,0xff,0xff,//*16bytes*
};
printf("size::%d\n",sizeof(block_bmp));
writeFile(block_bmp);
}
//void writeFile(unsigned char *da)
void writeFile(char *da)
{
printf("%d\n",__LINE__);
printf("size::%d\n",sizeof(da));
printf("length::%d\n",strlen(da));
FILE *fp;
int i;
fp=fopen("/tmp/hexfile","wb");
for(i=0;i<3780;i++)
fprintf(fp,"%c",da[i]);
// fwrite(da,sizeof(unsigned char),sizeof(da),fp);
fclose(fp);
}
If it points to a NULL-terminated string, use strlen. If not, the pointer is just some memory address for the called function, without any additional information about the size of the array (I assume, you try to pass an array). I suggest passing the number of array elements as additional parameter to the function.
You can not use sizeof in this condition. You should be using the strlen if the char array is NULL terminated.
When you pass array to a function, it decays to pointer, you can't use sizeof on this pointer to get the size of the array. The sizeof will give you 4 bytes (assuming 32 bit machine).
Example:
#include <stdio.h>
void fun(int myArray[10])
{
int i = sizeof(myArray);
printf("Size of myArray = %d\n", i);
}
int main(void)
{
// Initialize all elements of myArray to 0
int myArray[10] = {0};
fun(myArray);
getch();
return 0;
}
/**************OUTPUT**************
Size of myArray = 4
***********************************/
unsigned char array[100];
// sizeof(array) == 100
unsigned char* ptr = array;
// sizeof(ptr) == 4 for 32 bit platform.
When you call a function such as
foo(unsigned char* ptr)
{
}
with 'array' as argument, you only see a 'unsigned char *', not an array with 100 elements. That's why 'sizeof' returns 4.
pointers size sizeof(any_pointer_variable) will not depend on the datatype to which it is going to point. The size of the pointer is mostly 4 that is what you are getting in function. and it doesnt depend on what it points to. all pointers will have same size independent of what type they point to.
What's the difference between this function parameter stringLength(char string[]) to stringLength(char *string), shouldn't the first one not allow the incrementation(string = string +1) that has a comment on the code below?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int stringLength(char string[]) {
int length = 0;
while(*string) {
string = string + 1; // I can do it here
length++;
}
return length;
}
int main(void){
char s[] = "HOUSE";
s = s + 1; // I can not do it here
printf("%s\n", s);
printf("%d\n", stringLength(s));
}
That's because s is an array in main, but when you pass it as a parameter in stringLength it decays into a pointer.
It means that string is not an array, it is a pointer, which contains the address of s. The compiler changes it without telling you, so it is equivalent to write the function as:
int stringLength(char *string);
There's a page that talks about C arrays and pointers in the C-Faq
From there, I recommend you to read questions:
6.6 Why you can modify string in stringLength
6.7 Why you can't modify s in main
6.2 I heard char a[] was identical to char *a
6.3 what is meant by the ``equivalence of pointers and arrays'' in C?
6.4 why are array and pointer declarations interchangeable as function formal parameters?
I am learning C programming and I have a simple question about pointers...
I used the following code to play around with pointers:
#include <stdio.h>
int main (int argc, const char * argv[]) {
int * c;
printf("%x\n",c);
return 0;
}
When I print the value of C, I get back a 0. However, when I print &c (i.e. printf("&x\n",&c) I get an address in memory...
Shouldn't I be getting an address in memory when printing the pointer (i.e. printf("%x\n",c)?
--- EDIT ---
#include <stdio.h>
#include <stdlib.h>
int main (int argc, const char * argv[]) {
char * a = malloc(11);
printf("String please\n");
scanf("%s",a);
printf("%s",a);
}
The question is, why does printf("%s",a) returns the string instead of the address that is stored in a?
Shouldn't I use *a to follow the pointer and then print the string?
your current program is not correct. You define variable and do not set value before first use. the initial value is not guranteed for c, but you are lucky and it is equal to 0. It means that c points to nowhere. when you print &c you print address of variable c itself. So actually both versions print address.
printf is actually quite a complex function and can be made to do all sorts of tricks by giving it the right format specifier.
In your string example:
printf("%s", a)
the "%s" tells the printf function that the following variable should be treated as a string. In C, a string is a pointer to one or more char, terminated by a char containing 0. This is a pretty common request, which is why printf supports a format specifier "%s" that triggers this relatively complex behavior. If you want to print the address contained in the string pointer you have to use the format you found earlier:
printf("%x\n",a);
which tells printf to treat the contents of a as an unsigned integer, and print it in base 16.
*a would just be the value pointed to by a, which is just a single character.
You could print the single character with
printf("%c", *a);
Having int* c; If you print value of c, you get back a value that should be interpreted as a memory address of an integer value. In you example it might be 0 or something completely different as you are not initializing c.
If you print &c you get memory address of the pointer c (stored in stack).
#include <stdio.h>
int main (int argc, const char * argv[]) {
int * c;
int a=10;
c = &a;
printf("%x\n",c);
return 0;
}
This may clarify what happens when you make the int pointer point to something in memory.