keep getting ascii value where char is expected - c

When a coordinate is selected, it should be replaced with a "~". However, it's being replaced with the ascii value for the ~ instead (126). I tried a few different things, but I always get the 126 instead of the ~. Any ideas?
Thanks for the help!
int board_is_empty(int N, int board[ROWS][COLS])
{
int i = 0, j = 0;
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
if (board[i][j] != '~')
{
return 0;
}
}
}
return 1;
}
//updates the board to replace each selected coordinate with a ~.
//returns nothing
void update_board (int board[ROWS][COLS], int row_target, int column_target)
{
board[row_target][column_target] = '~';
}
int main(void)
{
int game_board[ROWS][COLS] = {0};
int rows, columns = 0;
int players_turn = 1, target_column = -1, target_row = -1, value = 0;
int row_selection = 0, column_selection = 0;
int i = 0;
initialize_game_board(game_board);
display_board(game_board);
generate_starting_point(game_board, &rows, &columns);
printf ("\nPlease hit <Enter> to continue.\n");
getchar ();
while (board_is_empty(ROWS, game_board) != 1)
{
select_target (&target_row, &target_column, players_turn);
value += game_board[target_row][target_column];
update_board (game_board, target_row, target_column); //should cause the coordinates at target_row && target_column to be replaced with a ~
display_board(game_board);
}
printf("\n%d", value);
}

'~' is a character and you have declared board as a two dimensional integer array.
so when you write board[row_target][column_target] = '~';
it convert '~' it into integer i.e into its ascii value which is 126
and there for it becomes board[row_target][column_target] = 126
I will suggest make board as two dimensional character array. Hopefully it will solve your problem.
And in case if you want it as integer only then consider 126 as a special no which means '~' by declaring

For storing your coordinates, you are using an integer array. When you execute
board[row_target][column_target] = '~'; tilde's ascii value (126) is assigned to LHS. There is no way you can assign a character to an integer value. I think you should use some special number rather than tilde. If I were you, I would use INT_MIN or INT_MAX.

There isn't a difference between the character '~' and the number 126 as far as the C language is concerned, '~' == 126.
(You used "~" which i would normally use for a string, but i assume you don't actually mean that).
If you want to display a value, you have to use the correct format string. %d is for decimal integers, %c would be for characters (the variable holding the value should also be a char)

In C, chars are just integers. At output time they are represented as characters but internally they hold just the ASCII code of that character.
Since your board is a matrix of int's, when you assign '~' you are effectively assigning the number 126 to a position of the board. If you check that position, the expected result is to get an int equal to 126.
However, if you want to see that value as a character, you can do it by casting that number into a char:
printf("%c", value);
Take a look:
#include <stdio.h>
int main()
{
int i = '~';
char c = '~';
printf("Integer: %d\n", i); /* outputs: 126 */
printf("Char: %c\n", c); /* outputs: ~ */
printf("Integer casted to char: %c\n", i); /* outputs: ~ */
}
That is, your value is right. You just need to get the representation you want. (If you want to be able to store the value 126 in the board and the character ~ at the same time, then you're out of luck because for C they are the same thing -you can use some other value that you know that the board isn't going to hold, like -1 or something like that).
Update:
So, if I didn't get it wrong what you're trying to do is to read numbers from a bidimensional matrix of random integers and mark each one as you go reading them.
If that is what you're trying to achieve, then your idea of using '~' to mark the read positions isn't going to work. What I meant before is that, in C, 126 and the character '~' are the exact same thing. Thus, you won't be able to differentiate those positions in which you have written a '~' character and those ones in which a random 126 is stored by chance.
If you happen to be storing positive integers in your array, then use -1 instead of '~'. That will tell you if the position has been read or not.
If you are storing any possible random integer, then there is nothing you can store in that array that you can use to mark a position as read. In this case a possible solution is to define your array like this:
typedef struct {
int value;
char marked;
} Position;
Position board[ROWS][COLS];
Thus, for each position you can store a value like this:
board[row][col].value = 23123;
And you can mark it as read like this:
board[row][col].marked = 'y';
Just, don't forget to mark the positions as not read (board[row][col].marked = 'n';) while you fill the matrix with random integers.

Related

Convert single characters of a string to elements of an integer array

So I'm a newcomer to C and I've just learned about string after array. Now I'm trying to write a program that convert a string which consists of only integer numbers into an integer array.
For example let's say I have this string og[] and use fgets to get the input: og = 123456
Then I want to convert this '012345678' string into an array, let's say mod[] which be like:
mod[0] = 1;
mod[1] = 2;
mod[2] = 3;
mod[3] = 4;
mod[4] = 5;
mod[5] = 6;
Is there any method to achieve this quickly with a function? If no, how could I write a function to convert this?
Thank you in advance.
Use ASCII difference method in order to get required outcome:
For example let you are converting (char)1 to (int)1. So Subtract
ASCII value of 1 by 0:
ie,'1'-'0'(since, 49-48=1 here 49 is ASCII value of '1' and 48 is of '0').
And at the end store it into integer variable.
By using above concept you code will be:
int i=0;
char str []="123456789";
int strsize=(sizeof(str)/sizeof(char))-1;
int *arr=(int * )malloc(strsize*sizeof(int));
// YOUR ANSWER STARTS HERE
while(str[i]!='\0'){
arr[i]=str[i]-'0';
i++;
}
here size of str string is 10 thus subtracting 1 from it in order to get 9.
here while loop moving till end of string (i.e '\0')
If you are using an ASCII-based system (very likely) and you are only concerned with single digits, this is quite simple:
int main(void)
{
char og[] = "123456";
int *mod = calloc(strlen(og),sizeof(*mod));
for (int i = 0; og[i]; ++i) {
mod[i] = og[i] - '0';
}
// then whatever you want to do with this
}
This works because in ASCII, decimal digits are sequential and when the character is '0' and you subtract '0' (which is 48 in ASCII), you get the numerical value of 0; when the character is '1' (which is 49 in ASCII), you get the numerical value 1; and so on.

Maximum product of 13 adjacent numbers of a 1000-digit number

I have to find the largest product of 13 adjacent numbers of a 1000-digit number below. My code for the problem is as follows:
#include <stdio.h>
int main()
{
char arr[1000] =
"731671765313306249192251196744265747423553491949349698352031277450"
"632623957831801698480186947885184385861560789112949495459501737958"
"331952853208805511125406987471585238630507156932909632952274430435"
"576689664895044524452316173185640309871112172238311362229893423380"
"308135336276614282806444486645238749303589072962904915604407723907"
"138105158593079608667017242712188399879790879227492190169972088809"
"377665727333001053367881220235421809751254540594752243525849077116"
"705560136048395864467063244157221553975369781797784617406495514929"
"086256932197846862248283972241375657056057490261407972968652414535"
"100474821663704844031998900088952434506585412275886668811642717147"
"992444292823086346567481391912316282458617866458359124566529476545"
"682848912883142607690042242190226710556263211111093705442175069416"
"589604080719840385096245544436298123098787992724428490918884580156"
"166097919133875499200524063689912560717606058861164671094050775410"
"022569831552000559357297257163626956188267042825248360082325753042"
"0752963450";
int i, j;
long int max;
max = 0;
long int s = 1;
for (i = 0; i < 988; i++) {
int a = 0;
for (j = 1; j <= 13; j++) {
printf("%c", arr[i + a]);
s = s * arr[i + a];
a++;
}
printf("%c%d", '=', s);
printf("\n");
if (s > max) {
max = s;
}
}
printf("\nMaximum product is %d", max);
getchar();
}
Some outputs are zero even if none of the input is zero. The second output happens to be negative. The answers don't even match. Any help is appreciated.
Many set of 13 digits in your char array arr contains zeroes and that is why the multiplication of these sets will result in 0.
There are a couple of issues with your code:
You are using %d instead of %ld to print long int. Using the wrong conversion specifier will result in undefined behaviour.
If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.
You are not converting the ASCII value of the digit into its actual value before multiplication. (ASCII value of '0' is 48). This results in integer overflow and is the cause for negative values to be printed.
So the statement:
s = s * arr[i + a];
should be changed to:
s = s * (arr[i + a] - '0');
You are also not resetting the product s to 1 at the beginning of the inner for loop and because of this, you end up multiplying values from the results of different sets of 13.
After making these changes, you can see the live demo here.
There are a few issues to tackle in this code:
Clean up spacing and variable names (an edit by another user helped resolve this issue). Remove redundant variables like a, which j could easily represent by iterating from 0 to 12 rather than 1 to 13. This seems cosmetic but will make it easier for you to understand your program state, so it's actually critical.
Numerical overflow: As with all PE problems, you'll be dealing with extremely large numbers which may overflow the capacity of the long int datatype (231 - 1). Use unsigned long long to store your max and s (which I'd call product) variables. Print the result with %llu.
Convert chars to ints: arr[i+j] - '0'; so that you're multiplying the actual numbers the chars represent rather than their ASCII values (which are 48 higher).
s (really product) is not reset on each iteration of the inner loop, so you're taking the product of the entire 1000-sized input (or trying to, until your ints start to overflow).

odd numbers in language C? pb 'ram or algorithm'!

This program gives us the position of the odd numbers in a given integer, this program works well, but when I give him an integer in its numbers are greater than 10 -like 123456789123-, it doesn't work.
I do not know if is a problem of ram or algorithm ?
#include<stdio.h>
#include<stdlib.h>
main(){
int a,b;
int i = 0;
scanf("%d",&a);
while(a/10!=0){
b=a%10;
if(b%2!=0)
printf("\nodd number position: %d",i);
a=a/10;
i++;
}
if(a%2!=0)
printf("\nodd number position: %d",i);
system("pause");
}
The problem is one of processor (architecture) rather than RAM. On your platform the size of an int seems to be 32 bits which cannot hold a number as large as 123456789123. As Groo commented to Raon, you could use a string instead (if you don't plan to do any calculations on the number):
char a[1024] = {0}; /* should be plenty, but extend the array even more if needed */
fgets(a, sizeof a, stdin); /* fgets is recommended as it doesn't overflow */
int i, length = strlen(a);
for(i = 0; i < length; i++){
/* count your odd digits here
left as an exercise to the reader */
/* note that you must access the individual digits using a[i] */
}
Every data type is limited to specific range.for example char is limited to range -128 to 128. if you use the beyond this range. You might get unexpected results.
In your program if you give any number which is beyond the range of integer, then you will get unexpected results
if your int size is 4 byte/32-bit you can give input with in this range –2,147,483,648 to 2,147,483,647
if Your int size is 2 byte/16-bit you can give input with in this range –32,768 to 32,767
Check this Data Type Ranges.
And if you want to give large Numbers You can declare variable as long int/long long int
and don't forgot to change format specifier when using long int(%ld) and long long int(%lld)
You can also use string and check whether all characters are digits are not by using isdigit() function in ctype.h header and convert character digit into integer digit by substracting '0'(character zero). and check whether is that odd or not.
The problem is that 123456789123 exceed the storage limit for an integer data type,
try using a string to store the value and parse it, something like
#include<stdio.h>
int main(){
char a[] = "12345678912345678913246798";
int i = 0;
for (i=0; a[i] != '\0'; i++){
if ( a[i] % 2 != 0 ) printf("%c is odd\n", a[i]);
}
return 0;
}
#include<stdio.h>
void main() {
int i;
char s[256];
scanf("%s",s);
for( i=0; s[i]!=0; ++i ) {
/*int digit = s[i]-48;
if( digit%2==1 ) break;
- or even shorter: */
if( s[i]%2==1 ) break;
}
if( s[i]!=0 )
printf( "First odd digit position: %d", i );
else
printf( "All digits are even" );
}
Here is working sample: http://cfiddle.net/sempyi
I think this program will not give proper answer if you give more than 10 digits! please correct me if I am wrong.
The max Unsigned integer value is 4294967295 (in any 32 bit processor). if the given value is more than that then it will either limit to that max value or overflow will happen. So if you give a integer which is more than 4294967295 it will not work as it supposed to.
try printing the input. In that case you will know whether complete number is sent or Max number is sent to find the odd number's position.
One way to make it work is read the input number as array of characters and then try to figure out the odd number position.
Note: for signed integer maximum is 2147483647
123456789123 is 0x1CBE991A83
so if int is 32 bit, your number is truncated (to 3197704835 or 0xBE991A83).
Number you are giving input is greater than range of int. You need to change the data type Below link should help you.
http://www.tutorialspoint.com/ansi_c/c_basic_datatypes.htm
You need to choose a data type that matches the expected data range.
If you want your program to work for any number it is probably best to read the number one character at a time.
Code (not that in this code, position is counted with the most significant digit = 1, which is the other direction compared to your code):
int c;
unsigned long long pos = 0;
while (++pos) {
c = getc();
if (c < '0' || c > '9') break; // Not a digit
if ((c - '0')%2 != 0) {
printf("\nodd number position: %ulld", pos);
}
}
The code can handle numbers that have a ridiculus amount of digits. Eventually the pos variable will overflow, though.

Can't figure out hexadecimal conversion with pointers in C

So I am getting pretty frustrated with this and feel the only way to figure out exactly what I am doing wrong is to ask you fine people. I am trying to convert a string of characters (contains number values) to hexadecimal. Here is my code (note, I haven't placed the switch for 10-15 to letters yet; I just wanted to make sure I was getting back integer values when I ran this... no luck):
void toHex(char *inString){
char *charVal = inString;
char decVal[100];
for(int i = 0; decVal[i] != '\0'; i++){
decVal[i] = *charVal;
charVal++;
}
char storeMod[100];
int i = 0;
int testVal = atoi(decVal);
for(i; testVal >= 16; i++){
int a = testVal;
testVal = testVal/16;
storeMod[i] = a;
}
int a = 0;
char hexval[100];
hexVal[0] = '0';
hexVal[1] = 'x';
for(int j = i+2; j>=2; j--){
hexVal[j] = storeMod[a];
a++;
}
printf("%s hex valu\n", hexVal);
return;
}
For example, an input of 300 returns ,#
I have also tried:
char hexVal[100];
sprintf(hexVal,"%x",*inString);
strcpy(instring,hexVal);
which returns a hex value of 3fa844e0 for 300 which is obviously wrong as well. Any help is appreciated, I need to do this for octals too so I have to figure this concept out and see what I am doing wrong.
Instead of:
sprintf(hexVal,"%x",*inString);
Use:
sprintf(hexVal, "%x", atoi(inString));
As has been pointed out, you can replace your whole function with:
printf("%lx\n", strtol(inString, NULL, 10));
But, if this is for school or personal gratification, you seem to know the two main steps.
Convert the string to an integer
Encode the integer back into a string of the right base.
For step one, step through the number left-to-right (which is easy in a string) multiplying a running result by 10, and adding the current digit.
For step two, simply run through the number four bits(one hex digit) at a time, inserting that plus '0'. If you've started from the LSB, remember to reverse the string.

If I have to represent integers and char's in a single array, what would be an acceptable way to do this in C?

Can I declare an int array, then initialize it with chars? I'm trying to print out the state of a game after each move, therefore initially the array will be full of chars, then each move an entry will be updated to an int.
I think the answer is yes, this is permitted and will work because an int is 32 bits and a char is 8 bits. I suppose that each of the chars will be offset by 24 bits in memory from each other, since the address of the n+1'th position in the array will be n+32 bits and a char will only make use of the first 8.
It's not a homework question, just something that came up while I was working on homework. Maybe I'm completely wrong and it won't even compile the way I've set everything up?
EDIT: I don't have to represent them in a single array, as per the title of this post. I just couldn't think of an easier way to do it.
You can also make an array of unions, where each element is a union of either char or int. That way you can avoid having to do some type-casting to treat one as the other and you don't need to worry about the sizes of things.
int and char are numeric types and char is guaranteed smaller than int (therefore supplying a char where an int is expected is safe), so in a nutshell yes you can do that.
Yes it would work, because a char is implicitly convertible to an int.
"I think the answer is yes, this is permitted and will work because an int is 32 bits and a char is 8 bits." this is wrong, an int is not always 32 bits. Also, sizeof(char) is 1, but not necessarily 8 bits.
As explained, char is an int compatible type.
From your explanation, you might initially start with an array of int who's values are char, Then as the game progresses, the char values will no longer be relevant, and become int values. Yes?
IMHO the problem is not putting char into an int, that works and is built into the language.
IMHO using a union to allow the same piece of space to be used to store either type, helps but is not important. Unless you are using an amazingly small microcontroller, the saving in space is not likely relevant.
I can understand why you might want to make it easy to write out the board, but I think that is a tiny part of writing a game, and it is best to keep things simple for the rest of the game, rather than focus on the first few lines of code.
Let's think about the program; consider how to print the board.
At the start it could be:
for (int i=0; i<states; ++i) {
printf("%c ", game_state[i]);
}
Then as the game progresses, some of those values will be int.
The issue to consider is "which format is needed to print the value in the 'cell'?".
The %c format prints a single char.
I presume you would like to see the int values printed differently from ordinary printed characters? For example, you want to see the int values as integers, i.e. strings of decimal (or hex) digits? That needs a '%d' format.
On my Mac I did this:
#include <stdio.h>
#define MAX_STATE (90)
int main (int argc, const char * argv[]) {
int game_state[MAX_STATE];
int state;
int states;
for (states=0; states<MAX_STATE; ++states) {
game_state[states] = states+256+32;
}
for (int i=0; i<states; ++i) {
printf("%c ", game_state[i]);
}
return 0;
}
The expression states+256+32 guarantees the output character codes are not ASCII, or even ISO-8859-1 and they are not control codes. They are just integers. The output is:
! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? # 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 [ \ ] ^ _ ` 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
I think you'd like the original character to be printed (no data conversion) when the value is the initial character (%c format), but you do want to see data conversion, from a binary number to a string of digit-characters (%d or a relative format). Yes?
So how would the program tell which is which?
You could ensure the int values are not characters (as my program did). Typically, this become a pain, because you are restricted on values, and end up using funny expressions everywhere else just to make that one job easier.
I think it is easier to use a flag which says "the value is still a char" or "the value is an int"
The small saving of space from using a union is rarely worth while, and their are advantages to having the initial state and the current move available.
So I think you end up with something like:
#include <stdio.h>
#define MAX_STATE (90)
int main (int argc, const char * argv[]) {
struct GAME { int cell_state; int move; char start_value } game_state[MAX_STATE];
enum CELL_STATE_ENUM { start_cell, move_cell };
int state;
int states;
for (states=0; (state=getchar())!= EOF && states<MAX_STATE; ++states) {
game_state[states].start_value = state;
game_state[states].cell_state = start_cell;
}
// should be some error checking ...
// ... make some moves ... this is nonsense but shows an idea
for (int i=0; i<states; ++i ) {
if (can_make_move(i)) {
game_state[states].cell_state = move_cell;
game_state[states].move = new_move(i);
}
}
// print the board
for (int i=0; i<states; ++i) {
if (game_state[i].cell_state == start_cell) {
printf("'%c' ", game_state[i].start_value);
} else if (game_state[i].cell_state == move_cell) {
printf("%d ", game_state[i].move);
} else {
fprintf(stderr, "Error, the state of the cell is broken ...\n");
}
}
return 0;
}
The move can be any convenient value, there is nothing to complicate the rest of the program.
Your intent can be made a little more clear my using int8_t or uint8_t from the stdint.h header. This way you say "I'm using a eight bit integer, and I intend for it to be a number."
It's possible and very simple. Here is an example:
int main()
{
// int array initialized with chars
int arr[5] = {'A', 'B', 'C', 'D', 'E'};
int i; // loop counter
for (i = 0; i < 5; i++) {
printf("Element %d id %d/%c\n", i, arr[i], arr[i]);
}
return 0;
}
The output is:
Element 0 is 65/A
Element 1 is 66/B
Element 2 is 67/C
Element 3 is 68/D
Element 4 is 69/E

Resources