Why is the & operator used after using scanf? [closed] - c

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);

Related

Read string with scanf() without knowing the length [duplicate]

This question already has answers here:
How can I read an input string of unknown length?
(11 answers)
Closed 8 months ago.
I want to read a string (str) from the user and a number (num) via scanf() but I don't know how to initialize str correctly.
int main(void)
{
char *str = NULL;
int num;
scanf("%s %d", str, &num);
printf("str: %s\nnum: %d\n", str, num);
}
If I do it like this I get a segmentation fault.
My problem is that I don't know the length of str so I can't say something like this:
char str[20];
and I'm also not allowed to hardcode some high amount of index e.g.:
char str[999];
My question now: How can I initialize str in this case?
Some implementations provide for a %ms specifier to allocate memory as required by the POSIX specification of scanf(). Even some Unix-like systems (e.g. macOS Monterey 12.x and earlier) do not provide it.
If that is available (check the manual), this will work.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char *str = NULL;
int num;
scanf("%ms %d", &str, &num);
printf("str: %s\nnum: %d\n", str, num);
free(str);
return 0;
}
To capture a string that includes space and tab, but no digits,
scanf("%m[^\n0123456789] %d", &str, &num);
could be used

This C program is not executing [closed]

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
I have this simple C program, It compiles successfully but It does not execute perfectly. It takes the input and closed after a while. I don't know, why it is not displaying output?
Please help me...
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
char str1[200], str2[200];
system("cls");
printf("<==== Enter two strings ====>\n");
printf("First: ");
scanf("%s", &str1);
printf("Second: ");
scanf("%s", &str2);
char txt1[] = "\nThe string \" ";
char txt2[] = " \"and \"";
char txt3[] = " not equal.";
strcat(strcat(strcat(strcat(txt1, str1), txt2), str2), txt3);
if(strcmp(str1, str2) != 0)
{
printf("%s", txt2);
}
else
{
printf("\nString 1 and string 2 are equal.");
}
getch();
}
Passing pointers to arrays to scanf() invokes undefined behavior because it is not it excepts. & should be removed and pointers to char should be passed. Using %d with char* also invokes undefined behavior. int* should be passed for that.
txt1 has no room for extra things, so the strcat() will cause out-of-range access, which also invokes undefined behavior. You should specify the number of elements explicitly to allocate enough elements.
(optional) You should specify the maximum length to read in %s for avoiding buffer overrun.
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
char str1[200], str2[200];
system("cls");
printf("<==== Enter two strings ====>\n");
printf("First: ");
scanf("%199s", str1); /* remove & and add length limit */
printf("Second: ");
scanf("%199s", str2); /* remove & and use correct specifier */
char txt1[512] = "\nThe string \" "; /* allocate enough elements */
char txt2[] = " \"and \"";
char txt3[] = " not equal.";
strcat(strcat(strcat(strcat(txt1, str1), txt2), str2), txt3);
if(strcmp(str1, str2) != 0)
{
printf("%s", txt2);
}
else
{
printf("\nString 1 and string 2 are equal.");
}
getch();
}

C - Dynamic Memory Allocation [duplicate]

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

Reverse of a string using pointers without using string handling functions? [closed]

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);

Safely get string input from user including spaces [duplicate]

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.

Resources