Use getchar with pointer like char array - c

#include<stdio.h>
int main(){
char *q;
int i=0;
do{
*(q+i)=getchar();
i++;
}while(*(q+i)!=48);
int j=0;
for(;j<i;j++)
printf("%c",*(q+j));
}
I try to use in this way. I could compile. However ıt does not work .
My aim is that I wanna acquire char array (unlimited or limit will be defined by the user)
What should I do?

You should read a book on C.
You're just writing into random memory, causing undefined behavior.
You must allocate memory, you can't just write through a non-initialized pointer!
For instance, make it:
char buffer[1024], *q = buffer;
Then make sure you don't overstep inside the loop, of course.
Also, there's no point in writing the access as *(p + i), when p[i] means the exact same thing and is much easier to read.
Finally, remember that technically getchar() returns int, since it can return EOF which is not a character.

1st allocate memory for your pointer *q
include<stdio.h>
int main()
{
int a;
char b[100];
int i=0;
char *p=b;
while((a=getchar())!=EOF)
{
p[i++]=a;
}
p[i+1]='\0';
printf("%s",b);
}
Also you can try heap memory allocation
char *p=(char*)malloc(40);

Related

Can I use a pointer as the parameter of gets in C?

I am studying the C language.
When I pass a pointer to gets(), I find it can work well.
char *ptr;
gets(ptr);
puts(ptr);
But if I define an array of pointers, it doesn't work.
char *ptr[4];
int i=0;
for(i=0;i<4;++i)
gets(ptr[i]);
for(i=0;i<4;++i)
puts(ptr[i]);
Are they different, or is the first part wrong in fact? I want to know the reason.
You pass a pointer to a function (e.g. gets()) that writes data to a memory location pointed by your pointer. In your case, you have the uninitialized pointer, which means it points to a random memory location (where applications or an operating system resides). This leads to random effects - from "working" to abnormal termination or hanging. You need to reserve memory and assign pointer to point there, e.g. by:
char *ptr = (char*)malloc(256);
gets(ptr);
puts(ptr);
free(ptr);
Consider to use gets_s() that is more secure.
char *ptr[4];
int i=0;
for(i=0;i<4;++i)
gets(ptr[i]);
This is not valid C code as you did not allocate space for ptr[i]. On the other hand, never use gets because it's a function that does not check for buffer limit.
The pointer has to point somewhere first.
#define BUFSIZE 100
char *ptr = malloc(BUFSIZE);
fgets(stdin, ptr, BUFSIZE);
puts(ptr);
char *ptr[4];
int i=0;
for(i=0;i<4;++i) {
ptr[i] = malloc(BUFSIZE);
fgets(ptr[i], BUFSIZE, stdin);
}
for(i=0;i<4;++i) {
puts(ptr[i]);
}

Using pointers to make a new string in function

I am doing a bit of studying about C pointers and how to transfer them to functions, so I made this program
#include <stdio.h>
char* my_copy(pnt);
void main()
{
int i;
char a[30];
char* p,*pnt;
printf("Please enter a string\n");
gets(a);
pnt = a;
p = my_copy(pnt);
for (i = 0; i < 2; i++)
printf("%c", p[i]);
}
char* my_copy(char* pnt)
{
char b[3];
char* g;
g = pnt;
b[0] = *pnt;
for (; *pnt != 0; pnt++);
pnt--;
b[1] = *pnt;
b[2] = NULL;
return b;
}
It's supposed to take a string using only pointers and send a pointer of the string to the function my_copy and return a pointer to a new string which contains the first and the last letter of the new string. Now the problem is that the p value does receive the 2 letters but I can't seem to print them. Does anyone have an idea why?
I see five issues with your code:
char* my_copy(pnt); is wrong. A function prototype specifies the types of the parameters, not their names. It should be char *my_copy(char *).
void main() is wrong. main should return int (and a parameterless function is specified as (void) in C): int main(void).
gets(a); is wrong. Any use of gets is a bug (buffer overflow) and gets itself has been removed from the standard library. Use fgets instead.
b[2] = NULL; is a type error. NULL is a pointer, but b[2] is a char. You want b[2] = '\0'; instead.
my_copy returns the address of a local variable (b). By the time the function returns, the variable is gone and the pointer is invalid. To fix this, you can have the caller specify another pointer (which tells my_copy where to store the result, like strcpy or fgets). You can also make the function return dynamically allocated memory, which the caller then has to free after it is done using it (like fopen / fclose).
You're returning an array from my_copy that you declared within the function. This was allocated on the stack and so is invalid when the function returns.
You need to allocate the new string on the heap:
#include <stdlib.h>
b = malloc(3);
if (b) {
/* Do your funny copy here */
}
Don't forget to free() the returned string when you've finished with it.

I'm getting Runtime Error : Segmentation Fault (SIGSEGV), why?

I am getting a runtime error in this and i can't seem to figure it out.
This is my code to reverse a string and change A to T and vice-versa and to change C to G and vice-versa,
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char* reverse(char *input)
{
int len=strlen(input);
char *rev=NULL;
rev=(char*)malloc(sizeof(char)*len);
int i,k=0;
for(i=len-1;i>=0;i--)
{
rev[k++]=input[i];
if(rev[k-1]=='A')
rev[k-1]='T';
else if(rev[k-1]=='T')
rev[k-1]='A';
else if(rev[k-1]=='C')
rev[k-1]='G';
else if(rev[k-1]=='G')
rev[k-1]='C';
}
rev[k]='\0';
return rev;
}
int main()
{
char *input=(char *)malloc(sizeof(char)*1000);
scanf("%s",input);
char *str =NULL;//(char*)malloc(sizeof(char)*1000);
str=reverse(input);
printf("%s",input);
free(input);
}
You do not allocate enough memory to hold your reversed string:
int len=strlen(input);
...
rev=(char*)malloc(sizeof(char)*len);
...
rev[k]='\0';
You missed 1 extra byte for the terminating \0.
And by the way... Please don't cast the return value from malloc to a pointer.
First of all, you use i++ instead of i-- in the for loop. That means that the for loop never ends and k gets very very big and your rev[k] atempts to access values that it shouldnt.
Secondly, you do not need to allocate memory for str, because you allocate it in the function.
And you should allocate memory for one more char in the function as you will need if for '\0'.

C programming strcat using pointer

I am a beginner in C. I wanted to make strcat function using pointers. I made it but don't know what is wrong with it. I used gcc compiler and it gave segmentation fault output.
#include<stdio.h>
#include<string.h>
char scat(char *,char *);
void main()
{
char *s="james";
char *t="bond";
char *q=scat(s,t);
while(*q!='\0') printf("the concatenated string is %c",*q);
}
char *scat(char *s,char *t)
{
char *p=s;
while(*p!='\0'){
p++;
}
while(*t!='\0'){
*p=*t;
p++;
t++;
}
return p-s-t;
}
This one works:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *scat(char *,char *); /* 1: your prototype was wrong */
void main()
{
char *s="james";
char *t="bond";
char *q=scat(s,t);
printf("cat: %s\n", q); /* 2: you can use %s to print a string */
free(q);
}
char *scat(char *s,char *t)
{
char *p=malloc(strlen(s)+strlen(t)+1); /* 3: you will have to reserve memory to hold the copy. */
int ptr =0, temp = 0; /* 4 initialise some helpers */
while(s[temp]!='\0'){ /* 5. use the temp to "walk" over string 1 */
p[ptr++] = s[temp++];
}
temp=0;
while(t[temp]!='\0'){ /* and string two */
p[ptr++]=t[temp++];
}
return p;
}
You have to allocate new space to copy at the end of s. Otherwise, your while loo[ will go in memory you don't have access to.
You shoul learn about malloc() here.
It is undefined behaviour to modify a string literal and s, and eventually p, is pointing to a string literal:
char* s = "james";
s is passed as first argument to scat() to which the local char* p is assigned and then:
*p=*t;
which on first invocation is attempting to overwite the null character an the end of the string literal "james".
A possible solution would be to use malloc() to allocate a buffer large enough to contain the concatentation of the two input strings:
char* result = malloc(strlen(s) + strlen(p) + 1); /* + 1 for null terminator. */
and copy them into it. The caller must remember to free() the returned char*.
You may find the list of frequently asked pointer questions useful.
Because p goes till the end of the string and then it starts advancing to illegal memory.
That is why you get segmentation fault.
It's because s points to "james\0", string literal & you cannot modify constant.
Change char *s="james"; to char s[50]="james";.
You need to understand the basics of pointers.
a char * is not a string or array of characters, it's the address of the beginning of the data.
you can't do a char * - char* !!
This is a good tutorial to start with
you will have to use malloc
You get a segmentation fault because you move the pointer to the end of s and then just start writing the data of p to the memory directly following s. What makes you believe there is writable memory available after s? Any attempt to write data to non-writable memory results in a segmentation fault and it looks like the memory following s is not writable (which is to expect, since "string constants" are usually stored in read-only memory).
Several things look out of order.
First keep in mind that when you want to return a pointer to something created within a function it needs to have been malloc'ed somewhere. Much easier if you pass the destination as an argument to the function. If you follow the former approach, don't forget to free() it when you're done with it.
Also, the function scat has to return a pointer in the declaration i.e. char *scat, not char scat.
Finally you don't need that loop to print the string, printf("%s", string); will take care of printing the string for you (provided it's terminated).
At first, your code will be in infinte loop because of the below line. you were supposed to use curely braces by including "p++; t++ " statements.
while(*t!='\0')
*p=*t;
though you do like this, you are trying to alter the content of the string literal. which will result in undefined behavior like segmentation fault.
A sequence of characters enclosed with in double quotes are called as string literal. it is also called as "string". String is fixed in size. once you created, you can't extend its size and alter the contents. Doing so will lead to undefined behavior.
To solve this problem , you need to allocate a new character array whose size is sum of the length of two strings passed. then append the two strings into the new array. finally return the address of the new array.
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char* scat(char *,char *);
void append(char *t , char *s);
int main(void)
{
char *s="james";
char *t="bond";
char *n = scat(s,t);
printf("the concatenated string is %s",n);
return 0;
}
char* scat(char *s,char *t)
{
int len = strlen(s) + strlen(t);
char *tmp = (char *)malloc(sizeof(char)* len);
append(tmp,s);
append(tmp,t);
return tmp;
}
void append(char *t , char *s)
{
//move pointer t to end of the string it points.
while(*t != '\0'){
t++;
}
while( *s != '\0' ){
*t = *s;
t++;
s++;
}
}

Static array and dynamic array

char a[10];
scanf("%s",a);
int i=0;
while(a[i]!='\0')
printf("\n%c",a[i++]); //similar to printf("%s",a);
char *b;
b=malloc(10*sizeof(char));
scanf("%s",b);
i=0;
while((b+i)!='\0')
printf("\n%c",*(b+i++)); //not similar to printf("%s",a);
For input "abcd", the first loop prints a[] is it would be with printf(). But the same is not true for *b.
Second loops continues for too many until it encounters a '\0'.
So, does this mean '\0' is appended at the end of character strings automatically but not at the end of char type pointers?
And whose job is it to append this '\0'? Compiler's?
You forgot to dereference the pointer you get with b+i. It should be:
while (*(b + i) != '\0') // or while (b[i] != '\0') or while(b[i])
b + i just gets you an address, you have to dereference it to actually look at what the memory is pointing at and see if it's the NUL-terminator. The x[y] notation is equivalent to *(x + y).
Also don't forget to free the memory you allocated with malloc.
Dereferencing issue.
In the line (b+i) should be replaced with either:
*(b+i)
or
b[i]
Additionally, if you are just taking in strings, you should consider using fgets() instead of scanf, as it can help you avoid the user typing in too many characters and crashing your program.
Finally, you might consider using calloc() instead of malloc() as it automatically sets the contents of the array you allocate to be all-zeros rather than random garbage.
As an example:
#include <stdio.h>
#define MAX_BUFFER_LENGTH
int main(void) {
char a[MAX_BUFFER_LENGTH];
char *b;
fgets(a,MAX_BUFFER_LENGTH,stdin);
int i=0;
while(a[i]!='\0') {
printf("\n%c",a[i++]);
}
b=calloc(MAX_BUFFER_LENGTH,sizeof(char));
fgets(b,MAX_BUFFER_LENGTH,stdin);
i=0;
while(*(b+i)!='\0') {
printf("\n%c",*(b+i++));
}
// Done
return 0;
}
This is a much safer way to approach the problem you are solving.
Good luck!

Resources