This question already has answers here:
Why does scanf ask twice for input when there's a newline at the end of the format string?
(7 answers)
Closed 5 years ago.
I am trying to simply get a user input string. The string is saved (scanf) when the person hits enter or the string hits the NULL character. Yet, when I run my program, and type in the string, it continues input until I type \n or \0 (whichever I have in my if statement. Here's my code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MSL 30
char intersperse(char);
char widen_stars(char);
int main(int argc, char *argv[])
{
char *p, *q, *str1[MSL], *str2[MSL];
if(str1[MSL+1] != '\0'){
printf("Please enter a string of maximum 30 characters: ");
scanf("%s\n", str1[MSL]);
}
printf("%s\n", str1[MSL]);
}
This is by no means finished code, i'm just in the process of writing my program when I snagged this annoying bug. The +1 on my MSL is to make sure the NULL character is read so my string doesn't yell at me, idk if it's necessary, but it's a precaution. Thank you answerers.
There are various problems with your code, not just a simple bug. I'll try to describe some of them here.
Turn on compiler warnings. For example, if your array is size 30, there is no element at index 30 (indexes would go from 0 to 29). Your compiler could have warned you about that and other problems.
Store a string in a char array or pointer, but not in a char pointers array. When you wrote:
char *str1[MSL]
You are creating an array of pointers to char, or an array of strings. However, since you're dealing with pointers to char as strings, you'd need to allocate space for them yourself. That's another concept. You probably meant to write an array of char like this:
char str1[MSL]
char *p, *q, str1[MSL], str2[MSL]; /* in your declaration */
Enter at maximum 29 characters. If your string holds 30 char, and you need 1 to mark the null at the end, you've got 29 remaining usable chars. Or… change MSL to 31.
Consider dropping the \n from your scanf format. It will make it read all whitespace (which is what \n represents in a format) waiting for the next non-whitespace. Thus, the input somestring<enter> for example won't be sent directly to your program until the next non-whitespace or EOF.
Give scanf an address. That could be just the array name (which translates to the first element address) or a pointer if you were working with them.
scanf("%s", str1);
scanf("%s", strptr); /* strptr is a char pointer pointing
to previously allocated space */
You can limit the length of what scanf reads. To be safe:
scanf("%29s", str1);
Don't use uninitialised data in comparisons. When you wrote if(str1[MSL+1] != '\0'), what did you expect str1 to contain if you had never stored anything yet?
int
main(int argc, char **argv)
{
char *p, *q, str1[31], str2[31]; /* a lot of unused variables */
printf("Please enter a string of maximum 30 characters: ");
scanf("%30s", str1);
printf("%s\n", str1);
return 0;
}
Related
I must write a program in C that can print the middle letter of the string you entered. Spaces () are also calculated, and the number of characters must be odd.
Ex. Input
Hi sussie
--> 9 characters, including space
The output should be s.
I have tried this:
#include <stdio.h>
#include<string.h>
char x[100];
int main(void)
{
printf("Hello World\n");
scanf("%c\n",&x);
long int i = (strlen(x)-1)/2;
printf("the middle letter of the word is %c\n",x[i]);
return 0;
}
and the output always shows the first letter of the word I have entered.
You're only reading the first character from stdin (and incorrectly; you shouldn't be using &).
If you must use scanf, you should use this format:
scanf("%99[^\n]", x);
This is safe and doesn't read past the buffer.
Note that %s wouldn't work here. %s causes scanf to interpret whitespace as the end of the string.
A much better, safer, and easier solution would be to use fgets instead of scanf; fgets is safer and it doesn't require you to change a format string when you change the size of your array:
fgets(x, sizeof(x)-1, stdin);
This eliminates any possible issues with whitespace or buffer overflow.
int main()
{
char arr[1024];
char a;
int i,counter=0;
printf("enter string :: ");
fgets(arr,sizeof(arr),stdin);
for(i=0;i<strlen(arr);i++)
counter++;
for(i=0;i<strlen(arr);i++)
{
if(i==(counter/2))
printf("%c\n",arr[i]);
}
return 0;
}
I can't take inputs except string.
If I give inputs in code itself, program is working.
But when I try to take inputs, its not working.
How do I get it to accept given inputs?
For example, if s were "codebook", and from == 'o' and to == 'e', s would become "cedebeek".
#include<stdio.h>
#define MAX 50
void replace(char *s, char from, char to)
{
int i=0;
while(s[i]!='\0')
{
if(s[i]==from)
{
s[i]=to;
}
i++;
}
}
int main()
{
char str[MAX];
char from;
char to;
printf("Enter the string");
scanf("%[^\n]s",&str[0]);
printf("\nEnter the character to be replaced");
scanf("%c",&from);
printf("\nEnter the character to be replaced with");
scanf("%c",&to);
replace(str, from, to);
printf("\nThe modified string is %s",str);
return(0);
}
There are a couple of problems in the posted code. Since arrays decay to pointers to their first elements in most expressions, there is no need for the address operator & in the call to scanf(); also, the trailing s is not part of the scanset conversion specifier:
scanf("%[^\n]", str);
As pointed out by #M.M in the comments, it is not incorrect to use &str[0] here instead of str, but it is more idiomatic, and I personally find it more clear, to use the less cluttered str.
When scanf() returns, a newline character will be left in the input stream, so you should add a leading space in the next call to scanf() to skip over this \n character before reading the user input:
scanf(" %c",&from);
And this call to scanf() will also leave a \n character in the input stream, so again:
scanf(" %c",&to);
Note that you should really specify a maximum width to avoid buffer overflow when reading user input into a string; there is no easy way to do this with MAX, but you can do:
scanf("%49[^\n]", str);
You could further improve code and ensure that input is as expected by checking the values returned by the calls to scanf().
I am currently trying to solve a problem from CodeChef but I am having troubles with using fgets() inside a loop.
The first input (T) is going to be a positive integer containing the number of user inputs.
Then delimited by newline characters, the user is going to input a string below the length of 10 under any circumstances.
So, I've tried this:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
int main()
{
int T;
int diffX, diffY;
char s[SIZE];
scanf("%d", &T);
while (T--){
fgets(s, SIZE, stdin);
printf("%s\n", s);
}
return 0;
}
However, when I attempted to test the code with the following inputs:
3 Hello Hi What
I was only able to input until "Hi" then the program exited successfully (returning 0).
Why is this the case and how can I fix it?
Thank you in advance,
kpark.
fgets() consumes the newline left behind by the first call to scanf(). So, it is consuming 3 lines, but the first line looks like an empty line to the fgets() loop you have.
You can fix this by using fgets() to get the first line too, and parse the string into a number using sscanf().
fgets(s, SIZE, stdin);
sscanf(s, "%d", &T);
/* ... */
It is counting the read of the T as part of the counting. Add a newline in the scanf.
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
int main()
{
int T;
int diffX, diffY;
char s[SIZE];
scanf("%d\n", &T);
while (T--){
fgets(s, SIZE, stdin);
printf("%s\n", s);
}
return 0;
}
Is your Question is about how to read Multiple Strings in C ?
Then it can be done by 2 ways :-
1.By declaring two dimensional Array of characters.
//Let say we want 6 strings each of them having max 10 characters.
char set[6][10] ;
for(int i=0;i<6;i++)
scanf("%s",set[i])
2.By declaring one dimensional Array of pointers to character (Notice the naming Conventions), in which each of those pointer pointing to a String.
int main(){
int i,numOfStrings;
char temp[30];
printf("Enter Number of strings in set ");
scanf("%d",&numOfStrings);
//Here We have defined array of pointer that will store each string sepratly.
//Arry of pointer to character.
char *setOfStrings[numOfStrings];
for(i=0;i<numOfStrings;i++)
{
printf("Enter string ");
scanf("%s",temp);
setOfStrings[i]= (char*)malloc(sizeof(temp)); //allocted new memory and gave it to array of pointer
strcpy(setOfStrings[i],temp);
}
for(i=0;i<numOfStrings;i++)
{
printf("string = %s \n",setOfStrings[i]);
}
return 0;
}
But that need to understand :
In case of array of pointers we may initialize them with String but Can't take as input from Command line like
char *set[2]={"Dinesh","Kandpal"}; //Its valid but you can't do this from command line
for doing so What we do we will create an space dynamically ,store that address in the one of the element in 1-D array of pointers and then whatever value we have scanned copy that content to the another string to the location that we created using malloc
This is part of an assignment that I'm supposed to submit, this program is supposed to take 2 inputs, a name containing 4 letters and a city containing 5 letters then sub them in that sentence. The problem is that the first word is not being output properly, like if I type john all I get is 'r' instead of the word. I'm new to this and there might be other mistakes, but I wanna fix this one. Help greatly appreciated. :l
#include <stdio.h>
int main(int argc, char **argv)
{
char name1[4];
char city1[5];
printf("\nEnter four letter name:\n");
scanf("%s", name1);
printf("\nEnter five letter city:\n");
scanf("%s", city1);
printf("%s was afraid of the airplane, he walked from %s to Romaine.", name1, city1);
return 0;
}
When I put John and Denver it output "r was afraid of the airplane he walked from Denver to Romaine"
Aham, so this is a buffer overflow. What you should do is:
I. Allocate two reasonably long buffers. 4 and 5 just make me cry. There's a LINE_MAX macro in <limits.h> which may be useful.
II. Use a safe function that lets you specify how big your buffer is. For example, fgets() is an excellent function for inputting a line of text. Using it also has the benefit that it really always reads an entire line (if the buffer passed to it is large enough). scanf() requires some messing with the %s conversion specifier before you can make it accept whitespace and stuff.
char name[LINE_MAX];
char city[LINE_MAX];
fgets(name, sizeof name, stdin);
fgets(city, sizeof city, stdin);
#include <stdio.h>
int main(int argc, char **argv)
{
char name1[8];
char city1[8];
printf("\nEnter four letter name:\n");
scanf("%s", name1);
printf("\nEnter five letter city:\n");
scanf("%s", city1);
printf("%s was afraid of the airplane, he walked from %s to Romaine.", name1, city1);
return 0;
}
The solution: Make sure the character arrays are large enough for the input.
scanf is an unsafe function as it will fetch data from its input stream and copy it past the end of the buffer you provide if it's not large enough. In addition it will place a nul terminating character at the end of the copied string.
In your example John requires at least 5 characters while Denver at least 7 because you must account for the terminating character.
You should consider using a larger buffer for both strings, or as a better alternative, write your own function which uses a buffer to store the string and then copies it to the final destination buffer (assuming length is enough, truncating otherwise).
Take a look at this answer: How to prevent scanf causing a buffer overflow in C?, there are some common work arounds for your problem.
I am trying to input 2 strings in C, and output a 3rd string which the concatenation of string 1 and 2.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
*
*/
int main(int argc, char** argv) {
char stringarray1 [30];
char stringarray2 [30];
char stringarray3 [30];
int length;
printf("Please enter some text less than 30 characters long\n");
scanf("%[a-z, ]", &stringarray1);
printf("Please enter some text less than 30 characters long\n");
scanf("%[a-z, ]", &stringarray2);
strcat(stringarray1, stringarray2);
//length = strlen(stringarray);
printf("The combined string is %s\n", stringarray1);
return (EXIT_SUCCESS);
}
It allows me to input the first string, but then prints the seond and third printf statement, without allowing me to enter the second string.
How can i enter the second string without it exiting? Why does it exit?
Have a look at the documentation of scanf: Your format string "%[a-z, ]" does not what you seem to think what it does. Just use "%s" for strings instead. (It's without any character checks).
You should not put the & for your arrays that are already pointers.
scanf("%[a-z, ]", stringarray2);
At a guess, I'd say you need a \n inside your scanf specification strings. You should probably also be asking for %s instead of %[a-z, ]. The way you have it a single character would match, then when the second scanf is hit, the next character would match.
Also there are some safety issues. You should probably be checking to make sure both strings together aren't larger than 30 chars. As Benoit pointed out, arrays in C also double as pointers to the first character, so you don't use the address-of operator (&) on them when passing them to the C IO routines. That would give the routine the address of your array pointer itself, which the IO routine would then merrily wipe out with character data. Not good!
You know the difference between an chararray a stringarray? I think not. Also you must allocate enough space for you result-string, like:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
*
*/
int main(int argc, char** argv) {
char chararray1 [31];
char chararray2 [16];
char chararray3 [30];
int length;
printf("Please enter some text less than 15 characters long\n");
scanf("%15[a-z, ]", stringarray1);
printf("Please enter some text less than 15 characters long\n");
scanf("%15[a-z, ]", stringarray2);
strcat(stringarray1, stringarray2);
//length = strlen(stringarray);
printf("The combined string is %s\n", stringarray1);
return (EXIT_SUCCESS);
}
I would recommend using fgets instead of scanf, that you can specify a max length (buffer target size - 1) and avoid surprises.
also the target buffer should be twice the size of your input buffers otherwise you risk a memory overwrite