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 2 years ago.
Improve this question
int main(void)
{
char mine[5] = "hello";
char *pen = mine;
while(*pen != '\0')
{
printf("%c\n", *pen);
pen++;
}
}
int main(void)
{
char mine[5] = "hello";
char *pen = mine;
while(*pen != '\0')
{
printf("%c\n", *pen);
*pen++;
}
}
I'm trying to grasp the idea of pointers with string. I ran both of the codes and got the same result, but I got a warning on the 2nd version of the code with *pen++ but still was able to run.
What is each of them doing and how come it gave me the same output?
According to the rules on operator precedence, the line
*pen++;
is equivalent to
*(pen++);
which means the * does nothing. So it is doing exactly the same thing as the line
pen++;
in the first program.
Also, it is important to note that the line
char mine[5] = "hello";
is not doing what you expect. You are initializing a character array of length 5 with a string literal of length 6 (including the terminating null character). This means the array does not contain sufficient space for the terminating null character.
Therefore, you should change the line to the following:
char mine[6] = "hello";
Alternatively, in order to make the compiler automatically allocate a sufficient amount of memory for the initialization, you can just write the following:
char mine[] = "hello";
pen++; is a statement consisting of one expression pen++. This expression's value is pen and the side effect is that pen is incremented.
*pen++ is a statement constisting of one expression *pen++. The expression's value is *pen and the side effect is that pen is incremented.
When an expression is used as a statement, then the value of the expression is ignored, only the side effects are relevant/observable. So in your case it is irrelevant if pen or *pen is the value, the side effect of incrementing pen is identical in both cases. Thus in your program both variants have the same observable effect. Yet it does not make sense to write *pen++ if you don't want to use the value. Then you should just write pen++, or even better ++pen.
Related
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 4 years ago.
Improve this question
I have searched for any reference to this for quite a bit now but I haven't had any success, so I thought I would ask here. Basically, I am trying to understand a C written program for creating a shell in linux and I am having problems with this piece of code
...
else if (args[0][0]-'!'==0){
int x = args[0][1]-'0';
int z = args[0][2]-'0';
...
}
The args is storing the command's entered by the user. For instance, later the address space of the child (parent process reads the commands, child executes them) is replaced using a call to execvp(args[0], args). The definition of args is as follows: char *args[MAX_LINE/2 +1];
What I have been having trouble understanding is the ways in which the array is accessed; specifically what is meant by these expressions in this context:
args[0][0]-'!'==0
args[0][1]-'0';
args[0][2]-'0';
Judging by the name of the variable, args stands for a list/array of arguments.
arg[0] is the first element of that array.
args[0][0] is the first character of the first element of that array.
The expression args[0][0]-'!'==0 checks whether that character is equal to '!'. That could have been written better as args[0][0] == '!'.
It's as if instead of using if ( i == 10 ), you decide to use if (i-10 == 0).
The next two lines
int x = args[0][1]-'0';
int z = args[0][2]-'0';
expect that the second and third characters of the first argument are digits and extract the decimal values they correspond to. If the first argument is "!26", then x will have the value 2 and z will have the value 6.
That logic depends on the guarantee that the encoding used for the characters '0' - '9' are required to be contiguous.
Probably args is a reference to
int main(int argc, char **argv);
Then args[0] is the name of the program and in the following args you would find the Arguments of the Programm, see e.g. Arguments to main in C
Thus args[0[0] is the first character of the name of the program.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 5 years ago.
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.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Improve this question
char hi[10] = "bye";
char a = 'a';
strcat(hi, a);
Like the example above. How would I do this in C? Is there a more general string I cant let hi be?
a is a char type while strcat expects it's both arguments of type char *. To append the char to an array of characters you can do this
int index = strlen(hi);
if(index < sizeof(hi)-1)
hi[index] = a;
Note that in this particular case the initializer will initialize the first three elements of hi to b, y and e respectively. The rest of the elements will be initialized to 0. Therefore you do not need to take care of the null termination of the array after appending each character to it. But in general you have to take care of that.
int index = strlen(hi);
if(index < sizeof(hi)-1){
hi[index] = a;
hi[index+1] = '\0';
}
strcat(hi, (char[]){a,0});
This would append the a.
Or you can do this
char s[]={a,0};
strcat(hi,s);
Or simply
#define MAXLEN 10
...
size_t len = strlen(hi);
if( len+1 <= MAXLEN-1)
hi[len]=a,hi[len+1]=0;
else
// throw error.
In your case hi[len+1]=0 is not required as it is already filled with \0. Also as mentioned by Serge that you can use simply used the string literal as the second parameter to the strcat function.
strcat(hi,"a");
There is a subtle difference in this two as mentioned by Serge again, that string literals are const but the compound literals are not.
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 5 years ago.
Improve this question
For example, I have this string:
ABABcct
Can I copy
ABc
begin index = 2, end index = 4
...from that string?
Is there any specific built-in function that can do this?
I know strncpy() can copy a number of characters of a string starting from the beginning of the string onto another. But I don't think it can do what I have just described. As far as I know, its "begin index" is limited to 0.
Actually you can use the function strncpy() with a pointer to anywhere in your string, not only a pointer to its beginning.
Example:
char *src = strdup("ABABcct");
char *dest;
strncpy(dest, src + 2, 3) // Copies 3 characters from your pointer src + 2 to your pointer dest
If you run this code, dest will contain ABc.
While in your case the standard copy functions would eventually work, their use is not allowed when the source and the destination are overlapped, in which case you'll experience an UB.
For such issue the standard C library provide the function memmove designed to handle overlapped areas. It works as using an intermediate buffer to solve any overlapping problem.
see also Meaning of overlapping when using memcpy
With strncpy
#include <stdio.h>
#include <string.h>
int main(void)
{
char p[10],s[10]="abcdefgh";
strncpy(p,s+2,3);
puts(p);
return 0;
}
I know strncpy() ... As far as I know, its "begin index" (as I call it) is limited to 0.
You knew it wrong. It's not about begin index or anything - simply you need to pass relevant char* in src and target which is being done here.
To add further clarification - most standard library functions which you are talking about never put a constraint of passing the pointer to the 0-th index. It doesn't matter which index you send - you can send 100th or 50th doesn't matter as long it follows the things expected by function (null termination etc).
The code posted here is for illustration purpose - didn't include the necessary checks needed to use str*cpy functions.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
The code which does not work. In function main after initializing variables by the user, it goes to if part and after that crash happens. This program's goal is to impact the repetitive characters in the string. So I decided to have a pointer in a function f1 and the pointer should point to 0th char of the array kar[]
then compare the 0th char to 1st char but the program crashes exactly after the last scanf("%s",kar[1000]).
where is the problem?
#include <stdio.h>
char f1(char* p)
{
int i=0,c=1;
while(*(p+i))
{
if(*p==*(++p))
{
c+=1;
p++;
i++;
continue;
}
else
{
if(c>1)
{
printf("%c%d",*p,c);
}
else
{
printf("%c",*p);
}
}
i++;
}
}
int main()
{
int n,i,m;
char kar[1000];
scanf("%d",&n);
for(i=1;i<=(2*n);++i)
{
scanf("%d",&m);
scanf("%s",kar[1000]);
if(m==1)
{
f1(kar);
}
}
}
This
scanf("%s",kar[1000]);
should trigger a compiler warning, as you pass a char where a char* is expected. You pass the 1001st element of kar (which is out of kar's bounds, BTW). In C array indices start with 0 for the 1st element.
To scan into kar, just pass the address of kar's 1st element.
scanf("%s", &kar[0]);
As arrays get decayed to the address of their 1st element when being passed to a function the following statement is equivalent
scanf("%s", kar);
Please note that the above two statements very well allow the user to enter more characters then kar can hold and with this make scanf() overflow kar, that is write beyond it bounds, invoking undefined behaviour, which might crash your program or whatever ...
To avoid this tell scanf() the maximum to scan by doing:
scanf("%999s", kar);
The maximum for chars a strings can hold in C is always one less then defined as C strings need one more char to have their end marked by a '\0'terminator.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Wrong implementation (compiled with gcc):
#include <stdio.h>
#include <ctype.h>
char* strupr( char *str )
{
while(*str) {
*str++ = toupper(*str);
}
return str;
}
int main(void) {
char string[] = { "Test String!" };
strupr( string );
puts( string );
return 0;
}
The function changes the string in an unexpected way, where the chars translated to upper case are only starting from the second char.
Note str is used twice in the assignment.
This implementation is invalid because it contains undefined behavior.
The explanation comes from section 6.5, paragraph 2 of the standard:
Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be read only to determine the value to be stored.
The standard gives an example of an expression that is considered undefined behavior to clarify the second sentence:
a[i++] = i;
In this expression the value of i is read not only to determine the new value to be stored, but also to determine the storage location of another value.
This is precisely what is happening in your expression:
*str++ = toupper(*str);
The only difference is that your expression uses pointers, and calls toupper in between.
This requirement may seem arbitrary, but it has a reason. C standard allows the compiler to make side effects of ++ visible before or after the call of toupper to allow compiler writers maximum flexibility. Without a restriction on str's use in expression this could lead to different behavior on different platforms, so the standard writers decided to prohibit it outright.