I'm a beginner in C and am currently experiencing some troubles invovling chars.
I'm having an issue trying to enter values in a char matrix and then print it.
Here's my code:
#include <stdio.h>
#define N 3
int main( )
{
char arr[N][N]={{0}};
int i,j;
for(i=0;i<N;i++){
for(j=0;j<N;j++){
scanf("%c",&arr[i][j]);
}
}
for(i=0;i<N;i++){
for(j=0;j<N;j++){
printf("%c",arr[i][j]);
}
}
return 0;
}
There are two chars that are missing at the end of the output.
I don't know what I'm doing wrong and I would like to understand my mistake:
-Is it some kind of problem involving the scanf fonction? I've heard about the buffer before, is that related? Is the problem coming from the moment I press enter?
-Am I initializing my matrix in a wrong way?
-Is it better to use getchar() in this situation? If so, how can I manage to enter exactly N*N values and not more?
Thanks a lot.
Jordan.
You should use " %c" to accept char as input. When you add a space before "%c" it consumes white-spaces (newline, tab, space, etc.) entered with previous inputs.
#include <stdio.h>
#define N 3
int main() {
char arr[N][N]={{0}};
int i,j;
for(i=0;i<N;i++){
for(j=0;j<N;j++){
scanf(" %c",&arr[i][j]);
// ^ --- the space before %c
}
}
for(i=0;i<N;i++){
for(j=0;j<N;j++){
printf("%c ",arr[i][j]);
}
printf("\n");
}
return 0;
}
Input:
a b c d e f g h i
You can also input these characters one by one using Enter or Return button.
Output:
a b c
d e f
g h i
You may also check this post which addresses the same issue.
Another way to do this.. Add getchar(); statement after scanf() statement.
for(i=0;i<N;i++){
for(j=0;j<N;j++){
scanf("%c",&arr[i][j]);
getchar();
}
}
getchar() will consume tailling new lines.
In this case, just enter the 9 characters in sequence without pressing enter button like
123456789\n
because putting a newline character after each character is stored in one of character index becuase \n is a character itself which surely you don't want to be entered like this
1\n2\n3\n4\n5\
In above case only 5 characters would be taken from user intentionally.
Related
Trying to take strings as input and place it in 2d array. Why is this given code showing different behavior. The last for loop "arr[i][j]" is not printing the string.It is not even printing a character also.
Why this code does not work.only this code.Not a new way to write it
This code takes input just fine(or at least the way needed.each row a single string no white space)And when a short string is stored remaining are filled with null after carriage return. When the arr[] is passed in last for loop everything seems fine only when arr[][] is passed ,the problem arises.But again arr[][] is initialized as arr[1][0] then arr[2][0] so should not it work!
#include <stdio.h>
#include <stdbool.h>
int main(void){
int i,j,m;
scanf("%d",&m);
char arr[m][50];
for(i=0;i<m;i++){
for(j=0;j<50;j++){
printf("please enter a string");
scanf("%s",&arr[i][j]);
/*j is always 0. arr[i] takes string without space and store ending with null*/
break;
}
}
//Everything fine upto this,including storing a small continuous string in arr[i](where i<50) and null terminating*/
for(i=0;i<m;i++){
for(j=0;j<50;j++){
printf("%s\n",arr[i][j]);
break;
}
}
}
You program has several issues, like using wrong format specifier:
scanf("%s",&arr[i][j]);
arr[i][j] is a character and you are using %s format specifier. If you want your program should take string as input, you just need to do:
scanf("%s",arr[i]);
Since, you have given the size 50 characters, put a restriction in scanf() to not to read more than 49 characters (the remain one character space is for null terminating character) like this:
scanf("%49s",arr[i]);
^^
Beware with this, it does not discard the remaining input from input stream when the input characters are more than 49 and the remaining characters will be consumed by consecutive scanf() call.
If you want to drop the extra input which wasn't consumed by scanf(), one way of doing it is to read and discard the extra input using a loop, like this:
int c;
while((c = getchar()) != '\n' && c != EOF)
/* discard the character */;
In case if you have any doubt on how this will discard the extra input, I would suggest first go through getchar().
Putting all these together, you can do:
#include <stdio.h>
int main(void){
int i,m;
scanf("%d",&m);
char arr[m][50];
for(i=0;i<m;i++){
printf("please enter a string");
scanf("%49s",arr[i]);
int c;
while((c = getchar()) != '\n' && c != EOF) // <=== This loop read the extra input characters and discard them
/* discard the character */;
}
for(i=0;i<m;i++){
printf("%s\n",arr[i]);
}
return 0;
}
EDIT
The below edit is because OP updated question and added - Why this code does not work.only this code.Not a new way to write it
Above in my answer, I have already stated that you are using wrong format specifier in the scanf(). In this part of your code:
for(i=0;i<m;i++){
for(j=0;j<50;j++){ // <====== Nested for loop
printf("please enter a string");
scanf("%s",&arr[i][j]);
// since the nested loop is supposed to run 50 times, assuming you are trying to read character by character and using %s format specifier
break;
// the nested loop will break in the first iteration itself unconditionally, do you really need nested loop here!
}
}
Check the inline comments. Hope this might give an idea of the mistakes you are doing.
Seems that you want to read string character by character using scanf(). If this is the case than make sure to take care of null terminating character because, in C, strings are actually one-dimensional array of characters terminated by a null character '\0'.
You can do:
#include <stdio.h>
void discard_extra_input() {
int c;
while((c = getchar()) != '\n' && c != EOF)
/* discard the character */;
}
int main(void){
int i,j,m;
printf ("Enter number of strings: ");
scanf("%d",&m);
discard_extra_input();
char arr[m][50];
for(i=0;i<m;i++){
printf("please enter string number %d: ", i+1);
for(j=0;j<49;j++){
scanf("%c",&arr[i][j]);
if (arr[i][j] == '\n') {
//need to add null terminating character manually
arr[i][j] = '\0';
break;
}
}
if (j==49) {
// In case where the input from user is more than 50 characters,
// need to add null terminating character manually.
arr[i][j] = '\0';
// discard the extra input when input from user is more than 50 characters.
discard_extra_input();
}
}
for(i=0;i<m;i++){
for(j=0;j<50 && arr[i][j]!='\0';j++){
printf("%c",arr[i][j]);
}
printf ("\n");
}
return 0;
}
The code is self explanatory except one thing - call to discard_extra_input() function after first input from user scanf("%d",&m);. Reason -
Look at the statement:
scanf("%c",&arr[i][j]);
the %c format specifier will consume the leftover newline character '\n' from the input stream due to the ENTER key pressed after first input by the user (number of strings input from user). Hence, in order to discard it, calling discard_extra_input() function. In the other place it has been used to discard the characters when user entered string of size more than 49.
Hope this helps.
I know the code. But looking for specific ans. Where the problem lies with the code
The problem is here:
scanf("%s",&arr[i][j]);
and here:
printf("%s", arr[i][j]);
This is the specific answer you are looking for.
%s won't do any bound checking. It adds the characters starting from the memory location arr + i * m + j to arr + i * m + j + (length of input) + 1 (one extra char for the additional null character that scanf appends). Take a sample input. Assume an arbitrary starting address for arr and do the maths.
Also consider any writes beyond the allocated space for arr leads to undefined behavior.
Similarly printf("%s", arr[i][j]); will try to start reading from the address arr[i][j] till it finds a null character. It would usually lead to crash of the code because if your string has ascii characters, the address would be too low to point to any valid user-mapped memory.
If your code is working, its mostly because you already have a UB in your scanf.
Get a pen and paper and do some dry runs
This is a pretty simple problem buddy. You've got the idea right actually, that you need to use 2d array to store strings. Just that the usage is slightly wrong.
First of all let me tell you how 2d arrays need to be used to store in c. In your 2-D array, you've got rows and columns. Say, row represented by i and columns by j, i.e, each row arr[i] contains j elements. So in your context, each row arr[i] contains each string of upto 50 chars. So scanf should be just for arr[i]. And you need to loop with for, m times to accept m strings.
Same applies to printing as well.
Here is the working code:
#include <stdio.h>
#include <stdbool.h>
int main(void){
int i,j,m;
printf("\nenter m value:");
scanf("%d",&m);
char arr[m][50];
for(i=0;i<m;i++){
printf("\nplease enter a string no %d: ", (i+1));
scanf("%s",arr[i]);
}
printf("\nthe strings are: \n");
for(i=0;i<m;i++){
printf("\n%s\n",arr[i]);
}
}
And the output in case you want to cross check:
OUTPUT:
enter m value: 3
please enter a string no 1: qwerty
please enter a string no 2: asdfgh
please enter a string no 3: zxcvbn
the strings are:
qwerty
asdfgh
zxcvbn
Hey I don't understand why my its taking two inputs while taking the element as input . I tried this code on TurboC compiler , GCC but got the same error .
#include <stdio.h>
int menu();
void bubble_short();
void selection_short();
int main()
{
int ch,j,n,a[100];
ch=menu();
switch (ch)
{
case 1:
{
bubble_short();
break;
}
case 2:
{
selection_short();
}
default :
break;
}
}
void bubble_short()
{
int i,j,n,a[100];
printf("Elements");
scanf("%d",&n);
for (j=0; j<n;j++)
{
scanf("%d",&a[j]);
}
for (i=0;i<n;i++)
{
for (j=0;j<n-1-i;j++)
{
if (a[j]>a[j+1])
{
a[j]=a[j]+a[j+1];
a[j+1]=a[j]-a[j+1];
a[j]=a[j]-a[j+1];
}
}
}
printf("the sorted elements are :\n");
for ( i = 0; i < n; i++)
{
printf("%d\n",a[i]);
}
}
void selection_short()
{
int i,j,n,a[100],min;
printf("Elements");
scanf("%d",&n);
for ( i = 0; i <n-1; ++i)
{
min=i;
for ( j = 1+i; i < n; ++i)
{
if(a[min]>a[j])
min=j;
}
if(i!=min)
{
a[i]=a[i]+a[min];
a[min]=a[i]-a[min];;
a[i]=a[i]-a[min];;
}
}
printf("the shorted elements are :\n");
for ( i = 0; i < n; ++i)
{
printf("%d\n",a[i] );
}
}
int menu()
{
int k;
printf("Enter the choice \n 1. bubble short \n 2. selectionshort");
scanf("\n %d ",&k);
return k;
}
Hey I don't understand why my it's taking two inputs while taking the element as input. I tried this code on TurboC compiler, GCC but got the same error.
Output
Got your problem!
Never use newlines, whitespace, tabs and return carriages inside scanf as to avoid such problems and maintaining good coding guidelines! These act as delimiters for it and you have provided 3 of them.
Edit your menu scanf to this:-
scanf("%d",&k);
A basic logic behind it:- Taking a basic example :-
scanf("%d %d", &i, &j);
Notice that space between two placeholders. When you run this, it will take the first input and then it will wait for that delimiter to be read from the keyboard and afterwards it will read the second parameter of the input.
I think the rest of the program should run fine.
In the menu() function, you have:
scanf("\n %d ",&k);
The leading white space characters (the '\n' and the ' ') are not needed; %d skips leading white space anyway, and one is sufficient. Note that each white space character in a format string for scanf() et al maps to zero or more white space characters in the input.
The trailing white space is bad. It means skip zero or more white space characters (newlines, blanks, tabs) and keep going until you see something that isn't a white space character (or until EOF). Trailing white space in a format string is a bad idea — doubly so when the input is supposed to be interactive. You have to predict what the next input should be before you can terminate the current input, which is not easy for people to do.
There are multiple other issues, too. Your function declarations are not prototypes (you must write int menu(void); etc to make it a prototype in C). You're missing a break after case 2: — it happens to be harmless at the moment, but when you put an error message or another sort option into the system, it becomes a problem. You haven't used enough functions: you should have an array reading function and an array printing function and should use them. You've left the data reading loop out of your selection_short() function. Normally, the term used is sort, not short — the function names seem anomalous to most people.
Your swap algorithm is contorted:
a[i]=a[i]+a[min];
a[min]=a[i]-a[min];;
a[i]=a[i]-a[min];;
You don't need the double semicolons. And you run the risk of overflows if the values are large enough. It's simpler, and far more orthodox — and ultimately safer — to use:
int tmp = a[i];
a[i] = a[min];
a[min] = tmp;
You should check each and every scanf() call to ensure that it succeeded, taking appropriate action if it fails. Note that it can fail by returning 0 or EOF; you should test:
if (scanf("%d", &n) != 1)
…oops…
I have a small program, where i say the number of lines and columns of a array I want to input, then input info to fill that array with data. What it does next it's not important so ill just omit that part of the code and put (...) in it.
int main (){
int nl, nc,i,j,z,n;
scanf ("%d %d\n", &nl,&nc);
char matrix [nl] [nc];
for (i=0;i<nl;i++)
for (j=0;j<nc;j++)
scanf(" %c",&matrix[i][j]);
scanf("%d",&n);
int s[n*2];
for (z=0;z<n*2;z++)
scanf("%d",&s[z]);
int y=0;
char s2[n];
for (z=0;z<n*2;z+=2){
s2[y]=matrix [(s[z])-1][(s[z+1])-1];
y++;
}
for (z=0;z<n;z++)
printf ("%c", s2[z]);
return 0;
}
My problem is, that it this blows up if input more chars than I should. For example if my input is:
2 3
ABC
DEF
This works just fine.
But if I put:
2 3
ABC
DEFF
It give me a segmentation fold and stops the program. Keep in mind that I have a space before the "%c" in scanf so it's ignoring the "\n" and spaces I put in the input.
What can I do to stop that extra chars in the array from blowing up?
scanf("%d",&n);
int s[n*2];
This code tries to scan and convert whatever is left in the input after reading the matrix. If the input is not numeric, as will be the case if you enter more letters than the matrix should contain, the conversion will fail and n will remain uninitialized. Then int s[n*2]; is undefined because n is indeterminate.
If you want to ignore some characters in the input, you need to do so explicitly. You also better check return values of all functions that take user input, and verify that the values read are sensible.
Ok i figured out that the problem with it was input going to the buffer. To solve this i cleared the buffer before the next input using:
while (getchar() != '\n');
Your problem is filling the array over that size.
You get your input character by character and if you enter character more than your array size the program will stopped or has been logical error,
So you can use getche() and check the array constraint.
You can edit your code as follow:
int main (){
int nl, nc,i,j;
scanf ("%d %d\n", &nl,&nc);
char matrix [nl] [nc];
for (i=0;i<nl;i++)
for (j=0;j<nc;j++)
matrix[i][j]=getche();
(...)
return 0;
}
Use %s instead of %c and remove the inner loop. So the code will be something like this:
for(i=0; i<nl; i++)
{
scanf("%s", &matrix[i]);
}
My code only takes 5 values as input.? What am i doing wrong?
#include<stdio.h>
#include<stdlib.h>
int main()
{
char arr[3][3];
int i,j,n;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
scanf("%c",&arr[i][j]);
}
}
return 0;
}
How should i correct it?
Change
scanf("%c",&arr[i][j]);
to
scanf(" %c",&arr[i][j]);.
Notice the space given before specifier to consume \n left in stdin buffer when you pressed enter.
Each \n is working as input taking your space from input space.
It should work, but note that %c will read only a single character. Whitespace is not suppressed as it is for other (more "high-level") format specifiers, so if you're separating your characters by blanks of any kind those will be read instead of the actual characters.
Also note that you should check the return value of scanf(), it can fail if no suitable input is present.
The first input is stored in arr[0][0] then when you press enter(return key) it is stored in arr[0][1] and while you think you are inputting the second character actually you are giving the third input. Try the code below to see if you didnt get it.
#include<stdio.h>
#include<stdlib.h>
int main()
{
char arr[3][3];
int i,j,n;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
printf("Input array [%d][%d]",i,j);
scanf("%c",&arr[i][j]);
}
}
}
And as for the correction you need a scanf(" %c",&arr[i][j]); a space infront of %c to consume the \n
Hope it answers your question
Instead you can use gets(arr[i][j])
instead of scanf("%c",&arr[i][j]);
This will work perfectly. It is good idea to use gets() and puts() function instead of printf() and scanf() function for string and character in C
you can use fflush(stdin)
char arr[3][3];
int i,j,n;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
scanf("%c",&arr[i][j]);
fflush(stdin);
}
}
My little program below shall take 5 numbers from the user, store them into an array of integers and use a function to print them out. Sincerly it doesn't work and nothing is printed out. I can't find a mistake, so i would be glad about any advice. Thanks.
#include <stdio.h>
void printarray(int intarray[], int n)
{
int i;
for(i = 0; i < n; i ++)
{
printf("%d", intarray[i]);
}
}
int main ()
{
const int n = 5;
int temp = 0;
int i;
int intarray [n];
char check;
printf("Please type in your numbers!\n");
for(i = 0; i < n; i ++)
{
printf("");
scanf("%d", &temp);
intarray[i] = temp;
}
printf("Do you want to print them out? (yes/no): ");
scanf("%c", &check);
if (check == 'y')
printarray(intarray, n);
getchar();
getchar();
getchar();
getchar();
return 0;
}
Change your output in printarray() to read:
printf("%d\n", intarray[i]);
^^
That will add a newline after each number.
Normally, output written to the console in C is buffered until a complete line is output. Your printarray() function does not write any newlines, so the output is buffered until you do print one. However, you wait for input from the user before printing a newline.
Change to that:
char check[2];
And also that:
scanf("%s", check);
if (!strcmp(check,"y"))
printarray(intarray, n);
Hope that helped. Your scanf("%c", &check); failed. Instead of y you end up having NL (ASCII code 10), which means the if part fails.
I don't know if it a nice fix though. Maybe someone could give a better one. Keep in mind if you input something bigger (eg yess) you going to get a bit unlucky ;)
Aside from the suggestions about printing the \n character after your array (which are correct), you also have to be careful with your scanf that expects the "yes/no" answer. Muggen was the first one to notice this (see his answer).
You used a %c specified in your scanf. %c specifier in scanf does not skip whitespace, which means that this scanf will read whatever whitespace was left in the input buffer after you entered your array. You hit the "Enter" key after entering the array, which put a newline character into the input buffer. After that scanf("%c", &check) will immediately read that pending newline character instead of waiting for you to enter "yes" or "no". That's another reason your code does not print anything.
In order to fix your scanf, you have to force it to skip all whitespace characters before reading the actual answer. You can do that by scanf(" %c", &check). Note the extra space before %c. Space character in scanf format string forces it to skip all continuous whitespace beginning from the current reading position. Newline character happens to be whitespace, so it will be ignored by this scanf.
printf("%d", intarray[i]);
add new line after this