Reputation: 123
#include<stdio.h>
#include<string.h>
main () {
char *line[5];
int i;
line[0] = "line 1";
line[1] = "line 2";
line[2] = "line 3";
line[3] = "line 4";
line[4] = "line 5";
char *p;
p=line[2];
//*p = *(p+2); //gives error as segmentation fault.
printf("\n coming here : %s",*line); //works fine
printf("\n coming here : %s",*line++); //gives error "invalid increment in main"
printf("\n coming here : %s",*(line+2)++); //error, i assumed it will work as *(line+2) is also a pointer
printf("%c",*(line[4]+1));//works, prints character 'i'
printf("%c",**(line+4));//segmentation error, i assumed it to print character 'l'
}
I was trying this program and faced few errors as I have mentioned in the comments beside each line of code.
with char *line[5] i was trying to achieve a array of pointers each pointer element of this array pointing to a string.
Please help me clarify what all I am doing wrong here. Thanks.
I have included only part of the example, please see the writelines function. Rest of this example is pretty straight forward this did not include it.
#define MAXLINES 5000 /* max #lines to be sorted */
char *lineptr[MAXLINES]; /* pointers to text lines */
int readlines(char *lineptr[], int maxlines)
{
int len, nlines;
char *p, line[MAXLEN];
nlines = 0;
while ((len = getline(line, MAXLEN)) > 0)
if (nlines >= maxlines || p = alloc(len) == NULL) return -1;
else {
line[len-1] = '\0'; /* delete newline */ strcpy(p, line);
lineptr[nlines++] = p;
}
return nlines;
}
/* writelines: write output lines */
void writelines(char *lineptr[], int nlines)
{
while (nlines-- > 0)
printf("%s\n", *lineptr++); // this is where they are incrementing array, which you said is incorrect.
}
main(int argc, char *argv[])
{
char *line[] = {"linawee 1", "lipe 2", "lint 3", "linr 4"};
while (--argc > 0) //command line input has same number of elements as 'line'
{
printf("%s%s", *++argv, (argc > 1) ? " " : ""); //works just fine.
printf("%s", *++line); //error
}
}
Please explain the above prog, why it works for one and gives error for other. Thanks.
Upvotes: 0
Views: 309
Reputation: 82026
So, let's iterate through the errors:
*p = *(p+2);
You're modifying a string literal. That's not allowed.
printf("\n coming here : %s", *line);
*line
will result in the same value as line[0]
, so this all makes sense.
printf("\n coming here : %s", *line++);
line
is an array. You're not allowed to increment arrays. So line++
is invalid.
printf("\n coming here : %s", *(line+2)++);
This actually means:
printf("\n coming here : %s", *(line + 2);
(line + 2) = (line + 2) + 1;
Which is invalid, because you can't assign to line + 2
.
printf("%c", *(line[4]+1));
Yep thats fine. We take the string at index 4, and then grab the character in it at index 1.
printf("%c", **(line+4));
This should work fine. It's not clear why you are getting an error.
void func(char *lineptr[]) {
*lineptr++;
}
For whatever reason, C allows you to use array notation during function calls. In this case, when you have a function parameter of: char *lineptr[]
, it is treated as char **lineptr
.
Therefore, in this case, you're actually incrementing a pointer, not an array, which is why it's allowed.
Note however, that the increments to the pointer are only visible inside the function. That is, if I do:
int main() {
char * arr[] = {"hi", "how", "are", "you"};
inc(arr);
// arr[0] still points to "hi"
}
void inc(char *arr[]) {
// arr[0] points to "hi"
arr++;
// arr[0] now points to "how"
}
char *line[] = {"linawee 1", "lipe 2", "lint 3", "linr 4"};
printf("%s", *++line);
You're incrementing an array. You're not allowed to do that. You certainly could do:
printf("%s", line[3]);
printf("%s", *(line + 3)
Upvotes: 4
Reputation: 311146
String literals may not be changed though in C they have types of non-const character arrays. In this statement
//*p = *(p+2); //gives error as segmentation fault
you are trying to change the string literal pointed by p.
As for other errors then arrays in expressions are converted to rvalue
of pointers to the first element of arrays. You may not increase an rvalue
. For it would be clear then for example expression
(line+2)++
in fact is equivalent to the following code
int x = 0;
( x + 2 )++;
Here the compiler will issue an error because expression ( x + 2 )
is not a lvalue
Upvotes: 1
Reputation: 1744
You have one problem here
You are trying to assign an rvalue (layman terms: value that should be in the right side of equation, and constants that you should not modify)
#include<stdio.h>
#include<string.h>
int main () {
char *line[5];
line[0] = "line 1";
line[1] = "line 2";
line[2] = "line 3";
line[3] = "line 4";
line[4] = "line 5";
char *p;
p=line[2];
// *p = *(p+2); // *p is a gives you a character, this means you are trying to assign character with character?
p = p + 2; // correct way
printf("%s\n", p); // outputs: "ine 3", expected
printf("coming here : %s\n",*line); // this is fine
// printf("\n coming here : %s",*line++); // Same reason as above and below
// printf("\n coming here : %s",*(line+2)++); //*(line + 2)++ means *(line + 2) = *(line + 2) + 1 => see the error?
printf("%c\n",*(line[4]+1)); //works, prints character 'i'
printf("%c\n",**(line+4));// this prints l on my machine and is valid.
return 0;
}
Upvotes: 0
Reputation: 21
See: lvalue required as increment operand
line is not a pointer to dynamic memory, it is an array declared on the stack. So line++ is invalid.
Upvotes: 2