fwrite() puts unknown zero - c

I have one strange problem while using fwrite() in C.After editing of file with integers, i get zero ("0") before my last element which added by fwrite().My exercise is to divide integers in file on groups which are consisted of 10 elements or less.
For example, i have :
{2, 3, 9, 4, 6, 7, 5, 87, 65,12, 45, 2, 3, 4, 5, 6, 7, 8, 9}
after editing i need :
{2, 3, 9, 4, 6, 7, 5, 87, 65, 12, 87, 45, 2, 3, 4, 5, 6, 7, 8, 9, 45 };
With code below I get:
{2, 3, 9, 4, 6, 7, 5, 87, 65, 12, 87, 45, 2, 3, 4, 5, 6, 7, 8, 9, 0, 45 };
In the process of step-by-step debugging fwrite() works only two times, it wites 87 after first ten elements, and 45 after remained.Zero wasn`t writed by fwrite().Is that so?From where it comes finally?
My code:
while (!feof(fp)) {
fread(&elems[k], sizeof(int), 1, fp);
fwrite(&elems[k], sizeof(int), 1, hp);
++k;
if (k == 10 || feof(fp)){
for (i = 0; i < 10; ++i){
if (elems[i] > max_number){
max_number = elems[i];
}
}
fwrite(&max_number, sizeof(int), 1, hp);
for (i = 0; i < 10; ++i){
elems[i] = 0;
}
max_number = INT_MIN;
k = 0;
}
}
Thank for answers!

Using feof will result in reading an extra item.
Must check for errors from fwrite and fread calls.
One possible error is the EOF error.
If fread returns 0 items read the value will be left at whatever it was before. Probably 0. Which is probably where your extra 0 comes from.

Related

Getting Odd numbers in a array? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 months ago.
Improve this question
I am begginer,I am faced with a challenge to take few numbers and multiply the odd numbers in them to apply the lunhs alogrithm.
Ex- If user inputs 100034341341313413941391341393413.
Is there any way I can take this input and specifically filter out the numbers in the odd places and even places and add them ?
Please just show me the way or how I can get it the number in a array and approach it.The rest i'll figure out.
Thanks in advance.
The last digit is always odd so start from there. To get last digit you can use Modulo Operator (%) which gives you remainder of a division. If you divide a number by 10 you get your number's very right digit. After that divide your number by 10 (not modulo) to remove right digit. Loop this process until you get 0.
int x = 72;
int last_digit = 72 % 10; // returns 2
int x = x / 10; // its 7.2 but its an int so x will be 7
Other approaches can be found in here.
#include <stdio.h>
void getSum(int n) {
// If n is odd then the last digit
// will be odd positioned
int isOdd = (n % 2 == 1) ? 1 : 0;
// To store the respective sums
int sumOdd = 0;
int sumEven = 0;
// While there are digits left process
while (n != 0) {
// If current digit is odd positioned
if (isOdd)
sumOdd += n % 10;
// Even positioned digit
else
sumEven += n % 10;
// Invert state
isOdd = !isOdd;
// Remove last digit
n /= 10;
}
printf("Sum odd = %d\n", sumOdd);
printf("Sum even = %d\n", sumEven);
}
To calculate LUHN algorithm on a string is always far better than doing it with an int variable, as the integer has a limited amount of memory to represent the numbers normally managed in a credit card. Normally credit card numbers are 20 digits long (but they can grow up to 24 or more), while long integers reach roughly 18 digits and make it impossible to get.
In addition to what was exposed above, the LUHN algorithm can be simulated as a DFA (Deterministic Finite Automaton) that can be easily implemented with a table and a loop, as follows:
#include <ctype.h>
#include <stdio.h>
#include <string.h>
const static char luhn_tab[][10] = {
{ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }, /* state 0, accepting state */
{ 11, 12, 13, 14, 15, 16, 17, 18, 19, 10 }, /* '' 1 */
{ 12, 13, 14, 15, 16, 17, 18, 19, 10, 11 },
{ 13, 14, 15, 16, 17, 18, 19, 10, 11, 12 },
{ 14, 15, 16, 17, 18, 19, 10, 11, 12, 13 },
{ 15, 16, 17, 18, 19, 10, 11, 12, 13, 14 }, /* '' 5 */
{ 16, 17, 18, 19, 10, 11, 12, 13, 14, 15 },
{ 17, 18, 19, 10, 11, 12, 13, 14, 15, 16 },
{ 18, 19, 10, 11, 12, 13, 14, 15, 16, 17 },
{ 19, 10, 11, 12, 13, 14, 15, 16, 17, 18 }, /* '' 9 */
{ 0, 2, 4, 6, 8, 1, 3, 5, 7, 9 }, /* state 10, accepting state */
{ 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 },
{ 2, 4, 6, 8, 0, 3, 5, 7, 9, 1 },
{ 3, 5, 7, 9, 1, 4, 6, 8, 0, 2 },
{ 4, 6, 8, 0, 2, 5, 7, 9, 1, 3 },
{ 5, 7, 9, 1, 3, 6, 8, 0, 2, 4 },
{ 6, 8, 0, 2, 4, 7, 9, 1, 3, 5 },
{ 7, 9, 1, 3, 5, 8, 0, 2, 4, 6 },
{ 8, 0, 2, 4, 6, 9, 1, 3, 5, 7 },
{ 9, 1, 3, 5, 7, 0, 2, 4, 6, 8 },
};
/* as the number of states is less than 32, we can use the bits of
* an integer to mark which states are accepting states and which aren't */
const static int accepting = (1 << 0) | (1 << 10);
int luhn_ok(char *s, size_t s_len)
{
s += s_len; /* point to the string end */
char st = 0; /* automaton state, initially zero */
while (s_len--) {
if (isdigit(*--s)) {
/* operate only on digits, skipping nondigits */
st = luhn_tab[st][*s - '0'];
}
}
/* accepting state only if final state is one of the marked
* bits in accepting */
return ((1 << st) & accepting) != 0;
} /* luhn_ok */
int main(int argc, char **argv)
{
for (int i = 1; i < argc; i++) {
printf("luhn_ok(\"%s\") == %s\n",
argv[i],
luhn_ok(argv[i],
strlen(argv[i]))
? "Good"
: "Bad");
}
} /* main */
As you see, the only difficulty lies in that I have to scan the string of digits from the rigth, instead of doing it from the left (to tie us to the odd/even position in the string) This can also be done from the left (I mean, with an automaton), but the automaton table grows up to 100 states (because we don't know if we start in an odd/even position from the left digit), instead of 20 of the table above /well, I have not minimized the table, but I think I will not get a table simpler than 100 states) Above, the state represents the expected LUHN remainder after processing the digits of the string, with 10 added if we are in an odd position or even. You will easily see that this matches the algorithm you have been given.
$ luhn "100034341341313413941391341393413" 12345678903
luhn_ok("100034341341313413941391341393413") == Bad
luhn_ok("12345678903") == Good
$ _
Note:
I have computed the 100 states table to allow computing the LUHN algorithm left to right, but finally I considered it cumbersome to add it here, as it adds no advantage to the computing (it is only interesting if you don't know in advance how long your string of digits will be, or if you are involved in a parsing algorithm that requires left to right parsing) If someone is interested, please ask for it in the comments, and I'll add it.

How to get used elements from space complexity optimized 0-1 knapsack

I have implemented 0-1 knapsack. "DP" is the 1D table that holds maximum profits. "capacity" is the maximum capacity, "n" is the number of elements. At the end it holds the last row of 2D classic approach in "DP". But i can't figure out how to get which elements are used with just looking at the 1D array.
DP = (int*)calloc(capacity + 1, sizeof(int));
used = (int*)calloc(n, sizeof(int));
for (i = 0; i < n; i++) {
for (j = capacity; j > 0; j--) {
if (weight[i] <= j && DP[j] < DP[j - weight[i]] + profit[i]) {
DP[j] = DP[j - weight[i]] + profit[i];
used[i] = 1;
}
}
}
// for example
// int profit[] = { 7, 16, 13, 8, 1, 11, 14, 11, 12, 7, 6, 10, 1, 1, 11, 12}
// int weight[] = { 6, 2, 7, 2, 1, 2, 5, 4, 12, 16, 1, 4, 10, 12, 12, 2}
// results DP = {0, 6, 16, 22, 28, 34, 39, 45, 47}
// total profit of used elements: 72 <- it should be 47
// total weight of used elements: 20 <- it should be lesser than 8(the capacity)

Initialize elements of GSL matrix

I have allocated a large gsl_matrix and would like to allocate all its elements with known float values. Is there a way to do it without using gsl_matrix_set for each element? I am looking for the equivalent of fortran's reshape function to initialize a matrix.
A = reshape( (/0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7/), (/ 8, 8/) )
Matrices only support limited setting of all values, that is by gsl_matrix_set_all, gsl_matrix_set_zero or gsl_matrix_set_identity.
However, you can create and initialise an array and then create a matrix view from that using gsl_matrix_view_array, gsl_matrix_const_view_array, gsl_matrix_view_array_with_tda or gsl_matrix_const_view_array_with_tda. (Matrix views are common in GSL. For example, they are used to express sub-matrices returned by gsl_matrix_submatrix.) The matrix view is a struct which contains a field matrix upon which you execute the gsl_matrix methods you wish to apply.
For example, compile with gcc matrixview.c -lgsl -lgslcblas the following file matrixview.c:
#include <stdio.h>
#include <gsl/gsl_matrix.h>
#define rows 2
#define cols 3
int main () {
const double data[rows*cols] = {
0.0, 0.1, 0.2,
1.0, 1.1, 1.2,
};
const gsl_matrix_const_view mat = gsl_matrix_const_view_array( data, rows, cols );
for ( size_t row = 0; row < rows; ++row ) {
for ( size_t col = 0; col < cols; ++col ) {
printf( "\t%3.1f", gsl_matrix_get( &mat.matrix, row, col ) );
}
printf( "\n" );
}
}

realloc() is screwing up my data... what's going on?

I'm writing a variable list implementation. In my insertion step, I check if the array's size is maxed out, and if so I double the maximum capacity and call realloc() to allocate me some new memory. Going from size 2 to 4, 4 to 8, and 8 to 16 works fine, but going from size 16 to 32 gives me some random zeroes in my array. Can anyone tell me what's going on here? I know I could avoid using realloc() by mallocing some new space, using memcpy and then freeing the old pointer... and perhaps there's no performance hit from doing that. But my intuition tells me that there is, and in any case I thought that's what realloc was there for. Can anyone tell me what's going on? The key function in this code is the append function.
#include <stdio.h>
#include <stdlib.h>
#include "problem5.h"
#define FAILURE -1
#define SUCCESS 0
ArrayList ArrayList_Init(int n, int (*append) (ArrayList, int), void (*print) (ArrayList), void (*insert) (ArrayList, int, int), void (*destroy) (ArrayList), int (*valueOf) (ArrayList, int))
{
ArrayList newArrayList = (ArrayList) malloc(sizeof(ArrayList_));
newArrayList->max_size = n;
newArrayList->current_size = 0;
newArrayList->data = malloc(n*sizeof(int));
newArrayList->append = append;
newArrayList->destroy = destroy;
newArrayList->print = print;
newArrayList->insert = insert;
newArrayList->valueOf = valueOf;
return newArrayList;
}// init a new list with capacity n
int append_(ArrayList list, int val)
{
//if the array is at maximum capacity
//double the capacity
//update max_size
//insert the value in the first open spot in the array (aka index current_size)
//increment current_size
if (list->current_size == list->max_size) {
list->max_size *= 2;
if (( list->data = realloc(list->data, list->max_size) ) == NULL)
return FAILURE;
}
list->data[list->current_size] = val;
list->current_size++;
return SUCCESS;
}
void print_(ArrayList list)
{
int i;
printf("List of size %d, max size %d. Contents:\n", list->current_size, list->max_size);
for (i=0; i<list->current_size; i++)
printf("%d, ", list->data[i]);
printf("\n");
}
void insert_(ArrayList list, int val, int index) {
}// insert val into index
void destroy_(ArrayList list)
{
//free list memory
}
int valueOf_(ArrayList list, int index)
{
//return value of specified element
return 0;
}
int main()
{
ArrayList list;
int stat, count = 0;
list = ArrayList_Init(2, append_, print_, insert_, destroy_, valueOf_); // init a new list with capacity 8
do {
printf("Appending %d\n", count);
stat = list->append(list, count) ; // add val to end of the list
list->print(list);
} while (stat == SUCCESS && ++count < 20);
return 0;
}
And here's the output of this:
Appending 0
List of size 1, max size 2. Contents:
0,
Appending 1
List of size 2, max size 2. Contents:
0, 1,
Appending 2
List of size 3, max size 4. Contents:
0, 1, 2,
Appending 3
List of size 4, max size 4. Contents:
0, 1, 2, 3,
Appending 4
List of size 5, max size 8. Contents:
0, 1, 2, 3, 4,
Appending 5
List of size 6, max size 8. Contents:
0, 1, 2, 3, 4, 5,
Appending 6
List of size 7, max size 8. Contents:
0, 1, 2, 3, 4, 5, 6,
Appending 7
List of size 8, max size 8. Contents:
0, 1, 2, 3, 4, 5, 6, 7,
Appending 8
List of size 9, max size 16. Contents:
0, 1, 2, 3, 4, 5, 6, 7, 8,
Appending 9
List of size 10, max size 16. Contents:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
Appending 10
List of size 11, max size 16. Contents:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
Appending 11
List of size 12, max size 16. Contents:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
Appending 12
List of size 13, max size 16. Contents:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
Appending 13
List of size 14, max size 16. Contents:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
Appending 14
List of size 15, max size 16. Contents:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
Appending 15
List of size 16, max size 16. Contents:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
Appending 16
List of size 17, max size 32. Contents:
0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16,
Appending 17
List of size 18, max size 32. Contents:
0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 17,
Appending 18
List of size 19, max size 32. Contents:
0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 17, 18,
Appending 19
List of size 20, max size 32. Contents:
0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 17, 18, 19,
It is very bad to write so:
list->data = realloc(list->data, list->max_size)
You should use new variable and if memory was reallocated you write so:
List->data = temp;
It will protect you from memory leak.
And you forgot *sizeof(int)

Finding the sum of the digits

I have a 5-digit integer, say
int num = 23456;
How to find the sum of its digits?
Use the modulo operation to get the value of the least significant digit:
int num = 23456;
int total = 0;
while (num != 0) {
total += num % 10;
num /= 10;
}
If the input could be a negative number then it would be a good idea to check for that and invert the sign.
#include <stdio.h>
int main()
{
int i = 23456;
int sum = 0;
while(i)
{
sum += i % 10;
i /= 10;
}
printf("%i", sum);
return 0;
}
int sum=0;while(num){sum+=num%10;num/=10;}
Gives a negative answer if num is negative, in C99 anyway.
Is this homework?
How about this:
for(sum=0 ,num=23456;num; sum+=num %10, num/=10);
If you want a way to do it without control statements, and incredibly efficient to boot, O(1) instead of the O(n), n = digit count method:
int getSum (unsigned int val) {
static int lookup[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // 0- 9
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, // 10- 19
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, // 20- 29
:
9, 10, 11, 12, 13, 14, 15, 16, 17, 18, // 90- 99
:
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, // 23450-23459
::
};
return lookup[23456];
}
:-)
Slightly related: if you want the repeated digit sum, a nice optimization would be:
if (num%3==0) return (num%9==0) ? 9 : 3;
Followed by the rest of the code.
Actually, I answered with another (somewhat humorous) answer which used a absolutely huge array for a table lookup but, thinking back on it, it's not that bad an idea, provided you limit the table size.
The following functions trade off space for time. As with all optimisations, you should profile them yourself in the target environment.
First the (elegant) recursive version:
unsigned int getSum (unsigned int val) {
static const unsigned char lookup[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // 0- 9
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, // 10- 19
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, // 20- 29
:
18, 19, 20, 21, 22, 23, 24, 25, 26, 27 // 990-999
};
return (val == 0) ? 0 : getSum (val / 1000) + lookup[val%1000];
}
It basically separates the number into three-digit groupings with fixed lookups for each possibility. This can easily handle a 64-bit unsigned value with a recursion depth of seven stack frames.
For those who don't even trust that small amount of recursion (and you should, since normal programs go that deep and more even without recursion), you could try the iterative solution:
unsigned int getSum (unsigned int val) {
static const unsigned char lookup[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // 0- 9
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, // 10- 19
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, // 20- 29
:
18, 19, 20, 21, 22, 23, 24, 25, 26, 27 // 990-999
};
unsigned int tot = 0;
while (val != 0) {
tot += lookup[val%1000];
val /= 1000;
}
return tot;
}
These are probably three times faster than the one-digit-at-a-time solution, at the cost of a thousand bytes of data. If you're not adverse to using 10K or 100K, you could increase the speed to four or five times but you may want to write a program to generate the static array statement above :-)
As with all optimisation options, measure, don't guess!
I prefer the more elegant recursive solution myself but I'm also one of those types who prefer cryptic crosswords. Read into that what you will.
#include <stdio.h>
2 #include <stdlib.h>
3
4 #define BUFSIZE 20
5
6 int main(void)
7 {
8 int number = 23456;
9 char myBuf[BUFSIZE];
10 int result;
11 int i = 0;
12
13 sprintf(myBuf,"%i\0",number);
14
15 for( i = 0; i < BUFSIZE && myBuf[i] != '\0';i++)
16 {
17 result += (myBuf[i]-48);
18 }
19
20 printf("The result is %d",result);
21 return 0;
22 }
23
Another idea here using the sprintf and the ascii number representation
#include<stdio.h>
main()
{
int sum=0,n;
scanf("%d",&n);
while(n){
sum+=n%10;
n/=10;
}
printf("result=%d",sum);
}
sum is the sum of digits of number n

Resources