What am I doing wrong in converting char to int? - c

I am basically trying to convert a char vector to int values: in file stage_03.txt I have something like 10011 10101 10011 11001 etc. and the stage_04.txt file should look like 19 21 19 etc. This code works perfectly fine in Code::Blocks. However, the stage_04.txt file is totally messed up when I run the code in Linux terminal: ^R ^S ^D etc.
#include <stdio.h>
#include <math.h>
int main(void) {
char x[256];
int aux[1000];
int numar = 0;
int z = 0;
int i = 0;
int l = 0;
int ch;
FILE *fin = fopen("stage_03.txt", "r");
FILE *fout = fopen("stage_04.txt", "w");
while ((ch = fgetc(fin)) != EOF) {
x[i++] = ch;
}
for (int i = 0; i < l; i = i + 6) {
numar = 0;
for (int j = 0; j <= 4; j++)
numar = numar + (x[i + j] - '0') * pow(2, (4 - j));
aux[z++] = numar;
}
for (i = 0; i < z - 1; i++) {
fputc(aux[i], fout);
fputc(' ', fout);
}
return 0;
}
What can I do to solve this?

Here is my solution. Please do not regard this as a "final" code. In final code one should divide the code into subprocedures and add error handling. I left this out for simplicity, here. The solution adds more flexibility concerning the separators and lengths of the numbers in the source file.
It can easily deal with source files such as:
0 1 00 01 10 11 000 001 010 011
100 101 110 111
0000 0001 0010 0011 0100 0101
0110 0111 1000 1001 1010 1011 1100 1101 1110
1111 10011 11001
You can see that fields do not need to have a fixed size of 6 character like in the original code.
#include <stdio.h>
#include <math.h>
#include <string.h>
int main(void) {
char sourceValues[256];
int targetValues[1000];
int number = 0;
int numLength = 0;
int i = 0;
int charsToProcess = 0;
int ch;
const char *srcPtr = &sourceValues[0];
int* targetPtr = &targetValues[0];
FILE *fin = fopen("stage_03.txt", "r");
FILE *fout = fopen("stage_04.txt", "w");
// read source file and determine number of chars to be processed
while ((ch = fgetc(fin)) != EOF) {
sourceValues[i++] = ch;
}
sourceValues[i] = '\0'; // terminate source data
charsToProcess = i;
srcPtr += strcspn(srcPtr, "01"); // eventually skip leading whitespace
do {
numLength = strcspn(srcPtr, " \t\n\r\v"); // determine runlength until next separator
// Convert ASCII into binary form
number = 0;
for (int i = 0; i < numLength; ++i)
{
number <<= 1; // Make room for next digit and propagate existing digits stepwise to their final place
number += (*srcPtr++ == '1'); // Insert new digit at starting pos
}
*targetPtr++ = number; // Store converted number in binary representation in target array
srcPtr += strcspn(srcPtr, "01"); // Skip whitespace. Set srcPtr to next numeric sequence
} while (srcPtr < sourceValues + charsToProcess);
for (const int *ptr = &targetValues[0]; ptr < targetPtr; ++ptr) {
fprintf(fout, "%d ", *ptr);
}
return 0;
}
Here is the output to the input given above:
0 1 0 1 2 3 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 19 25

Related

Is there a way of assigning array items to struct values?

so what I have is the following array:
10
1 250 350 50
2 525 200 80
3 425 700 60
4 675 475 65
5 850 850 40
6 925 200 90
7 1050 575 80
8 1250 800 70
9 1375 400 60
10 1500 650 40
Each lines' value means something different, per instance
1 250 350 50
id lat long value
I want to assign each of those line values to a structure so I can play with them, but after googling and coming up with the graph theory (which is kind of similar to what I am trying to do) nothing worked... I may say that this array is being pulled from a text file, whether that is or not relevant.
struct population{
int id;
int latitude;
int longitude;
int value;
};
I can't come up with any solution, can anyone help me out or at least provide some tutorials or articles to help me clear my mind?
Here is my code:
#include <stdio.h>
#include <math.h>
#include <string.h>
#define RSIZE 20
#define CSIZE 11
struct population{
int id;
int latitude;
int longitude;
int value;
};
int main(void)
{
char line[CSIZE][RSIZE];
char fname[20];
FILE *fptr = NULL;
int i = 0;
int tot = 0;
printf("\n\n Read the file and store the lines into an array :\n");
printf("------------------------------------------------------\n");
printf(" Input the filename to be opened : ");
scanf("%s",fname);
fptr = fopen("cord.txt", "r");
while(fgets(line[i], RSIZE, fptr))
{
line[i][strlen(line[i]) - 1] = '\0';
i++;
}
tot = i;
printf("\n The contents of the file %s are : \n",fname);
for(i = 0; i < tot; ++i)
{
printf(" %s\n", line[i]);
}
printf("\n");
return 0;
}
A good way to read, validate and save a line of file text into a struct is to use a helper function with fgets() and sscanf() #kaylum. Use " %n" to detect successful parsing completion.
#define INT_TEXT_SIZE 12 // INT_MIN
#define POPULAITON_LINE_SIZE ((INT_TEXT_SIZE + 1 /* separator */)*4 + 1)
// Return:
// 1 on success
// 0 on failure
// EOF on end-of-file/input error
int population_read(struct population *p, fptr) {
// Be generous in buffer size, suggest 2x max expected
char buf[POPULAITON_LINE_SIZE * 2];
if (fgets(buf, sizeof buf, fptr) == NULL) {
return EOF;
}
int n = 0;
// Use %n to store offset
sscanf(buf, "%d%d%d%d %n", &p->id,
&p->latitude, &p->longitude, &p->value, &n);
if (n == 0 || buf[n] || n >= sizeof buf - 1) {
// Parsing failed, junk at the end or very long
return 0;
}
// Maybe some range/value tests per member
if (p->latitude < LATITUDE_MIN || p->latitude > LATITUDE_MAX) {
return 0;
}
... // likewise for other members.
return 1;
}
Usage example:
struct population pop[CSIZE];
int count;
for (count = 0; count < CSIZE; count++) {
int result = population_read(&pop[count], fptr));
if (result == 0) {
report_error_with_TBD_code();
return -1;
}
if (result != 1) {
break;
}
}
for (int c = 0; c < count; c++) {
// Use pop[c];
}

C - iterate over array of 0s & 1s as if binary number

I need to iterate over an array of n elements (dynamic size thus), for example 4, as if it were a binary number, starting with all zeros ({0,0,0,0}). Every time this needs to increment as if it is binary, {0,0,0,0} -> {0,0,0,1} -> {0,0,1,0} -> {0,0,1,1} -> {0,1,0,0}, etc...
I have trouble generating an algorithm that does so with array values, I thought about using recursion but cannot find the method to do so other than hard-coding in ifs. I suppose I could generate an n-digit number and then apply any algorithm discussed in this post, but that would be inelegant; the OP asked to print n-digit numbers while I need to work with arrays.
It would be great if someone could point me in the right direction.
Context:
int n;
scans("%d", &n);
int *arr = calloc(n, sizeof(int));
Algorithm:
Start at the rightmost element.
If it's a zero, then set it to one and exit
It must be a one; set it to zero
If you are at the left-most element, then exit.
You aren't already at the left-most element; move left one element and repeat.
I'm sorry, I'm not in a position to provide a code sample.
Algorithm:
Start at the rightmost element.
If it's a zero, then set it to one and exit
It must be a one; set it to zero
If you are at the left-most element, then exit.
You aren't already at the left-most element; move left one element and repeat.
Here's Hymie's algorithm, I'll try making a code out of it :
#include <stdlib.h>
#include <stdio.h>
int my_algo(int *arr, int size) {
for (int i = size - 1; i >= 0; i--) { // Start at the rightmost element
if (arr[i] == 0) { // If it's a zero, then set it to one and exit
arr[i] = 1;
return 1;
} else if (arr[i] == 1) { // If it's a one, set it to zero and continue
arr[i] = 0;
}
}
return 0; // stop the algo if you're at the left-most element
}
int main() {
int n;
scanf("%d", &n);
int *arr = calloc(n, sizeof(int));
do {
for (int i = 0; i < n; i++) {
putchar(arr[i] + '0');
}
putchar('\n');
} while (my_algo(arr, n));
return (0);
}
This algorithm is dynamic and work with scanf.
Here's the result for 4 :
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111
What you seem to want to do is implement binary addition (or more precisely a binary counter), which is anyway implemented in the CPU's digital circuit using logic gates. It can be done using combination of logical operations (nand and xor to be exact).
But the most elegant approach according to my sense of elegance would be to use the CPU's innate ability to increment numbers and write a function to decompose a number to a bit array:
void generate_bit_array(unsigned int value, uint8_t *bit_array, unsigned int bit_count) {
for (unsigned int i=0; i<bit_count; i++) {
bit_array[i] = value >> (bit_count - i - 1) & 0x01;
}
}
int main(int argc, void **argv) {
unsigned int i;
uint8_t my_array[4];
/* Iterate and regenerate array's content */
for (i=0; i<4; i++) {
generate_bit_array(i, my_array, 4);
/* Do something */
}
return 0;
}
You can do:
#include <stdio.h>
#include <stdlib.h>
void gen_bit_array(int *numarr, int n, int arr_size) {
if(n > 0) {
numarr[arr_size-n] = 0;
gen_bit_array(numarr, n-1, arr_size);
numarr[arr_size-n] = 1;
gen_bit_array(numarr, n-1, arr_size);
} else {
int i;
for(i=0; i<arr_size; i++)
printf("%d", numarr[i]);
printf ("\n");
}
}
int main() {
int n,i;
printf ("Enter array size:\n");
scanf("%d", &n);
int *numarr = calloc(n, sizeof(int));
if (numarr == NULL)
return -1;
gen_bit_array(numarr, n, n);
return 0;
}
Output:
Enter array size:
2
00
01
10
11
Enter array size:
4
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111
If I have understood you correctly then what you need is something like the following
#include <stdio.h>
#define N 4
void next_value( unsigned int a[], size_t n )
{
unsigned int overflow = 1;
for ( size_t i = n; i != 0 && overflow; i-- )
{
overflow = ( a[i-1] ^= overflow ) == 0;
}
}
int empty( const unsigned int a[], size_t n )
{
while ( n && a[n-1] == 0 ) --n;
return n == 0;
}
int main(void)
{
unsigned int a[N] = { 0 };
do
{
for ( size_t i = 0; i < N; i++ ) printf( "%i ", a[i] );
putchar( '\n' );
next_value( a, N );
} while ( !empty( a, N ) );
return 0;
}
The program output is
0 0 0 0
0 0 0 1
0 0 1 0
0 0 1 1
0 1 0 0
0 1 0 1
0 1 1 0
0 1 1 1
1 0 0 0
1 0 0 1
1 0 1 0
1 0 1 1
1 1 0 0
1 1 0 1
1 1 1 0
1 1 1 1
Or you can write the function that evaluates a next value such a way that if the next value is equal to 0 then the function returns 0.
For example
#include <stdio.h>
#include <stdlib.h>
int next_value( unsigned int a[], size_t n )
{
unsigned int overflow = 1;
for ( ; n != 0 && overflow; n-- )
{
overflow = ( a[n-1] ^= overflow ) == 0;
}
return overflow == 0;
}
int main(void)
{
size_t n;
printf( "Enter the length of the binary number: " );
if ( scanf( "%zu", &n ) != 1 ) n = 0;
unsigned int *a = calloc( n, sizeof( unsigned int ) );
do
{
for ( size_t i = 0; i < n; i++ ) printf( "%i ", a[i] );
putchar( '\n' );
} while ( next_value( a, n ) );
free( a );
return 0;
}
The program output might look like
Enter the length of the binary number: 3
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
No need for an algorithm, you could build a function,
Here is a process which could be a good idea if the array is of a fixed size :
Build a function which take your array
Create a local integrer for this function
Set the bits value of the integrer to the cells value of the array
Increment the integrer
Set the array values to match each bits of the integrer
All this process can be done using shifts (>> <<) and masks (& 255 for example).

Binary to decimal algorithm in c giving strange results

Hi i'm fairly new to c but for a program I'm writing I need to convert binary strings to decimal numbers. here is my current code:
int BinaryToInt(char *binaryString)
{
int decimal = 0;
int len = strlen(binaryString);
for(int i = 0; i < len; i++)
{
if(binaryString[i] == '1')
decimal += 2^((len - 1) - i);
printf("i is %i and dec is %i and the char is %c but the length is %i\n", i, decimal, binaryString[i], len);
}
return decimal;
}
int main(int argc, char **argv)
{
printf("%i", BinaryToInt("10000000"));
}
and here is the output:
i is 0 and dec is 5 and the char is 1 but the length is 8
i is 1 and dec is 5 and the char is 0 but the length is 8
i is 2 and dec is 5 and the char is 0 but the length is 8
i is 3 and dec is 5 and the char is 0 but the length is 8
i is 4 and dec is 5 and the char is 0 but the length is 8
i is 5 and dec is 5 and the char is 0 but the length is 8
i is 6 and dec is 5 and the char is 0 but the length is 8
i is 7 and dec is 5 and the char is 0 but the length is 8
5
I'm confused as to why this doesn't work, all help is greatly appreciated. Thanks in advance!
Ps: I'm used to java so at the moment C just makes me cry
The ^ operator is not for exponentiation, but is instead the bitwise XOR operator.
If you want to raise a number to a power of 2, use the left shift operator << to shift the value 1 by the exponent in question.
decimal += 1 << ((len - 1) - i);
The trick is the same as with any number base: for each incoming digit, multiply the accumulator by the number base and add the digit.
#include <stdio.h>
#include <string.h>
int BinaryToInt(char *binaryString)
{
int decimal = 0;
int len = strlen(binaryString);
for(int i = 0; i < len; i++) {
decimal = decimal * 2 + binaryString[i] - '0';
}
return decimal;
}
int main(void)
{
printf("%d", BinaryToInt("10000000"));
return 0;
}
Program output:
128

Count alphabets in C using log functions(without math.h) and arrays

I'm facing a slight problem with one of my projects. I am supposed to write a c program to calculate each character present in the input/file. (It's supposed to be a basic program.) The constraints - I cannot use the math.h library to produce log functions and obtain an output in the format:
1
5 1 2 0 2 2 5 8 4 3 6 6 2 5 5 7 2 1 1 2
7 9 8 1 7 2 4 1 0 0 4 5 0 2 2 5 2 6 3 6 6 3 7 0 2 2
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
The program is supposed to count the number of occurrences of each alphabetic letter (case insensitive) in the stdin input stream and display a histogram.
As you can see, the output is formatted vertically with each line printing the base 10 number of the position of the character.
Now, this might seem silly, but what I have so far is this:
#include <stdio.h>
#include <ctype.h>
/*
int logBase10 (int num) {
method to calculate the log base 10 of num
}
*/
int main (int argc, char * argv[]) {
char alpha;
int count = 0;
int ascii[128] = {0};
while ( (alpha = getchar()) != EOF) {
count++;
ascii[(int)alpha]++;
alpha = getchar();
}
printf("Char \t Count \n");
printf("------------------------\n");
for (int i = 0; i < 127; i++) {
if(ascii[i] > 0) {
printf("%c \t %d \n", i, ascii[i]);
}
}
}
Which produces an output like this:
Char Count
------------------------
5
93
, 6
- 2
. 3
; 2
C 2
I 6
N 1
T 1
W 2
a 26
b 5
c 8
d 13
e 55
f 11
g 7
h 28
i 32
k 3
l 26
m 17
n 31
o 27
p 12
q 1
r 26
s 22
t 42
u 11
v 8
w 8
y 13
z 1
First off, my program is printing unwanted ascii characters (, ; - etc) and I am working on changing the print function to be more vertical, but I cannot figure out the log method at all. I know log(10) is 1 because 10^1 is 1, but I am having trouble figuring out how to use this to create the method itself. Also, for the extra characters, I tried using:
if(ascii[i] > 65 || ascii[i] < 90 || ascii[i] >= 97 || ascii[i] <= 122 ) {
printf("%c \t %d \n", i, ascii[i]);
}
to no avail. Trying that produced more gibberish characters instead.
Any help/feedback is appreciated.
Soul
The commenters have already pointed out issues with your code. Here's a version that counts only letters and prints vertical labels. It doesn't need <ctype.h> or <math.h>.
Each character hets a letter index which is a number from 0 to 25 for upper and lower case letters and −1 if the character isn't a letter. That reduces the array size to 26.
You could find out each digit with elaborate calculations, but the easiest way is to print the number to a string. snprintf does this for you. You can right-align the number with a field width. The maximum value for a typical int is about 2 billion, which has 10 digits. You should account for that, even if you had to pass in the whole Moby-Dick plus the Bible to get that many counts.
You can test whether you should start printing by assuming a width of ten digits first and checking whether the maximum count has ten digits, that is whether it is 1,000,000,000 or higher. Then divide that limit by 10 in each iteration.
Here's the code:
#include <stdio.h>
// return letter index or -1 for non-letter
int letter(int c)
{
if ('a' <= c && c <= 'z') return c - 'a';
if ('A' <= c && c <= 'Z') return c - 'A';
return -1;
}
int main(int argc, char * argv[])
{
int count[26] = {0}; // letter counts
char label[26][12]; // buffer for printing numbers
int limit = 1000000000; // smallest 10-digit number
int max = 0;
int i, j;
// read and count letters
while (1) {
int c = getchar();
if (c == EOF) break;
c = letter(c);
if (c >= 0) count[c]++;
}
// write auxiliary labels
for (i = 0; i < 26; i++) {
snprintf(label[i], sizeof(label[i]), "%10d", count[i]);
if (count[i] > max) max = count[i];
}
// print vertical labels
for (j = 0; j < 10; j++) {
if (max >= limit) {
for (i = 0; i < 26; i++) {
putchar(' ');
putchar(label[i][j]);
}
putchar('\n');
}
limit /= 10;
}
// print horizontal rule
for (i = 0; i < 26; i++) {
putchar('-');
putchar('-');
}
putchar('-');
putchar('\n');
// print letters
for (i = 0; i < 26; i++) {
putchar(' ');
putchar('A' + i);
}
putchar('\n');
return 0;
}
On your example, it produces:
1
5 1 2 0 2 2 5 8 4 3 6 6 2 5 5 7 2 1 1 2
7 9 8 1 7 2 4 1 0 0 4 5 0 2 2 5 2 6 3 6 6 3 7 0 2 2
-----------------------------------------------------
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
One easy way to figure out how many digits that you'll need is to use sprintf to convert the integer count to a string, and then use strlen to find out how many digits you have. For example:
char str[20] = {0}; // 20 digits should be enough for your case
for (i = 0; i < 128; i++) {
sprintf(str, "%d", ascii[i]);
num_digits = strlen(str);
printf("%d has %d digits\n", ascii[i], num_digits);
}
I didn't test the code, but it should be close.
Some pseudo code
Find max count
Find width of that count when printed w=sprintf(buf, "%d", mxcnt)
Loop w times (wi = 0 to w - 1)
for each non-zero count
form string sprintf(buf, "%*d", w, count[i])
print buf[wi] character
print space
print \n

C : 0 & 1 combinations using recursion

I want to list combinations of o & 1 recursively using c depending on variables number (number)
the output I want is
000
001
010
011
100
101
110
111
I've tried many algorithms the last one is :
void permute(unsigned number) {
if(number == 0) {
printf("\n");
return;
}
permute(number - 1);
printf("0");
permute(number - 1);
printf("1");
} //permute ends here
void permuteN(unsigned number) {
unsigned i;
for(i = 0; i < number + 1; i++){
permute(i);
}
} //permuteN ends here
I think it gives me the answer but not ordered because I don't know where to put \n;
need your help!
If you are indeed just looking for combinations of 1's and 0's I'd suggest you just count up the numbers and list them in binary.
Take the numerals 0...7 in binary and taking only the last 3 bits (apply mask maybe), and you end up with the same set you specified:
000
001
...
...
111
For n-digit combinations, you need to do 0..2^n - 1
Based off this answer, for one specific case of 3-bits
(Credit to #ChrisLutz and #dirkgently)
#include <stdio.h>
int main(){
int numdigits = 3, j;
for(j=1; j<8; j++)
printbits(j);
}
void printbits(unsigned char v) {
int i;
for(i = 2; i >= 0; i--) putchar('0' + ((v >> i) & 1));
printf("\n");
}
Output:
000
001
010
011
100
101
110
111
All you are actually doing is converting a number to binary.... A simple loop does this without any library calls (aside from printf)...
const unsigned int numbits = 3;
unsigned int bit;
for( bit = 1U << (numbits-1); bit != 0; bit >>= 1 ) {
printf( number&bit ? "1" : "0" );
}
printf( "\n" );
Edited, since you seem to want recursion. You need to have some way to specify how many bits you require. You need to pass this into your recursive routine:
#include <stdio.h>
void permute(unsigned number, unsigned bits)
{
if( bits == 0 ) return;
permute(number / 2, bits-1);
printf( "%d", number % 2 );
} //permute ends here
void permuteN(unsigned number, unsigned bits ) {
unsigned i;
for(i = 0; i < number + 1; i++){
permute(i, bits);
printf("\n");
}
} //permuteN ends here
int main(void)
{
permuteN(7, 3);
return 0;
}
To get the output in the order you require, you can't know when to write the newline. So in this case, you write it afterwards.
#paddy has a nice answer; only adding a bit (as of my toughs by your reply on my comment - was a bit late to the game). This rely on pow() , (and log10 for some nicety in print), tho so; if using gcc compile with -lm:
basemight be a bit confusing here - but guess you get the meaning.
gcc -Wall -Wextra -pedantic -o combo combo.c -lm
/* gcc - Wall -Wextra -pedantic -o combo combo.c -lm */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
static void prnt_combo(unsigned number, unsigned bits, int base)
{
if (!bits)
return;
prnt_combo(number / base, --bits, base);
printf("%d", number % base);
}
void prnt_combos(int bits, int base)
{
int i;
int n = pow(base, bits);
int wp = log10(n) + 1;
fprintf(stderr,
"Printing all combinations of 0 to %d by width of %d numbers. "
"Total %d.\n",
base - 1, bits, n
);
for (i = 0; i < n; i++) {
fprintf(stderr, "%*d : ", wp, i);
prnt_combo(i, bits, base);
printf("\n");
}
}
/* Usage: ./combo [<bits> [<base>]]
* Defaults to ./combo 3 2
* */
int main(int argc, char *argv[])
{
int bits = argc > 1 ? strtol(argv[1], NULL, 10) : 3;
int base = argc > 2 ? strtol(argv[2], NULL, 10) : 2;
prnt_combos(bits, base);
return 0;
}
Sample:
$ ./combo 4 2
Printing all combinations of 0 to 1 by width of 4 numbers. Total 16.
0 : 0000
1 : 0001
2 : 0010
3 : 0011
4 : 0100
5 : 0101
6 : 0110
7 : 0111
8 : 1000
9 : 1001
10 : 1010
11 : 1011
12 : 1100
13 : 1101
14 : 1110
15 : 1111
Or clean output:
$ ./combo 3 2 >&2-
000
001
010
011
100
101
110
111
You might like to add something like:
if (base > 10)
printf("%x", number % base);
else
printf("%d", number % base);
in prnt_combo(). This way you get i.e. by 2 16:
0 : 00
1 : 01
2 : 02
3 : 03
4 : 04
...
250 : fa
251 : fb
252 : fc
253 : fd
254 : fe
255 : ff

Resources