I am taking a couple of numbers as input from the user, storing them into a file and then reading from that file, sorting the numbers and displaying them to the user. The program works except for 1 issue. When taking input from the user it asks for an extra elememnt than the specifies limit. This extra element doesn't get stored anywhere. I have tried reducing the limit value by one but that results in loss of 1 element(i.e. 1 element becomes 0). I understand that this may be a very newbie issue but I coudn't find any direct answer to this issue. I wrote the program in Visual Studio 2010 as a C program. here's the code:
#include <stdio.h>
int arr[50];
int n;
int writefile()
{
FILE *ptr;
ptr = fopen("Sort.txt","w");
if(ptr==NULL)
{
printf("No such file exists\n");
fclose(ptr);
return 0;
}
else
{
int i;
printf("Enter number of elements in array\n");
scanf("%d", &n);
printf("Enter %d elements\n", n);
for(i=0; i<n; i++) //The issue is here
{
scanf("%d\n",&arr[i]); //say the user enter n=3, then after adding 1,2,3 it will ask for another 4th element but only 1,2,3 will get stored.
}
fwrite(arr, sizeof(int), n, ptr);
fclose(ptr);
printf("done\n");
}
}
void sortarr(int arr1[]);
int readfile()
{
FILE *ptr;
ptr = fopen("Sort.txt","r");
if(ptr==NULL)
{
printf("No such file exists\n");
fclose(ptr);
return 0;
}
else
{
int i;
int arrb[50];
fread(arrb, sizeof(int), n, ptr);
printf("Before sorting data\n");
for(i=0; i<n; i++)
{
printf("%d",arrb[i]);
}
printf("\n");
sortarr(arrb);
printf("After Sorting data\n");
for(i=0; i<n; i++)
{
printf("%d",arrb[i]);
}
printf("\n");
}
}
void sortarr(int arr1[])
{
int i,j,temp;
for (i = 0; i < n; i++) {
for (j = i + 1; j < n; j++) {
if (arr1[i] > arr1[j]) {
temp = arr1[i];
arr1[i] = arr1[j];
arr1[j] = temp;
}
}
}
}
int main()
{
writefile();
readfile();
return 0;
}
scanf("%d\n",&arr[i]);
Should be:
scanf("%d",&arr[i]);
If you ask it to ignore white space after the number, it will have to keep reading until it reads some non-whitespace in order for it to ensure it has ignored all the whitespace. You definitely don't want scanf to try to ignore whitespace after it has read the number, you want it to terminate.
The %d format specifier already ignores whitespace before the number.
Let's just narrow this down to the following code:
scanf("%d", &n);
for (i = 0; i < n; i++)
{
scanf("%d\n", &arr[i]);
}
Notice the difference in the scanf calls? The first call doesn't have a \n in its format string. The second call does.
Remove the \n from the scanf format string (in the second call). Things should work more like you're expecting then.
An online manual page for scanf says:
The format string consists of a sequence of directives which describe how to process the sequence of input characters... A directive is one of the following: A sequence of white-space characters (space, tab, newline, etc.; see isspace(3)). This directive matches any amount of white space, including none, in the input.
So the looped over scanf (with the extra \n in it) was effectively reading the number, the newline, the next number, then realizing it's read all of the white space it could. scanf then returned with the first number assigned to your array entry and the next number ready for the next call to reading from standard input. This left things effectively offset appearing like you saw and requiring the extra number before ending (in order that it could detect that the white space had ended).
Related
I tried to scan and print the characters of array using below code but input characters are not matching with output characters
#include <stdio.h>
int main() {
char s[10];
int i, n;
printf("enter the value of n:\n");
scanf("%d", &n);
printf("start entering the characters:\n");
for (i = 0; i < n; i++) {
scanf("%c", &s[i]);
}
for (i = 0; i < n; i++) {
printf("%c", s[i]);
}
return 0;
}
OUTPUT
enter the value of n:
5
start entering the characters:
ABCDE(scanf values)
ABCD(printf values)
Can anyone please clarify my doubt why is the output not matching with input
Since you are wanting to read data into a character array with "scanf" you probably could just reference the string identifier instead and simplify things. Following are a few tweaks to your code that still inputs the data and prints it back out.
#include <stdio.h>
#include <string.h>
int main()
{
char s[10];
int i, n;
printf("enter the value of n:\n");
scanf("%d", &n);
printf("start entering the characters:\n");
scanf("%s", s); /* In lieu of using a loop */
if (strlen(s) < n) /* Just in case less characters are entered than was noted */
n = strlen(s);
for (i = 0; i < n; i++)
{
printf("%c", s[i]);
}
printf("\n");
return 0;
}
The program just scans in the complete string instead of a character at a time. Also, I included the "<string.h> file so as to use functions such as "strlen" (get the length of the string) to provide a bit more robustness to the code. Running the program netted the same character set that was entered.
:~/C_Programs/Console/InputOutput/bin/Release$ ./InputOutput
enter the value of n:
7
start entering the characters:
ABCDEFG
ABCDEFG
You might give that a try.
Regards.
I do not know how to pass parameters to insertSort. I am also not certain if I am using scanf correctly.
I want the dynamic array like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void insertSort(int LENGTH, int *arr)
{
int temp;
for(int i=0; i<LENGTH; i++)
{
temp = arr[i];
for(int j=i+1; j<LENGTH; j++)
{
if( temp > arr[j] )
{
arr[i] = arr[j];
arr[j] = temp;
}
}
}
}
int main()
{
int LENGTH = 10;
int *arr = malloc(sizeof(int)*LENGTH); //create dynamic memory
memset(arr, 0, LENGTH); //initialize the space
printf("please enter nums length : %d\n", LENGTH);
for(int i=0; i<LENGTH; i++) //put numbers to the dynamic space
{
printf("%d index : ", i);
scanf("%d", &arr[i]);
}
for(int i=0; i<LENGTH; i++) //print those space
printf("%3d", arr[i]);
insertSort(&LENGTH, &arr); //SORT !
for(int i=0; i<LENGTH; i++)
printf("%3d", arr[i]);
}
Let's take this one piece at a time. For starters, your insertSort is not an insertion sort. An insertion sort implementation looks like:
void insertSort(int LENGTH, int *arr)
{
for (int i = 1; i < LENGTH; i++)
{
int tmp = arr[i], j;
for (j = i; j >= 1 && tmp < arr[j-1]; j--)
arr[j] = arr[j-1];
arr[j] = tmp;
}
}
Next, when you are testing functions, etc.., forego the user input and just test your function with a fixed set of data as a test-case, e.g.
int main(void) {
int arr[] = { 10, 2, 8, 5, 4, 6, 7, 3, 9, 1 },
nmemb = (int)(sizeof arr/sizeof *arr);
insertSort (nmemb, arr);
for (int i = 0; i < nmemb; i++)
printf ("%3d", arr[i]);
putchar ('\n');
}
Lastly, scanf. You cannot begin to use scanf correctly unless you validate its return. Further, in your case, what happens if the user types "ten" instead of the number 10 -- try it...
Any time you are taking user-input, you must account for each character that remains in the input buffer (stdin here). This is especially true when taking input with scanf (or family) due to the way scanf handles input or matching failures. When either occurs, no further characters are read, and any offending characters are left unread in the input buffer -- just waiting to bite you again on your next attempted read (generally resulting in an infinite loop if you are taking input within a loop)
(this is one of the primary reason a line-oriented function such as fgets or POSIX getline are recommended for taking user input)
scanf can be used, if used correctly. This means you are responsible for checking the return of scanf every time. You must handle three conditions
(return == EOF) the user canceling input by generating a manual EOF by pressing Ctrl+d (or on windows Ctrl+z, but see CTRL+Z does not generate EOF in Windows 10);
(return == expected No. of conversions) indicating a successful read -- it is then up to you to check whether the input meets any additional criteria (e.g. positive integer, positive floating-point, etc..); and
otherwise, you must handle the matching or input failure and you must account for every character that may be left in your input buffer. (generally you will scan forward in the input buffer until a '\n' or EOF is found discarding any extraneous characters that remain)
If you do your job, you can successfully use scanf as needed.
How can I input 2 strings which are separated by a new line?
My Problem:
First I need to give how many strings I need to get and then I need to get those strings then display it.
I tried this:
Code:
#include <stdio.h>
#include <string.h>
int main()
{
int n,i = 0;
scanf("%d", &n);
char arr[n][100];
for(int i = 0; i < n; i++)
{
scanf("%[^\n]s", arr[i]);
}
for(int i = 0; i < n; i++)
{
printf("%s\n", arr[i]);
}
return 0;
}
My Input is :
2 I am
Aravind
My Output is:
I am
รพ
First Line I got correct one but second line it shows some garbage value. Help me to solve this.
You have two major problems:
The "%[" format ends with the closing "]", there should be no "s" at the end.
The "%[" format doesn't skip leading space, like that newline which will be present after the first line you read.
Both these issues can be easily solve by using fgets to read whole lines instead.
You already have suggestions to not use scanf. However, if you 'must' use scanf then you can consider the following approach:
For dynamic memory allocation you should use malloc
the newline character stays in the stdin and hence needs to be flushed or handled/ignored
Here is the updated code.
int main()
{
int n,i = 0;
scanf("%d", &n);
scanf("%*[\n]");
/*this will read the \n in stdin and not store it anywhere. So the next call to
* scanf will not be interfered with */
char **inputs;
inputs = malloc(n * sizeof(char *));
for (i = 0; i < n; i++)
{
inputs[i] = malloc(100 * sizeof(char));
}
for(i = 0; i < n; i++)
{
scanf("%*[\n]");
scanf("%100[^\n]", inputs[i]);
}
for(i = 0; i < n; i++)
{
printf("%s\n", inputs[i]);
}
return 0;
}
use gets(arr[i]) instead of scanf.
I want to store a series of integers till i press an enter in an array.How can i implement that
Input:
1(tab space)2(tab space)3(tab space)4(tab space)enter
i tried doing this
#include<stdio.h>
main()
{
int i,j,c,d;
int a[5];
for(i=0;i<2;i++){
j=0;
while((d=scanf("%d",&c))==1){
a[j]=c;
j=j+1;
}
}
}
I dont know how scanf works and using scanf return value.Please explain how i can store this input if its not impossible to do so with scanf and also
2)What else can be used inside scanf along with %d ?
I have a file with 200 rows with numbers like this
(NOTE: each row has varied number of values but all numbers are less than 200)
1\t2\t3\t4\t5\t
2\t3\t4\t5\t6\t7\t8\t
11\t12\t13\t
.
.
200
... so i have to store this as an adjacency list representation
For the first part of your question. scanf() returns number of elements successfully read but it is of no use here and you can just scan in a loop and scanf() will pick your integers in a line when you press enter.
#include <stdio.h>
int main(void) {
int a[5];
int i, n;
for(i=0;i<5;i++)
{
if(scanf("%d",&a[i]) != 1)
{
printf("Value not read correctly\n");
break;
}
}
n = i;
for(i=0;i<n;i++)
printf("%d\n",a[i]);
return 0;
}
For the second question you have to do something line
1.Read a line from your file using fgets()
2.Break your line using strtok() with tab as delimiter.
3.Now convert each token to integer using atoi()
4.Now do whatever you want with the integer. i.e. create a node add your integer to the node
Let's make some reasonable assumptions about the width of each row.
These assumptions are useful for simple code, though not needed in general.
#define LINE_WIDTH_MAX 1000
#define INTS_PER_LINE_MAX 100
#define ROWS_PER_FILE (200 /* given by OP */)
Read each row with fgets(), then scan. Could use strtol(), sscanf() or various approaches.
This method uses sscanf() and "%n" to determine when the next number might follow.
int row;
for (row = 0; row < ROWS_PER_FILE; row++) {
char buf[LINE_WIDTH_MAX + 2];
if (fgets(buf, sizeof buf, stdin) == NULL) {
break; // Handle EOF or IO error
}
int num[INTS_PER_LINE_MAX];
char *p = buf;
for (int i = 0; i<INTS_PER_LINE_MAX; i++) {
int n = 0;
if (1 != sscanf(p, "%d %n", &num[i], &n)) {
break;
}
p += n;
}
if (*p) Handle_GarbageInLIne();
// do something with the `i` numbers
}
Notes:
Advise never use scanf()/
I am trying to get both parts of this program to work as you can see I have split it with first part (question 1) and second part (question 2). The problem is first part runs fine just when the second part starts I can not input any string and it just seems to skip through the code without letting me input the string.
If I delete the first part (question 1) of the program then everything works fine and I can input the string. What interrance is causing this issue.
int main()
{
first();
second();
}
//Question 1
int first()
{
/* dataarray.c */
float data[20] = {
50.972438, 93.765053, 9.252207, 1.851414, 16.717533,
71.583113, 97.377304, 20.352015, 56.309875, 0.072826,
23.986237, 36.685959, 80.911919, 86.621851, 53.453706,
96.443735, 29.845786, 18.119300, 31.079443, 52.197715 };
/* The number of elements in the data array */
int data_size = 20;
int pos;
int j;
int i;
int k;
printf("Question 1\n");
for(i=0;i<data_size;i++)
{
printf("\nArray %i is %f ",i,data[i]); //Initial arrays print statement
}
printf("\n\nArray number to delete:"); //User Choose one to delete
scanf("%i",&pos);
k =0;
for(j = 0; j< pos;j++)
{
printf("\n Array %i is now %f ",k,data[j]);
k++;
}
k=pos;
for(j=pos+1;j<data_size;j++)
{
printf("\n Array %i is now to %f ",k,data[j]); //Shows array changed to
k++;
}
data_size = data_size - 1; //Decreases data size
}
//Question 2
int second()
{
printf("\n\nQuestion 2\n");
int a,b,check=0;
char str[20];
printf("\nEnter a String:\n"); //User inputs word to check if its palindrome
gets(str);
for(b=0;str[b]!=0;b++); //Starts at 0 increment till the last length
b=b-1;
a=0;
while(a<=b)
{
if(str[a]==str[b]) //String a is forwards b is backwards
{
a=a+1;
b=b-1;
check=1; //If check = 1 then a palindrome
}
else
{
check=0; //If check = 0 then it not a plaindrome
break; //Loop break
}
}
if(check==1)
printf("It is a Palindrome:"); //Statement printed if check = 1
else
printf("It is not a Palindrome\n"); // Else if 0 this statement is printed
}
When you call scanf in part one, I presume you enter a number followed by a newline. scanf consumes the number, but the newline is left in the buffer. The gets() in part 2 then sees the newline and returns a blank line. An easy solution is to do
scanf( "%i\n", &pos );
BTW, never use gets. Use fgets instead.