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
I have updated the code as per the comments. As I am not near a PC, could you please check it and update me on that?
#include<stdio.h>
int main()
{
char s[100],rev[100],*ps1,*ps2,temp,*ptemp=&temp;
int i,n=0;
printf("Enter a string: ");
scanf("%s",s);
printf("The string is: %s\n",s);
for(i=0;s[i]!='\0';i++)
n++;
ps1=&s[0];
ps2=&s[n-1];
for(i=0;i<n/2;i++)
{
*ptemp=*ps1;
*ps1=*ps2;
*ps2=*ptemp;
*ps2--;
*ps1++;
}
printf("The reverse of the string is: %s\n",s);
}
Trying to keep code the closer to yours and making it works:
#include<stdio.h>
int main()
{
char s1[100], rev[100], *ps1=s1, *prev=rev;
int value1, value2 = 0;
int *i = &value1, *length = &value2; // Why the hell do you need pointers? But if you do want them, use them the right way
printf("Enter a string: ");
scanf("%99s", s1); // parameter must be a 'char *', not a 'char **'
printf("The string is: %s\n",s1); // Ends line with \n
for(*i=0;*(ps1+(*i))!='\0';(*i)++)
{
(*length)++;
}
printf("The length is: %d\n", *length);
for(*i=1;*(ps1+(*i)-1)!='\0';(*i)++)
{
*(prev+(*i)-1)=*(ps1+(*length)-(*i));
}
*(rev+(*i)-1)='\0';
printf("\nThe reverse string is: %s\n",rev); // Ends line with \n
}
But I must confess your last loop is really hard to understand. Also, why do you need those pointers?
Edit: Also you should check return value of scanf() is 1. Because if is is not, it means scanf() did not set a value to s1.
Edit 2: Correction of the new version of the question
#include<stdio.h>
int main()
{
char s[100],*ps1,*ps2,temp,*ptemp=&temp; // removing unused rev
int i,n=0;
printf("Enter a string: ");
scanf("%s",s);
printf("The string is: %s\n",s);
for(i=0;s[i]!='\0';i++)
n++;
ps1=&s[0]; // ps1 = s; would be fine
ps2=&s[n-1]; // ps2 = s + (n-1); would be fine
for(i=0;i<n/2;i++)
{
*ptemp=*ps1;
*ps1=*ps2;
*ps2=*ptemp;
ps2--; // You want ps2 point to previous character
ps1++; // You want ps1 point to next character
}
printf("The reverse of the string is: %s\n",s);
}
The first problem I see is that scanf expects a pointer, but you give it a pointer to a memory address which is effectively a pointer to pointer:
scanf("%s", &s1);
Should be changed to:
char s1[100] = {0};
scanf("%s", s1);
As scanf does not check for memory overflow, it would be a wiser choice to make use of this syntax over the above suggested one
char s1[100] = {0};
scanf("%99s", s1);
This way, you don't get into any buffer overflow issues
Next problem, you dereference a pointer before assigning it a valid location in memory:
for(*i=0;*(ps1+(*i))!='\0';(*i)++)
Change to:
int i;
for(i = 0; ps1[i] != '\0'; i++)
Do the same for your other for-loop
Finally, remove this line:
*(rev+(*i)-1)='\0';
And change the print statement to:
printf("\nThe reverse string is: %s",s1);
Related
This question already has answers here:
fgets instructions gets skipped.Why?
(3 answers)
Closed 6 years ago.
#include<stdio.h>
#include<malloc.h>
int main()
{
char *string1;
int length;
scanf("%d", &length);
string1 = (char *)malloc(sizeof(char) * length);
printf("\n Enter the First String : ");
fgets(string1, length, stdin);
printf("\n The First String : %s ",string1);
free(string1);
return 0;
}
Can someone help me on the above code ? I trying to get the length of a string and the string as inputs. But, I am able to enter only Length of the string. After that it skips the string input part.
This is the output I am getting :
sh-4.3$ main
10
Enter the First String :
The First String :
sh-4.3$
After typing "10<enter>" the <enter> or "\n" will remain in the
stdin buffer, so you have to use getchar() after the scanf to
remove it.
Also you should #include <stdlib.h> instead of malloc.h.
You malloc 1 character too less, because of the 0-terminator.
string1 = malloc(length + 1); will do the job, the cast is not
necessary and sizeof(char) is always 1.
If you need to use stdin for string input you can use fgetln. I edited you example and now it looks like that:
#include<stdio.h>
#include <stdlib.h>
int main()
{
char *string1;
size_t length;
//scanf("%d", &length);
//string1 = (char *)malloc(sizeof(char) * length);
printf("\n Enter the First String : ");
//fgets(string1, length, stdin);
string1 = fgetln(stdin, &length);
string1[length] = '\0';
printf("\n The First String : %s ",string1);
free(string1);
return 0;
}
Note: fgetln returns not a C string, you should add a NULL character to the end.
The most simple answer when reading from STDIN/keyboard with the newline etc.
is to just add the "\n" to the scanf, ie:
scanf("%d\n", &length);
Solves the problem ;)
PS: Beware of all the other security/buffer overflow issues of scanf
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
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.
Closed 6 years ago.
Improve this question
char string = "default";
printf("The default String is: %s", &string);
scanf("%s", &string);
printf("You entered: %s", &string);
The first printf statement prints out &string as X(?_?. The second printf, after the scanf statement prints out the string I entered.
Since the &var operator means "memory address of var", then why does &string print out the string entered? Why do I get a segmentation fault, when I attempt to use just "string"?
You have declared string as a single character but you fill it with a string. This invokes undefined behavior. You should change your code to :
char string [20] = "default"; //20 is random, you should use the maximum length of the input you may have
printf("The default String is: %19s", string);
scanf("%s", string);
printf("You entered: %s", string);
In general, scanf needs to take a memory address as an argument, and in the code above, string is a memory address. You can read more about scanf in this link.
#include <stdio.h>
#include <string.h>
char chomp(char* s, char c){
size_t l = strlen(s);
if (!l) return 0;
return s[l-1] = s[l-1]==c ? '\0' : s[l-1];
}
int main(){
char string[] = "default"; /* sizeof(string) == strlen("default")+1 */
printf("The default String is: %s\n", string);
//^ you want the array to decay to a char* here
/*scanf("%s", &string); -- DANGEROUS
-- scanf doesn't know how much space you have in string*/
fgets(string /*decay again*/, sizeof(string), stdin);
/* fgets does know because you've told it with sizeof(string)*/
chomp(string, '\n');
printf("You entered: %s", string);
return 0;
}
This would be a solution:
char string[20];
strcpy(string, "default");
printf("The default String is: %s", string);
scanf("%19s", string);
printf("You entered: %s", string);
This question already exists:
Safe Alternative to gets [duplicate]
Closed 8 years ago.
I know that I can use gets(char *) to get string input from user with spaces included but I read that buffer overflow problem. Using strcpy, strcmp (and a few other functions) is not safe we should use strncpy, strncmp and explicitly mention the size of the input. Some guy on Stack Overflow told me that. So, I am worried about using gets for getting input from user or it's safe? If it's safe tell me I'll continue using it. If not then what is the other way getting spaced string input from user safely?
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *a[2];
char b[] = "first";
char c[] = "second";
int s1; //,s2;
// printf("\nLong you want your %s string to be: \n",b);
//scanf("%d",&s1); fflush(stdin);
//printf("\nLong you want your %s string to be: \n",c);
// scanf("%d",&s1); fflush(stdin);
int i;
for(i=0; i<2; i++) {
printf("\nLong you want your %s string to be: \n",b);
scanf("%d",&s1); fflush(stdin);
a[i] = (char *) malloc(s1*sizeof(char));
}
printf("\nEnter the first string: \n");
scanf("%s", a[0]); fflush(stdin);
printf("\nEnter the second string: \n");
scanf("%s", a[1]); fflush(stdin);
printf("\nThe first string is: %s\n", a[0]);
printf("\nThe second string is: %s\n", a[1]);
}
Please do some research.. this http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1044652485&id=1043284385 may help you.
This is code I wrote that checks if a string is a palindrome or not. I need to revise this code so that it uses character pointers in it. Could someone give me some suggestions/tips...or show me how to do that? Thanks
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(){
char string1[20];
int i, length;
int flag = 0;
printf("Enter a string: ");
scanf("%s", string1);
length = strlen(string1);
for(i=0;i < length ;i++){
if(toupper(string1[i]) != toupper(string1[length-i-1])){
flag = 1;
break;
}
}
if (flag)
printf("%s is not a palindrome \n\n", string1);
else
printf("%s is a palindrome \n", string1);
return 0;
}
In your code you use string1[i] to access the current element from the beginning of the string, and string1[length-i-1] to access the current element from the end of the string. You could create two pointers, pb and pe, and then move them toward each other.
To define pointers, use this:
char *pb = &string1[0]; // Or just string1, compiler will convert it to pointer
char *pe = &string1[length-1];
To advance the pointers toward each other, use pb++ and pe--.
To see if the pointers have not crossed each other , check that pb < pe. Currently, your program checks the string twice; there's no need to do that - you can stop as soon as pe becomes less than or equal to the pb.
To access the character pointed to by the current pointer, use
toupper(*pb) != toupper(*pe)
You can combine the check with advancing the pointers, like this:
toupper(*pb++) != toupper(*pe--)
Note: it is not safe to use %s, because when users enter more characters than fits in your string1 buffer overrun results. You should specify the length of the buffer, like this:
scanf("%19s", string1); // Leave one char for null terminator
I'm not sure I completely understand the question, but I think this answers it. You actually are using character pointers. char string1[20] is the same as char *string1. The difference is that you've basically assigned the pointer to a block of memory. You could access the string in this way.
char string[20] = "foo";
printf("%c\n", string[0]); // will print 'f'
printf("%c\n", *string); // will also print 'f'
printf("%c\n", string[1]); // will print the first 'o'
printf("%c\n", *(string + 1)); // will also print the first 'o'
with char * it goes like this
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main()
{
char string1[20];
int i, length;
int flag = 0;
printf("Enter a string: ");
scanf("%s", string1);
length = strlen(string1);
char *start=string1;
char *end=&string1[length-1];
//only check upto half
for(i=0;i <= (length-1)/2 ;i++)
{
if(toupper(*(start+i)) != toupper(*(end-i)))
{
flag = 1;
break;
}
}
if (flag)
printf("%s is not a palindrome \n\n", string1);
else
printf("%s is a palindrome \n", string1);
return 0;
}
cant we just copy the original string to another array, and then use strrev() to reverse the copied string and then finally compare the original string with the reversed string?
Like this
1.get new string
2.copy string to new array
3.reverse the copied string using strrev
4.use strcmp to check if both are same or not?
this seemed easier
(i am a beginner so please correct me if i am wrong)
I'm a beginner in C programming and I just started learning the concept of pointers. Could someone explain why my code ends in a segmentation fault while I think I'm doing it right?
Maybe I'm lacking some memory allocation concepts and I hope someone here could explain them in detail or point me to link where I can find explanations for problems like mine.
char strs(char *s, char *k)
{
int flag=0;
do
{
if(*k=='\0') return (*(s-flag));
if(*s==*k)
{
k++;
flag++;
}
if(flag!=0 && *s!=*k)
{
k=k-flag;
}
s++;
} while(*s!='\0');
return('\0');
}
main()
{
char s[10],k[5];
printf("Please enter the main string: ");
scanf("%s",s);
printf("Please enter the key string: ");
scanf("%s",k);
if((strs(s,k))!='\0') printf("The pointer is at <<<%s>>> in %s",strs(s,k),s);
if((strs(s,k)=='\0')) printf("\nKey string not found, value of strs is %s", strs(s,k));
}
Your strs function returns a char but you're trying to output it using the %s format specifier. To output a single char use %c:
printf("The pointer is at <<<%c>>> in %s",strs(s,k),s);