Reading multiple user input strings inside a loop - c

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

Related

Program to reverse a string in c, but its printing a at the /0 position

The program is as follows:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
setbuf(stdout,NULL);
int l,i;
char s[10],c;
printf("Enter the string: ");
gets(s);
l=strlen(s);
for(i=0;i<l/2;i++){
c=s[i];
s[i]=s[l-1-i];
s[l-1-i]=c;
}
printf("The reversed string is: %s ",s);
return EXIT_SUCCESS;
}
The output is:
Enter the string: hello world.
The reversed string is: hlrow olleo.
First of all, as mentioned by #Passerby, the gets function should no longer be used. Instead, you can use the fgets() function to take the input.
fgets(s, sizeof(s), stdin); // read string
Secondly, you are storing your input in an array of size 10, whereas your input string is of length 11. So, the 'd' of 'world' is not read at all. Change the array size to a bigger value and replace gets with fgets, and the problem will be fixed.
char s[15], c;
just try to increase the size of array of character bcoz the size of input string "hello world" is greater than 10 OR try to insert small string like "hi world"

Print a middle character of a string

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

How to add a string to a 2D array in C

i am starting to learn C and I have ran into the problem of adding a string input to a 2D array, i am able to get the string input correctly but when i try and add the string element to the array it is not working as expected.When printing the array(which is how i test the program) it will assign each index in the array a single character instead of the entire string.
And here is my code for viewing, thank you very much in advance i appreciate any help that is posted.
#include <stdio.h>
main()
{
char c_array[3][3];
int x;
int y;
int z=10;
int i_user_input;
char c_name[256];
for(x=0;x<=+2;x++)
{
for(y=0;y<=2;y++)
{
printf("\nPlease enter a name to the system:");
scanf(" %s",&c_array[x][y]);
printf("The string is %s\n",c_name);
printf("Please press '1' if you would like to keep entering names\n");
printf("Please press '2' if you would like to print the list of names:");
scanf("%d",&i_user_input);
if(i_user_input==1)
continue;
if(i_user_input==2)
for(x=0;x<=2;x++)
{
for(y=0;y<=2;y++)
{
printf("c_array[%d][%d]=%c\n",x,y,c_array[x][y]);
}
}
}
}
}
The output looks as follows with the sample input 'Penelope!'
c_array[0][0]=P
c_array[0][1]=e
c_array[0][2]=n
c_array[1][0]=e
c_array[1][1]=l
c_array[1][2]=o
c_array[2][0]=p
c_array[2][1]=e
c_array[2][2]=!
When you declare:
char c_array[3][3];
This means that each element of your 2D array is a "char" (a single character); not a "string of characters".
To have each element be a string of characters, you need to declare your array in the following way:
char string_array[3][3][256];
I am not sure this is what you want to do though. Mw feeling is that you want an array of 3 elements where each element is a string. In that case, [3] is hardly enough, your strings will have to be less than two characters (the third being reserved for the terminating zero).
Strings aren't a type. They're a value pattern, like if you say an int stores a multiple of ten, then it ends in 0... If you say an array of char stores a string, then it ends at the first '\0', see? We can store multiples of ten in different kinds of integer variables, and likewise for strings.
Strings are patterns of values, not types. When choosing which integer type we want to use, we consider the range for integers. We choose int for small integer values (less than 32768), long for larger values (less than 2147483648) or long long for values larger than that. As a result, we choose the correct type of integer depending on the multiple of ten we expect. Likewise for strings, we need to make sure we have enough memory for the characters in the string followed by the '\0' at the end.
The character &c_array[x][y] only has enough memory for 0 characters followed by a '\0' at the end; it's only useful for storing an empty string. Perhaps you meant to declare c_array like this:
char c_array[3][3][256];
In this case, scanf expects %s to correspond to an argument of the type char *... but as your compiler will probably warn you, &c_array[x][y] will have the type char (*)[256]. If you want to fix that warning, you'll need to remove the & from your scanf code:
if (scanf("%s", c_array[x][y]) != 1) {
/* XXX: Handle an error here, *
* e.g. by exiting or returning or something */
}
While we're on that topic, you'll notice that I removed the redundant space; %s already performs the functionality that the format directive would perform. I also wrote code to check the return value of scanf, as you should...
Remember how we spoke about choosing the types of integers that we use to store data? One other consideration is whether or not the data we intend to store can be negative. Consider this: In your code, should x and y be able to store negative values? What sense does a negative array index make? It is advisable that all array indexes be declared as size_t. When you use printf to print a size_t value, you'll want to use the %zu format specifier rather than %d.
char c_name[256];
/* ... */
printf("The string is %s\n",c_name);
Now, if the string is stored into c_array[x][y], then what is the point of c_name? That's an unnecessary variable. Use c_array[x][y], instead.
printf("\nPlease enter a name to the system:");
Common implementations will often refrain from printing characters until a '\n' is written; the line is printed all at once rather than character by character. As a result, you might see some strange behaviour such as this line not appearing at the right time. Fix this problem by putting the '\n' on the end of the line, rather than the beginning:
printf("Please enter a name to the system:\n");
... or use puts, which adds a '\n' for you automatically:
puts("Please enter a name to the system:");
... or use fflush, which will write all pending unwritten data even if there is no '\n':
fflush(stdout);
In your code
scanf(" %s",&c_array[x][y]);
printf("The string is %s\n",c_name);
both the statements are wrong.
%s expects a pointer to an array, not a single char. To scan a single char, you need %c format specifier.
c_name, as used in the printf() is uninitialised. Using uninitialised value invokes undefined behaviour.
Solution: To take input element by element, you can do do something like
for(x=0; x<=2 ;x++)
{
printf("Start entering the name, one character at a time\n");
for(y=0; y< 2; y++) //note only '<' here
{
scanf(" %c", &c_array[x][y]); // note the leading space
}
c_array[x][y] = 0; //null termination of array to be used as string
}
If you want to assign a string to each index in the array, then create the array as follows :
#include<stdio.h>
int main(void)
{
char a[2][10];
int i=0;
char temp[20];
for(i=0;i<2;i++)
{
scanf("%s",temp);
strcpy(a[i],temp);
}
printf("%s",a[0]);
return 0;
}
Each string that you enter will be stored in each index of the array.
#include <stdio.h>
#include <string.h>
int main(void){
char c_array[3][3];
int x;
int y;
//int z=10;//unused
int i_user_input;
char c_name[256];
printf("\nPlease enter a name to the system:");
scanf("%255s",c_name);
printf("The string is %s\n",c_name);
printf("Please press '1' if you would like to keep entering names\n");
printf("Please press '2' if you would like to print the list of names:");
scanf("%d", &i_user_input);
if(i_user_input==1)
;
else if(i_user_input==2){
memcpy(c_array, c_name, sizeof(c_array));
for(x=0;x<3;x++){
for(y=0;y<3;y++){
printf("c_array[%d][%d]=%c\n", x, y, c_array[x][y]);
}
}
}
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 3
int main(void){
char *c_array[SIZE][SIZE] = { NULL };
int x;
int y;
//int z=10;//unused
int i_user_input;
char c_name[256];
for(x=0;x<SIZE;x++){
for(y=0;y<SIZE;y++){
printf("\nPlease enter a name to the system:");
scanf("%255s", c_name);
printf("The string is %s\n", c_name);
printf("Please press '1' if you would like to keep entering names\n");
printf("Please press '2' if you would like to print the list of names:");
scanf("%d", &i_user_input);
c_array[x][y] = strdup(c_name);
if(i_user_input==1){
continue;
}
if(i_user_input==2){
int x, y;//local variable
for(x=0;x<SIZE;x++){
for(y=0;y<SIZE;y++){
if(c_array[x][y] != NULL)
printf("c_array[%d][%d]=%s\n", x, y, c_array[x][y]);
}
}
}
}
}
for(x=0;x<SIZE;x++)
for(y=0;y<SIZE;y++)
free(c_array[x][y]);
}
Why not use pointers in you array/matrix?
#include <stdio.h>
#include <string.h>
main()
{
char *c_array[3][3];
int x;
int y;
int z=10;
int i_user_input;
char c_name[256];
for(x=0;x<=+2;x++)
{
for(y=0;y<=2;y++)
{
printf("\nPlease enter a name to the system:");
scanf(" %s",c_name);
new_string = malloc(strlen(c_name)+1)
if (new_string == NULL) {
print("error allocating string\n")
exit(-1);
}
strcpy(new_string, c_name);
c_array[x][y] = new_string
printf("The string is %s\n",c_name);
printf("Please press '1' if you would like to keep entering names\n");
printf("Please press '2' if you would like to print the list of names:");
scanf("%d",&i_user_input);
if(i_user_input==1)
continue;
if(i_user_input==2)
for(x=0;x<=2;x++)
{
for(y=0;y<=2;y++)
{
printf("c_array[%d][%d]=%c\n",x,y,c_array[x][y]);
}
}
}
}
for(x=0;x<=2;x++) {
for(y=0;y<=2;y++) {
free(c_array[x][y])
}
}
}
The code above stores the input string in each cell of the array, if that is your goal.
Note: I have no tried it, so there may be subtle errors. My point is to show you how to use pointers and their equivalence to arrays. Using C without pointers is pointless. :)

Reading string from input with space character? [duplicate]

This question already has answers here:
How do you allow spaces to be entered using scanf?
(11 answers)
Closed 4 years ago.
I'm using Ubuntu and I'm also using Geany and CodeBlock as my IDE.
What I'm trying to do is reading a string (like "Barack Obama") and put it in a variable:
#include <stdio.h>
int main(void)
{
char name[100];
printf("Enter your name: ");
scanf("%s", name);
printf("Your Name is: %s", name);
return 0;
}
Output:
Enter your name: Barack Obama
Your Name is: Barack
How can I make the program read the whole name?
Use:
fgets (name, 100, stdin);
100 is the max length of the buffer. You should adjust it as per your need.
Use:
scanf ("%[^\n]%*c", name);
The [] is the scanset character. [^\n] tells that while the input is not a newline ('\n') take input. Then with the %*c it reads the newline character from the input buffer (which is not read), and the * indicates that this read in input is discarded (assignment suppression), as you do not need it, and this newline in the buffer does not create any problem for next inputs that you might take.
Read here about the scanset and the assignment suppression operators.
Note you can also use gets but ....
Never use gets(). Because it is impossible to tell without knowing the data in advance how many characters gets() will read, and because gets() will continue to store characters past the end of the buffer, it is extremely dangerous to use. It has been used to break computer security. Use fgets() instead.
Try this:
scanf("%[^\n]s",name);
\n just sets the delimiter for the scanned string.
Here is an example of how you can get input containing spaces by using the fgets function.
#include <stdio.h>
int main()
{
char name[100];
printf("Enter your name: ");
fgets(name, 100, stdin);
printf("Your Name is: %s", name);
return 0;
}
scanf(" %[^\t\n]s",&str);
str is the variable in which you are getting the string from.
The correct answer is this:
#include <stdio.h>
int main(void)
{
char name[100];
printf("Enter your name: ");
// pay attention to the space in front of the %
//that do all the trick
scanf(" %[^\n]s", name);
printf("Your Name is: %s", name);
return 0;
}
That space in front of % is very important, because if you have in your program another few scanf let's say you have 1 scanf of an integer value and another scanf with a double value... when you reach the scanf for your char (string name) that command will be skipped and you can't enter value for it... but if you put that space in front of % will be ok everything and not skip nothing.
NOTE: When using fgets(), the last character in the array will be '\n' at times when you use fgets() for small inputs in CLI (command line interpreter) , as you end the string with 'Enter'. So when you print the string the compiler will always go to the next line when printing the string. If you want the input string to have null terminated string like behavior, use this simple hack.
#include<stdio.h>
int main()
{
int i,size;
char a[100];
fgets(a,100,stdin);;
size = strlen(a);
a[size-1]='\0';
return 0;
}
Update: Updated with help from other users.
#include <stdio.h>
// read a line into str, return length
int read_line(char str[]) {
int c, i=0;
c = getchar();
while (c != '\n' && c != EOF) {
str[i] = c;
c = getchar();
i++;
}
str[i] = '\0';
return i;
}
Using this code you can take input till pressing enter of your keyboard.
char ch[100];
int i;
for (i = 0; ch[i] != '\n'; i++)
{
scanf("%c ", &ch[i]);
}
While the above mentioned methods do work, but each one has it's own kind of problems.
You can use getline() or getdelim(), if you are using posix supported platform.
If you are using windows and minigw as your compiler, then it should be available.
getline() is defined as :
ssize_t getline(char **lineptr, size_t *n, FILE *stream);
In order to take input, first you need to create a pointer to char type.
#include <stdio.h>
#include<stdlib.h>
// s is a pointer to char type.
char *s;
// size is of size_t type, this number varies based on your guess of
// how long the input is, even if the number is small, it isn't going
// to be a problem
size_t size = 10;
int main(){
// allocate s with the necessary memory needed, +1 is added
// as its input also contains, /n character at the end.
s = (char *)malloc(size+1);
getline(&s,&size,stdin);
printf("%s",s);
return 0;
}
Sample Input:Hello world to the world!
Output:Hello world to the world!\n
One thing to notice here is, even though allocated memory for s is 11 bytes,
where as input size is 26 bytes, getline reallocates s using realloc().
So it doesn't matter how long your input is.
size is updated with no.of bytes read, as per above sample input size will be 27.
getline() also considers \n as input.So your 's' will hold '\n' at the end.
There is also more generic version of getline(), which is getdelim(), which takes one more extra argument, that is delimiter.
getdelim() is defined as:
ssize_t getdelim(char **lineptr, size_t *n, int delim, FILE *stream);
Linux man page
If you need to read more than one line, need to clear buffer. Example:
int n;
scanf("%d", &n);
char str[1001];
char temp;
scanf("%c",&temp); // temp statement to clear buffer
scanf("%[^\n]",str);
"%s" will read the input until whitespace is reached.
gets might be a good place to start if you want to read a line (i.e. all characters including whitespace until a newline character is reached).
"Barack Obama" has a space between 'Barack' and 'Obama'. To accommodate that, use this code;
#include <stdio.h>
int main()
{
printf("Enter your name\n");
char a[80];
gets(a);
printf("Your name is %s\n", a);
return 0;
}
scanf("%s",name);
use & with scanf input

Problem with scanf and fgets

This is for a homework assignment to sort some given strings. I'm prompting the user for the number of strings they'd like to sort with scanf, allocating an array based on that number, and then getting the strings themselves with fgets.
Everything works fine if the number of strings is hardcoded, but the addition of scanf to let the user decide screws things up. Here's the code:
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#define LENGTH 20 // Maximum string length.
int main(void)
{
int index, numStrings = 0;
char **stringArray;
printf("Input the number of strings that you'd like to sort: ");
assert(scanf("%d", &numStrings) == 1);
stringArray = (char **)malloc(numStrings * sizeof(char *));
for (index = 0; index < numStrings; index++)
{
stringArray[index] = (char *)malloc(LENGTH * sizeof(char));
assert(stringArray[index] != NULL);
printf("Input string: ");
assert(fgets(stringArray[index], LENGTH, stdin) != NULL);
}
// Sort strings, free allocated memory.
return 0;
}
And here's what the console looks like:
Input the number of strings that you'd like to sort: 3
Input string: Input string: foo
Input string: bar
It skips over the first iteration of the loop, resulting in an empty string at the beginning of the array. My question is, why does it do that, and how can I fix it?
Here's what the console looks with the format string "%d\n" passed to scanf:
Input the number of strings that you'd like to sort: 3
foo
Input string: Input string: bar
Input string: baz
So, I can input all of the strings, but the first prompt for a string is in the wrong place.
You have to tell scanf to clobber the \n by putting \n in the scanf:
scanf("%d\n", &numStrings)
without it, scanf will read the residual newline character [from when the enter button was hit] as the first line in the loop
The real answer (in my humble but ever-so-correct opinion :P) is not to use scanf. Use fgets to read the first line (i.e. the number) and then parse that string yourself with, say, sscanf or strtoul. That way you have the ability to handle errors when someone doesn't input the data in a nice format, and you don't have to hack around scanf's lack of robust whitespace handling.
Also, never used an int to store sizes unless you expect to have a lot of arrays with -4 length. The standard specifies the unsigned type size_t as an unsigned type that is large enough to store object sizes and array indices. Using any other type isn't guaranteed to work.

Resources