I have this peace of C Programming code to take multiple literal strings from the user and store each address to each pointer and print out the value
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
char *ptr[3];
int i = 0;
for (; i < 3; i ) {
printf("ptr_%d: ", i 1);
fgets(ptr[i], 15, stdin);
ptr[i][strlen(ptr[i]) - 1] = 0;
puts(ptr[i]);
}
return 0;
}
However, only the first one is printed. Here is the output
ptr_1: first line
first line
Segmentation fault
[Program finished]
I want the same result that is produced Here
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
char *ptr[] = {
"first line",
"second line",
"third line"
};
puts(ptr[0]);
puts(ptr[1]);
puts(ptr[2]);
return 0;
}
output
first line
second line
third line
[Program finished]
Thanks in advance
CodePudding user response:
fgets(ptr[i], 15, stdin);
You've declared an array of three pointers:
char *ptr[3];
But none of those actually point to buffers of memory.
You can either create those buffers automatically:
char ptr[3][15];
Or dynamically with malloc.
char *ptr[3];
for (size_t i = 0; i < 3; i ) {
ptr[i] = malloc(15);
}
If you do this, make sure to free the memory you've allocated.
CodePudding user response:
If you are running gcc (with glibc 2.7 or greater), you can use the m modifier with scanf to allocate memory:
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
char *ptr[3];
for (i = 0; i < 3; i ) {
printf("ptr_%d: ", i 1);
while (scanf(" %m[^\n]",&ptr[i]) != 1)
printf("Try again: ");
puts(ptr[i]);
}
for (; i < 3; i )
free(ptr[i]);
return 0;
}
And be sure to free the memory when you are done with it.
CodePudding user response:
You'd probably want to put the scanf section of this code into a function but here is the smallest change to your existing sample that should work.
$ cat allocinput.c
#include <stdio.h>
#include <string.h>
#define MAX_LEN 80
int main(int argc, char *argv[])
{
char c;
char ptr[3][MAX_LEN];
int i = 0;
for (;i<3;i ) {
printf("ptr_%d: ", i 1);
// could overflow if the user types more than MAX_LEN characters
char *p = ptr[i];
while (scanf("%c", &c) && (p - ptr[i] < MAX_LEN)) {
if (c == '\n') break;
*p = c;
*p = 0;
}
puts(ptr[i]);
}
return 0;}
$ gcc -Wall allocinput.c
$ ./a.out
ptr_1: first line
first line
ptr_2: second line
second line
ptr_3: third line
third line
$
P.S. I recommend astyle to clean up the formatting:
$ astyle allocinput.c
Formatted /tmp/overflow/allocinput.c
$ cat allocinput.c
#include <stdio.h>
#include <string.h>
#define MAX_LEN 80
int main(int argc, char *argv[])
{
char c;
char ptr[3][MAX_LEN];
int i = 0;
for (; i<3; i ) {
printf("ptr_%d: ", i 1);
// could overflow if the user types more than MAX_LEN characters
char *p = ptr[i];
while (scanf("%c", &c) && (p - ptr[i] < MAX_LEN)) {
if (c == '\n') break;
*p = c;
*p = 0;
}
puts(ptr[i]);
}
return 0;
}
